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)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM