Android 11 踩雷之 App无法唤起相机

Posted 清风伴佳人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 11 踩雷之 App无法唤起相机相关的知识,希望对你有一定的参考价值。

android 11 踩雷之 App无法唤起相机

因为本人申请了MIUI12的开发版,所以体验了Android11,讲真的体验感极差,基本上App很少有适配android11 的 举个例子大多数游戏的分享会报错,部分App保存图片时会造成闪退等。

好了,言归正传,我们先来看问题

这是在吊起相机时出现的问题,问题代码是

  // 在sd卡中创建一保存图片(原图和缩略图共用的)文件夹
    private fun createFileIfNeed(fileName: String): File 
        val fileA = this.getExternalFilesDir(Environment.DIRECTORY_PICTURES)?.absolutePath + "/test"
        val fileJA = File(fileA)
        if (!fileJA.exists()) 
            fileJA.mkdirs()
        
        val file = File(fileA, fileName)
        if (!file.exists()) 
            file.createNewFile()
        
        return file
    

我们先来看看为什么会出现这个问题

android11 将存储空间分为了2部分,所以直接调用就会导致,权限不足而导致崩溃。

解决方法:
首先权限申请方面:在Android11之前,在文件里只需要相册相册的权限,在manifest里声明相机的权限,然后用相机的调用码,就可以打开相机,进行拍照裁剪等操作。

但是在android11中这是不允许的,需要在manifest文件中声明,而且需要申请相机权限。

然后就是代码中彻底解决:

将这一行替换掉
替换成

因为Android11 更新后,不存在公共分区,所以无法在公共分区创建文件。

 // 在sd卡中创建一保存图片(原图和缩略图共用的)文件夹
    private fun createFileIfNeed(fileName: String): File 
        val fileA = this.getExternalFilesDir(Environment.DIRECTORY_PICTURES)?.absolutePath + "/test"
        val fileJA = File(fileA)
        if (!fileJA.exists()) 
            fileJA.mkdirs()
        
        val file = File(fileA, fileName)
        if (!file.exists()) 
            file.createNewFile()
        
        return file
    

到现在问题解决。

最后给大家分享一下,kotlin的简便权限申请,简单又好用

object PermissionUtils 
    private val RESULT_CODE_TAKE_CAMERA = 7461    //拍照
    private val RESULT_CODE_OPEN_ALBUM = 7462     //读写
    private val RESULT_CODE_SOUND_RECORD = 7463   //录音
    private val RESULT_CODE_CALL_PHONE = 10111   //拨号
    lateinit var context: Context
    private var cameraCallback: (() -> Unit)? = null        //相机回调
    private var readAndWriteCallback: (() -> Unit)? = null  //读写回调
    private var audioCallback: (() -> Unit)? = null         //录音回调
    private var callPhone: (() -> Unit)? = null         //录音回调

    /**
     * 电话权限申请
     */
    fun CallPhone(context: Context, callPhone: () -> Unit) 
        this.context = context
        this.callPhone = callPhone
        Log.e("测试电话权限申请", "ok")
        permission(context, Manifest.permission.CALL_PHONE, RESULT_CODE_CALL_PHONE, callPhone)
    

    /**
     * 相机权限申请
     */
    fun camera(context: Context, cameraCallback: () -> Unit) 
        this.context = context
        this.cameraCallback = cameraCallback
        permission(context, Manifest.permission.CAMERA, RESULT_CODE_TAKE_CAMERA, cameraCallback)
    


    /**
     * 读写权限申请
     */
    fun readAndWrite(context: Context, readAndWriteCallback: () -> Unit) 
        this.context = context
        this.readAndWriteCallback = readAndWriteCallback
        permissions(
            context,
            arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.CAMERA),
            RESULT_CODE_OPEN_ALBUM,
            readAndWriteCallback
        )
    

    /**
     * 录音权限申请
     */
    fun audio(context: Context, audioCallback: () -> Unit) 
        this.context = context
        this.audioCallback = audioCallback
        permission(
            context,
            Manifest.permission.RECORD_AUDIO,
            RESULT_CODE_SOUND_RECORD,
            audioCallback
        )
    

    /**
     * 权限申请结果
     */
    fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) 
        val cameraAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED
        Log.e("测试电话权限申请3", "ok")
        when (requestCode) 

            RESULT_CODE_TAKE_CAMERA ->     //拍照
                if (cameraAccepted) 
                    cameraCallback?.let  it() 
                 else 
                    //用户拒绝
                    Toast.makeText(context, "请开始拍照权限", Toast.LENGTH_SHORT).show()
                
            
            RESULT_CODE_OPEN_ALBUM ->  //读写
                if (cameraAccepted) 
                    readAndWriteCallback?.let  it() 
                 else 
                    Toast.makeText(context, "请开启应用读取权限", Toast.LENGTH_SHORT).show()
                
            
            RESULT_CODE_SOUND_RECORD ->  //录音
                if (cameraAccepted) 
                    audioCallback?.let  it() 
                 else 
                    Toast.makeText(context, "请开启应用录音权限", Toast.LENGTH_SHORT).show()
                
            
            RESULT_CODE_CALL_PHONE ->  //拨号
                if (cameraAccepted) 
                    callPhone?.let 
                        Log.e("已申请电话权限", "ok")
                        it()
                    
                 else 
                    Log.e("未申请电话权限", "ok")
                    Toast.makeText(context, "请开启应用电话权限", Toast.LENGTH_SHORT).show()
                
            
        
    

    //权限申请
    private fun permission(
        context: Context,
        systemCode: String,
        resultCode: Int,
        callback: () -> Unit
    ) 
        //判断是否有权限
        if (ContextCompat.checkSelfPermission(
                context,
                systemCode
            ) == PackageManager.PERMISSION_GRANTED
        ) 
            Log.e("已申请权限", "ok")
            callback()
         else 
            //申请权限
            Log.e("无权限", "ok")
            ActivityCompat.requestPermissions(context as Activity, arrayOf(systemCode), resultCode)
        
      //权限申请

    private fun permissions(
        context: Context,
        systemCode: Array<String>,
        resultCode: Int,
        callback: () -> Unit
    ) 
        //判断是否有权限
        if (ContextCompat.checkSelfPermission(
                context,
                systemCode[0]
            ) == PackageManager.PERMISSION_GRANTED
        ) 
            Log.e("已申请权限", "ok")
            callback()
         else 
            //申请权限
            Log.e("无权限", "ok")
            ActivityCompat.requestPermissions(context as Activity, systemCode, resultCode)
        
    

调用的时候也很简单

PermissionUtils.readAndWrite(this, 

        )

到此,本文结束,谢谢大家耐心的阅读。

以上是关于Android 11 踩雷之 App无法唤起相机的主要内容,如果未能解决你的问题,请参考以下文章

Ios/Android h5 唤起本地APP

为啥我无法在 Android Instant App 中访问相机?

iOS/Android 浏览器(h5)及微信中唤起本地APP

Android 从 Web 唤起 APP

Android使用URL Scheme唤起APP

iOS/Android 微信及浏览器中唤起本地APP