zoukankan      html  css  js  c++  java
  • Android调用系统拍照裁剪和选图功能

    最近项目中用到修改用户头像的功能,基本上都是模板代码,现在简单记录一下.

    • 调用系统拍照
        private fun openCamera() {  //调用相机拍照
            // 创建File对象,用于存储拍照后的图片
            var outputImage = File(externalCacheDir, "output_image.jpg")
            try {
                if (outputImage.exists()) {
                    outputImage.delete()
                }
                outputImage.createNewFile()
            } catch (e: IOException) {
                e.printStackTrace()
            }
            if (Build.VERSION.SDK_INT < 24) {
                imageUri = Uri.fromFile(outputImage)
            } else {
                //Android 7.0系统开始 使用本地真实的Uri路径不安全,使用FileProvider封装共享Uri
                //参数二:fileprovider绝对路径 com.yaoli.testcamerademo:项目包名
                imageUri = FileProvider.getUriForFile(this@MainActivity, "com.yaoli.testcamerademo.fileprovider", outputImage)
            }
            // 启动相机程序
            val intent = Intent("android.media.action.IMAGE_CAPTURE")
            intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri)
            startActivityForResult(intent, 1)
        }

    为了适配Android7.0以后的版本,需要在AndroidManifest配置一下(在后面相册选图也需要用到)

    <application>
        ...  
        <provider
                android:name="android.support.v4.content.FileProvider"
                android:authorities="com.yaoli.testcamerademo.fileprovider"
                android:exported="false"
                android:grantUriPermissions="true">
                <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/file_paths" />
            </provider>
    </application>

    其中的 file_paths是这样的

     

    • 调用系统相册
     private fun pickPhoto() {
          val intent = Intent("android.intent.action.GET_CONTENT")
              intent.type = "image/*"
          startActivityForResult(Intent.createChooser(intent,"Select Picture"), 2) // 打开相册,这种方式可以打开图片或图库或文件管理中的图片
    }

    再来看下onActivityResult

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
            when (requestCode) {
                1 -> {//拍照
                    if (resultCode == AppCompatActivity.RESULT_OK) {
                        startPhoneCrop(imageUri!!)
                    }
                }
                2 -> {//打开相册
                    // 判断手机系统版本号
                    if (Build.VERSION.SDK_INT >= 21) {
                        // 4.4及以上系统使用这个方法处理图片
                        handleImageOnKitKat(data!!)
                    } else {
                        // 4.4以下系统使用这个方法处理图片
                        handleImageBeforeKitKat(data!!)
                    }
                }
        START_CROP_IMAGE_REQUEST -> {
      if (resultCode == Activity.RESULT_OK) {
    var file = File(outputUri!!.path)
        }
    }

    其中涉及到一些系统裁剪相关的方法

    • 调用系统裁剪
        /**
         * 调用系统裁剪的方法
         */
        private fun startPhoneCrop(uri: Uri) {
            outputUri = Uri.fromFile(File(Environment.getExternalStorageDirectory().absolutePath + "/" + System.currentTimeMillis() + ".jpg"))
            val intent = Intent("com.android.camera.action.CROP")
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
            }
            intent.setDataAndType(uri, "image/*")
            //是否可裁剪
            intent.putExtra("corp", "true")
            intent.putExtra("scale", true)
            //裁剪器高宽比
            intent.putExtra("aspectY", 1)
            intent.putExtra("aspectX", 1)
            //设置裁剪框高宽
            intent.putExtra("outputX", 150)
            intent.putExtra("outputY", 150)
            //返回数据
            intent.putExtra("return-data", false)
            intent.putExtra(MediaStore.EXTRA_OUTPUT, outputUri)
            intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString())
            startActivityForResult(intent, START_CROP_IMAGE_REQUEST)
        }
    // 4.4及以上系统使用这个方法处理图片 相册图片返回的不再是真实的Uri,而是分装过的Uri
        @TargetApi(21)
        private fun handleImageOnKitKat(data: Intent) {
            var imagePath = ""
            val uri: Uri = data.data
            if (DocumentsContract.isDocumentUri(this, uri)) {
                // 如果是document类型的Uri,则通过document id处理
                val docId = DocumentsContract.getDocumentId(uri)
                if ("com.android.providers.media.documents" == uri.authority) {
                    val id = docId.split(":")[1] // 解析出数字格式的id
                    val selection = MediaStore.Images.Media._ID + "=" + id
                    imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection)
                } else if ("com.android.providers.downloads.documents" == uri.authority) {
                    val contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), docId.toLong())
                    imagePath = getImagePath(contentUri, null)
                }
            } else if ("content".equals(uri.scheme, true)) {
                // 如果是content类型的Uri,则使用普通方式处理
                imagePath = getImagePath(uri, null)
            } else if ("file".equals(uri.scheme, true)) {
                // 如果是file类型的Uri,直接获取图片路径即可
                imagePath = uri.path
            }
            val imgUri = FileProvider.getUriForFile(applicationContext, "com.yaoli.example.fileprovider", File(imagePath))
            startPhoneCrop(imgUri)
        }private fun handleImageBeforeKitKat(data: Intent) {
            val uri = data.data
            val imagePath = getImagePath(uri, null)
            val imgUri: Uri = Uri.fromFile(File(imagePath))
            startPhoneCrop(imgUri)
        }

      private fun getImagePath(uri: Uri, selection: String?): String {
            var path = ""
            // 通过Uri和selection来获取真实的图片路径
            val cursor = contentResolver.query(uri, null, selection, null, null)
            if (cursor != null) {
                if (cursor.moveToFirst()) {
                    path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA))
                }
                cursor.close()
            }
            return path
        }
     

    裁剪之后的返回也在onActivityResult方法中.

    startActivityForResult(Intent.createChooser(intent, "Select Picture"), 2)
  • 相关阅读:
    php将字符串形式的数组转化为真数组
    Mysql8.0及以上 only_full_group_by以及其他关于sql_mode原因报错详细解决方案
    php使用base64_encode和base64_decode对数据进行编码和解码
    大数据基本概念
    sonarqube安装部署
    git-修改commit信息
    NLP-Commen Sense
    索引生命周期的管理
    kibana软件具体参数配置信息
    es机器监控x-pack导致的监控存储过大的问题
  • 原文地址:https://www.cnblogs.com/fuyaozhishang/p/9466258.html
Copyright © 2011-2022 走看看