package cn.sinata.xldutils.activity
|
|
import android.Manifest
|
import android.annotation.TargetApi
|
import android.app.Activity
|
import android.content.*
|
import android.content.pm.PackageManager
|
import android.database.Cursor
|
import android.net.Uri
|
import android.os.Build
|
import android.os.Bundle
|
import android.os.Environment
|
import android.provider.DocumentsContract
|
import android.provider.MediaStore
|
import android.provider.Settings
|
import androidx.core.app.ActivityCompat
|
import android.text.TextUtils
|
import android.util.Log
|
import android.view.Gravity
|
import android.widget.TextView
|
import androidx.loader.content.CursorLoader
|
import cn.sinata.xldutils.R
|
import cn.sinata.xldutils.utils.*
|
import cn.sinata.xldutils.widget.TipDialog
|
import com.tbruyelle.rxpermissions2.RxPermissions
|
import com.ypx.imagepicker.ImagePicker
|
import org.jetbrains.anko.bundleOf
|
import org.jetbrains.anko.find
|
import org.jetbrains.anko.sdk27.coroutines.onClick
|
import org.jetbrains.anko.toast
|
import java.io.File
|
import java.io.FileInputStream
|
import java.io.FileOutputStream
|
import java.io.InputStream
|
import java.util.*
|
|
class SelectPhotoDialog : DialogActivity() {
|
|
private var tempFile: File? = null
|
|
private var isRefused = false //全部文件管理权限
|
|
companion object {
|
val PATH = "path"
|
}
|
|
private val useFile by lazy {
|
intent.getBooleanExtra("useFile", false)
|
}
|
private val title by lazy {
|
intent.getStringExtra("title") ?: "上传头像"
|
}
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
setShowSOP(false)
|
super.onCreate(savedInstanceState)
|
setContentView(R.layout.activity_select_photo_dialog)
|
window.setGravity(Gravity.BOTTOM)
|
find<TextView>(R.id.tv_title).text = title
|
find<TextView>(android.R.id.button1).onClick {
|
val rxPermissions = RxPermissions(this@SelectPhotoDialog)
|
val fileGranted = true
|
val cameraGranted = rxPermissions.isGranted(Manifest.permission.CAMERA)
|
if ((SPUtils.instance().getBoolean("FILE_REFUSE") && !fileGranted)) {
|
myToast("缺少文件权限")
|
return@onClick
|
}
|
if ((SPUtils.instance().getBoolean("CAMERA_REFUSE") && !cameraGranted)) {
|
myToast("缺少相机权限")
|
return@onClick
|
}
|
if (fileGranted && cameraGranted) {
|
takePhoto()
|
} else {
|
val tipDialog = TipDialog()
|
tipDialog.arguments =
|
bundleOf("msg" to "为了拍摄照片上传,我们需要获取相机访问权限", "ok" to "去授权", "cancel" to "不需要")
|
tipDialog.setCallback(object : TipDialog.OnClickCallback {
|
override fun onOk() {
|
rxPermissions.request(Manifest.permission.CAMERA).subscribe {
|
if (it) {//有权限
|
//检测路径是否存在,不存在就创建
|
takePhoto()
|
} else {
|
toast("缺少相机权限")
|
SPUtils.instance().put("CAMERA_REFUSE", true).apply()
|
}
|
}
|
}
|
|
override fun onCancel() {
|
SPUtils.instance().put("CAMERA_REFUSE", true).apply()
|
}
|
})
|
tipDialog.show(supportFragmentManager, "camera")
|
}
|
}
|
|
find<TextView>(android.R.id.button2).onClick {
|
val rxPermissions = RxPermissions(this@SelectPhotoDialog)
|
val fileGranted = rxPermissions.isGranted(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
if (SPUtils.instance().getBoolean("FILE_REFUSE") && !fileGranted) {
|
myToast("缺少文件权限")
|
return@onClick
|
}
|
if (fileGranted) {
|
val intent = Intent(
|
Intent.ACTION_PICK,
|
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
|
)// 调用android的图库
|
intent.type = "image/*"
|
startActivityForResult(intent, 1)
|
} else {
|
val tipDialog = TipDialog()
|
tipDialog.arguments =
|
bundleOf("msg" to "为了访问相册选择图片上传,我们需要获取文件读写权限", "ok" to "去授权", "cancel" to "不需要")
|
tipDialog.setCallback(object : TipDialog.OnClickCallback {
|
override fun onOk() {
|
rxPermissions.request(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
.subscribe {
|
if (it) {
|
val intent = Intent(
|
Intent.ACTION_PICK,
|
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
|
)// 调用android的图库
|
intent.type = "image/*"
|
startActivityForResult(intent, 1)
|
} else {
|
myToast("缺少文件权限")
|
SPUtils.instance().put("FILE_REFUSE", true).apply()
|
}
|
}
|
}
|
|
override fun onCancel() {
|
SPUtils.instance().put("FILE_REFUSE", true).apply()
|
}
|
})
|
tipDialog.show(supportFragmentManager, "photo")
|
}
|
}
|
|
//取消
|
find<TextView>(android.R.id.button3).onClick {
|
onBackPressed()
|
}
|
}
|
|
private fun takePhoto() {
|
var name = System.currentTimeMillis().toString();//可为null
|
var isCopyInDCIM = true;//copy一份保存到系统相册文件
|
ImagePicker.takePhoto(this, name, isCopyInDCIM) {
|
var pathItem = getRealPathFromUri(this, it[0].uri)
|
var uri = it[0].uri
|
pathItem?.let {
|
//拍照
|
val intent = Intent()
|
intent.putExtra(PATH, pathItem)
|
setResult(RESULT_OK, intent)
|
finish()
|
overridePendingTransition(0, 0)
|
}
|
}
|
}
|
|
open fun copyFile(oldPath: String?, newPath: String?) {
|
try {
|
var bytesum = 0
|
var byteread = 0
|
val oldfile = File(oldPath)
|
if (oldfile.exists()) { //文件存在时
|
val inStream: InputStream = FileInputStream(oldPath) //读入原文件
|
val fs = FileOutputStream(newPath)
|
val buffer = ByteArray(1444)
|
while (inStream.read(buffer).also { byteread = it } != -1) {
|
bytesum += byteread //字节数 文件大小
|
println(bytesum)
|
fs.write(buffer, 0, byteread)
|
}
|
inStream.close()
|
}
|
} catch (e: java.lang.Exception) {
|
println("复制单个文件操作出错")
|
e.printStackTrace()
|
}
|
}
|
|
//复杂版处理 (适配多种API)
|
open fun getRealPathFromUri(
|
context: Context,
|
uri: Uri
|
): String? {
|
val sdkVersion: Int = Build.VERSION.SDK_INT
|
if (sdkVersion < 11) return getRealPathFromUri_BelowApi11(context, uri)
|
return if (sdkVersion < 19) getRealPathFromUri_Api11To18(
|
context,
|
uri
|
) else getRealPathFromUri_AboveApi19(context, uri)
|
}
|
/**
|
* 适配api11以下(不包括api11),根据uri获取图片的绝对路径
|
*/
|
private fun getRealPathFromUri_BelowApi11(
|
context: Context,
|
uri: Uri
|
): String? {
|
var filePath: String? = null
|
val projection =
|
arrayOf<String>(MediaStore.Images.Media.DATA)
|
val cursor: Cursor? = context.contentResolver.query(uri, projection, null, null, null)
|
if (cursor != null && cursor.moveToFirst()) {
|
filePath = cursor.getString(cursor.getColumnIndex(projection[0]))
|
cursor.close()
|
}
|
return filePath
|
}
|
/**
|
* 适配api11-api18,根据uri获取图片的绝对路径
|
*/
|
private fun getRealPathFromUri_Api11To18(
|
context: Context,
|
uri: Uri
|
): String? {
|
var filePath: String? = null
|
val projection =
|
arrayOf<String>(MediaStore.Images.Media.DATA)
|
//这个有两个包不知道是哪个。。。。不过这个复杂版一般用不到
|
val loader = CursorLoader(context, uri, projection, null, null, null)
|
val cursor: Cursor? = loader.loadInBackground()
|
if (cursor != null) {
|
cursor.moveToFirst()
|
filePath = cursor.getString(cursor.getColumnIndex(projection[0]))
|
cursor.close()
|
}
|
return filePath
|
}
|
/**
|
* 适配api19以上,根据uri获取图片的绝对路径
|
*/
|
@TargetApi(Build.VERSION_CODES.KITKAT)
|
private fun getRealPathFromUri_AboveApi19(
|
context: Context,
|
uri: Uri
|
): String? {
|
if (DocumentsContract.isDocumentUri(context, uri)) {
|
if (isExternalStorageDocument(uri)) {
|
val docId: String = DocumentsContract.getDocumentId(uri)
|
val split = docId.split(":").toTypedArray()
|
val type = split[0]
|
if ("primary".equals(type, ignoreCase = true)) {
|
return Environment.getExternalStorageDirectory().toString() + "/" + split[1]
|
}
|
} else if (isDownloadsDocument(uri)) {
|
val id: String = DocumentsContract.getDocumentId(uri)
|
val contentUri: Uri = ContentUris.withAppendedId(
|
Uri.parse("content://downloads/public_downloads"),
|
java.lang.Long.valueOf(id)
|
)
|
return getDataColumn(context, contentUri, null, null)
|
} else if (isMediaDocument(uri)) {
|
val docId: String = DocumentsContract.getDocumentId(uri)
|
val split = docId.split(":").toTypedArray()
|
val type = split[0]
|
val contentUri: Uri
|
contentUri = if ("image" == type) {
|
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
|
} else if ("video" == type) {
|
MediaStore.Video.Media.EXTERNAL_CONTENT_URI
|
} else if ("audio" == type) {
|
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
|
} else {
|
MediaStore.Files.getContentUri("external")
|
}
|
val selection = "_id=?"
|
val selectionArgs =
|
arrayOf(split[1])
|
return getDataColumn(context, contentUri, selection, selectionArgs)
|
}
|
} else if ("content".equals(uri.scheme, ignoreCase = true)) {
|
return getDataColumn(context, uri, null, null)
|
} else if ("file".equals(uri.scheme, ignoreCase = true)) {
|
return uri.path
|
}
|
return null
|
}
|
|
override fun exitAnim(): Int {
|
return R.anim.popup_out
|
}
|
|
override fun onRequestPermissionsResult(
|
requestCode: Int,
|
permissions: Array<out String>,
|
grantResults: IntArray
|
) {
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
if (requestCode == 12) {
|
if (TextUtils.equals(
|
permissions[0],
|
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
) && grantResults[0] == PackageManager.PERMISSION_DENIED
|
) {
|
//用户不同意,向用户展示该权限作用
|
if (!ActivityCompat.shouldShowRequestPermissionRationale(
|
this,
|
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
)
|
) {
|
alertDialog(
|
"请注意",
|
"本应用需要使用访问本地存储权限,否则无法正常使用!",
|
false,
|
"确定",
|
"取消",
|
DialogInterface.OnClickListener { _, _ -> finish() },
|
DialogInterface.OnClickListener { _, _ -> finish() })
|
return
|
}
|
finish()
|
}
|
}
|
}
|
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
super.onActivityResult(requestCode, resultCode, data)
|
if (resultCode == Activity.RESULT_OK) {
|
when (requestCode) {
|
0 -> {
|
//拍照
|
if (tempFile != null && tempFile!!.exists()) {
|
val intent = Intent()
|
intent.putExtra(PATH, tempFile!!.absolutePath)
|
setResult(RESULT_OK, intent)
|
finish()
|
overridePendingTransition(0, 0)
|
}
|
}
|
2 -> {//文件
|
if (data != null) {
|
val uri = data.data
|
if (uri != null) {
|
val path = getUrlPath(uri)
|
Log.e("mmp", "path;" + path)
|
if (path != null) {
|
val typeIndex = path.lastIndexOf(".")
|
if (typeIndex != -1) {
|
val fileType =
|
path.substring(typeIndex + 1).toLowerCase(Locale.CHINA)
|
//某些设备选择图片是可以选择一些非图片的文件。然后发送出去或出错。这里简单的通过匹配后缀名来判断是否是图片文件
|
//如果是图片文件则发送。反之给出提示
|
if (fileType == "jpg" || fileType == "gif"
|
|| fileType == "png" || fileType == "jpeg"
|
|| fileType == "bmp" || fileType == "wbmp"
|
|| fileType == "ico" || fileType == "jpe"
|
|| fileType == "pdf" || fileType == "doc" || fileType == "docx"
|
|| fileType == "xls" || fileType == "xlsx"
|
|| fileType == "ppt" || fileType == "pptx"
|
) {
|
val intent = Intent()
|
intent.putExtra(PATH, path)
|
setResult(RESULT_OK, intent)
|
finish()
|
overridePendingTransition(0, 0)
|
// cropImage(path);
|
// BitmapUtil.getInstance(this).loadImage(iv_image, path);
|
} else {
|
toast("仅支持png、jpg、pdf、doc、excel、ppt文件!")
|
}
|
} else {
|
toast("仅支持png、jpg、pdf、doc、excel、ppt文件!")
|
}
|
} else {
|
toast("无法访问该文件路径")
|
}
|
} else {
|
toast("无法访问该文件路径")
|
}
|
}
|
}
|
1 -> {
|
if (data != null) {
|
val uri = data.data
|
if (uri != null) {
|
val path = getUrlPath(uri)
|
if (path != null) {
|
val typeIndex = path.lastIndexOf(".")
|
if (typeIndex != -1) {
|
val fileType =
|
path.substring(typeIndex + 1).toLowerCase(Locale.CHINA)
|
//某些设备选择图片是可以选择一些非图片的文件。然后发送出去或出错。这里简单的通过匹配后缀名来判断是否是图片文件
|
//如果是图片文件则发送。反之给出提示
|
if (fileType == "jpg" || fileType == "gif"
|
|| fileType == "png" || fileType == "jpeg"
|
|| fileType == "bmp" || fileType == "wbmp"
|
|| fileType == "ico" || fileType == "jpe"
|
) {
|
val intent = Intent()
|
intent.putExtra(PATH, path)
|
setResult(RESULT_OK, intent)
|
finish()
|
overridePendingTransition(0, 0)
|
// cropImage(path);
|
// BitmapUtil.getInstance(this).loadImage(iv_image, path);
|
} else {
|
toast("无法识别的图片类型!")
|
}
|
} else {
|
toast("无法识别的图片类型!")
|
}
|
} else {
|
toast("无法识别的图片类型或路径!")
|
}
|
} else {
|
toast("无法识别的图片类型!")
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|