敞开成长之旅!这是我参与「日新方案 2 月更文应战」的第 30 天,点击查看活动详情

前语

今天是更文应战的最后一天了,上一篇(安卓开发控件学习——运用 PreviewView预览相机画面 – ())留了个坑,作者没把动态获取权限的代码附上,本篇咱们就来具体聊聊它。

正文

背景与官方建议

早在安卓远古时期,也就是Android 6.0(API 等级 23)之前都是不需求运用运行时额外去获取权限的(安装之前向用户一致恳求),也就是放清单文件注册权限即可,但后边Google出于用户隐私和安全性的考量,逐步收紧权限的开放,有些权限都列为风险权限,只能去运用运行时动态获取。

于是就出现假如你不向用户恳求权限(弹窗,用户挑选),有些功用就无法正常运行,比方调用摄像头,所以咱们通过动态获取权限的办法使功用可以正常运用(用户永拒时给予弹窗提示告知用户功用无法运用的原因),而Google当然也告诉了咱们开发者如何去动态恳求权限,咱们可以在官方的文档看到相关教程(恳求运行时权限 | Android 开发者 | Android Developers (google.cn))【中文版真的蛮友爱的】:

安卓开发小技巧——动态获取权限
参阅用例(Kotlin): permissions-samples/RuntimePermissionsBasicKotlin at main android/permissions-samples (github.com)

官方将恳求的办法以及比如都写好了,假如想运用系统办法或许自己封装恳求权限的话用官方的教程已经满足,但为了偷个懒,作者就用了Google写好的用于简易恳求权限的封装包(googlesamples/easypermissions: Simplify Android M system permissions (github.com)),咱们将依靠导入项目即可。

运用封装库恳求

依据官网提示,咱们先导入依靠:

dependencies {
    ...
    implementation 'pub.devrel:easypermissions:3.0.0'
    ...
}

然后同步好Gradle后就能直接开始运用EasyPermissions去恳求咱们的权限了。

运用办法很简单,咱们假如需求Camera权限,就先在Activity类名位置继承咱们的EasyPermissions.PermissionCallbacks接口

class MainActivity : AppCompatActivity() , EasyPermissions.PermissionCallbacks {
     ...
}

安卓开发小技巧——动态获取权限

安卓开发小技巧——动态获取权限

同时,咱们也就需求完成接口里的一切办法,分别是onPermissionsGranted()和onPermissionsDenied()办法,用来监听同意或回绝权限回调,假如需求对用户永久回绝的权限做提示就可以放onPermissionsDenied()办法完成:

override fun onPermissionsGranted(requestCode: Int, perms: MutableList<String>) {
    for (temp in perms) {
        if (temp == android.Manifest.permission.CAMERA) {
            Log.e(_TAG, "CAMERA onPermissionsGranted")
        }
    }
}
override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) {
    Log.d(_TAG, "onPermissionsDenied:" + requestCode + ":" + perms.size)
}

在咱们的onPermissionsDenied()办法去完成对用户永久制止相机权限提示到设置页去打开APP的相机权限,调用AppSettingsDialog办法弹窗提示:

override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) {
    Log.d(_TAG, "onPermissionsDenied:" + requestCode + ":" + perms.size)
    val permissions = android.Manifest.permission.CAMERA
    if (perms.contains(permissions)) {
        if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
            AppSettingsDialog.Builder(this)
                .setTitle("The permission has been denied by you")
                .setRationale("If you do not open the permission, you cannot use this function, click OK to open the permission")
                .setRequestCode(12345) 
                .build()
                .show()
        }
    }

然后咱们去封装一个request()恳求权限办法:

private fun request() {
    val permissions = arrayOf(
        android.Manifest.permission.CAMERA,
        //可以增加其他的权限,用来判别
    )
    //判别有没有权限
    if (EasyPermissions.hasPermissions(this, *permissions)) {
        // 有权限,需求做什么
    } else {
        // 没有权限, 恳求权限
        EasyPermissions.requestPermissions(
            this,
            "摄像机需求用户答应才能调用,请敞开相关权限(理由)",
            1,
            *permissions
        )
    }
}

咱们运用EasyPermissions的hasPermissions办法去判别是否给了权限,假如没有权限,咱们运用requestPermissions办法去提示用户敞开权限。

这个request()办法咱们直接放在咱们需求调用相关需求权限的当地即可,比方上一篇的运用摄像机的代码前面:

安卓开发小技巧——动态获取权限

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(binding.root)
    ...
    // 判别是否要恳求相机权限
    request()
    //恳求CameraProvider
    cameraProviderFuture = ProcessCameraProvider.getInstance(this)
    cameraProviderFuture.addListener({
        val cameraProvider = cameraProviderFuture.get()
        bindPreview(cameraProvider)
    }, ContextCompat.getMainExecutor(this))
}

至此,基本的动态权限恳求就完成了,咱们去运行程序来看看效果:

首先是发现用户没有给相机权限提示:

安卓开发小技巧——动态获取权限

然后假如回绝,下一次进来APP就会提示用户:

安卓开发小技巧——动态获取权限

这个当地的逻辑留意,假如正常的话,应该放入回绝的回调,这样用户回绝时就能提示到用户。

最后是用户永久回绝不提示时,咱们的弹窗提示用户去设置权限的当地去敞开:

安卓开发小技巧——动态获取权限

总结

用户的隐私愈加安全,但需求也变得更难做,可还是值得提倡,让用户的权力得到保障!