安卓调用原生拍照相册封装

74 阅读1分钟

代码如下

package com.purui.mobile.utils

import android.app.Activity
import android.content.Intent
import android.media.MediaScannerConnection
import android.net.Uri
import android.os.Environment
import android.provider.MediaStore
import androidx.core.content.FileProvider
import com.purui.mobile.PuruiApplication
import java.io.File

object CameraAlbumHelper {

    const val REQUEST_CAMERA = 0x10000
    const val REQUEST_ALBUM = 0x10001

    fun onActivityResultCamera(requestCode: Int, resultCode: Int, data: Intent?) {
        if (resultCode != Activity.RESULT_OK) {
            return
        }
        mImageUriFromCamera?.let {
            onCameraUriCallback?.invoke(it)
        }
    }

    fun onActivityResultAlbum(requestCode: Int, resultCode: Int, data: Intent?) {
        if (resultCode != Activity.RESULT_OK) {
            return
        }
        val clipData = data?.clipData
        if (clipData != null) {
            val clipData = data.clipData
            if (clipData != null) {
                for (i in 0 until clipData.itemCount) {
                    val uri = clipData.getItemAt(i).uri
                    onAlbumUriCallback?.invoke(uri)
                }
            }
        } else {
            data?.data?.let { onAlbumUriCallback?.invoke(it) }
        }
    }

    private var mImageUriFromCamera: Uri?= null

    private var onCameraUriCallback:((Uri)->Unit)?= null
    private var onAlbumUriCallback:((Uri)->Unit)?= null

    /**
     * 开启拍照
     */
    fun openCamera(context: Activity?, onCameraUriCallback:((Uri)->Unit)) {
        if (context == null) return
        this.onCameraUriCallback = onCameraUriCallback
        val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        val file = createFile(context)
        mImageUriFromCamera = FileProvider.getUriForFile(context, "${context.packageName}.fileprovider", file)
        intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUriFromCamera)
        context.startActivityForResult(intent, REQUEST_CAMERA)
    }

    /**
     * 开启相册
     */
    fun openAlbum(context: Activity?,  onAlbumUriCallback:(Uri)->Unit) {
        if (context == null) return
        this.onAlbumUriCallback = onAlbumUriCallback
        val intent = Intent(Intent.ACTION_PICK)
        intent.type = "image/*"
        context.startActivityForResult(intent, REQUEST_ALBUM)
    }

    private fun createFile(context: Activity): File {
        val sdcardDir = context.filesDir
        val myPhotoDir = File(sdcardDir, "camera")
        if (!myPhotoDir.exists()) {
            myPhotoDir.mkdir()
        }
        val file = File(myPhotoDir, "${System.currentTimeMillis()}.jpg")
        if (!file.exists()) file.createNewFile()

        val pathArray = arrayOf(file.absolutePath)
        val typeArray = arrayOf("image/jpeg")
        MediaScannerConnection.scanFile(PuruiApplication.instance, pathArray, typeArray) { s, uri -> }
        return file
    }

    fun release() {
        onCameraUriCallback = null
        onAlbumUriCallback = null
    }
}

AndroidManifets.xml 下要加入以下的 provider

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
<application>
    ...
    <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="${applicationId}.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_path" />
    </provider>
   </application>

</manifest>

res/xml 下要加入 file_path.xml

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
    <paths>
        <files-path path="" name="download"/>
    </paths>
</resources>