以前的权限都是在Manifest文件中列出,app安装时申请,用户同意后app就拥有了相关权限。6.0之后,敏感权限需要在不仅 需要在 Manifest中列出,还需要在代码中检查并申请,根据用户不同的操作作出反应。
以相机和读写SD卡权限为例(Kotlin),步骤如下 :
private val permissions = arrayOf("android.permission.CAMERA", "android.permission.WRITE_EXTERNAL_STORAGE")
private val appPackage = "com.demo"
private val ASK_FOR_CAMERA_PERMISSION = 1000
private fun requestCodeQRCodePermissions() {
val ps = getGrantedPermissions(appPackage)
Log.e(TAG, "已有的权限" + ps.toString())
if (checkPermission(ps, permissions[0]) && checkPermission(ps, permissions[1])) {
//有权限,todo
} else {
if (android.os.Build.VERSION.SDK_INT < 23) {
AlertDialog.Builder(this@OrderInfoActivity, R.style.Theme_AppCompat_Light_Dialog_Alert)
.setTitle("尚无相机权限,请前往设置或者手机管家中打开定位权限")
.setPositiveButton("前往设置") { _, _ ->
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", packageName, null))
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivityForResult(intent, Constants.ASK_FOR_PERMISSION)
}.setNegativeButton("我再想想") { dialog, _ -> dialog.dismiss() }.show()
} else {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this@OrderInfoActivity,
Manifest.permission.CALL_PHONE)) {
ActivityCompat.requestPermissions(this@OrderInfoActivity, permissions, ASK_FOR_CAMERA_PERMISSION)
// Show an expanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this@OrderInfoActivity, permissions, ASK_FOR_CAMERA_PERMISSION)
// MY_PERMISSIONS_REQUEST_CALL_PHONE is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
}
}
private fun checkPermission(permissions: List<String>, permission: String): Boolean {
return permissions.contains(permission)
}
输出app拥有的所有权限(可选)
internal fun getGrantedPermissions(appPackage: String): List<String> {
val granted = ArrayList<String>()
try {
val pi = packageManager.getPackageInfo(appPackage, PackageManager.GET_PERMISSIONS)
pi.requestedPermissions.indices
.filter { pi.requestedPermissionsFlags[it] and PackageInfo.REQUESTED_PERMISSION_GRANTED != 0 }
.mapTo(granted) { pi.requestedPermissions[it] }
} catch (e: Exception) {
e.printStackTrace()
}
return granted
}
重写onRequestPermissionsResult,根据requestCode做相应处理
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
when (requestCode) {
ASK_FOR_CAMERA_PERMISSION -> {
// If request is cancelled, the result arrays are empty.
if (checkPermission(getGrantedPermissions(appPackage), permissions[0]) && checkPermission(getGrantedPermissions(appPackage), permissions[1])) {
startActivity(Intent(this@OrderInfoActivity, QRCodeActivity::class.java))
} else {
requestCodeQRCodePermissions()
}
return
}
}
}