以前的權限都是在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
}
}
}