Android应用的权限必须提前在AndroidManifest.xml中声明。如果申请的是普通权限,系统会自动下发权限,如果申请的是危险的权限则必须由使用者同意后才能获取。
对于危险权限,在Android 5.1.1(API 22)之前,应用安装时会弹出系统弹窗,请求用户同意所有的危险权限。如果点击accept,则会将所有的危险权限下放给应用,否则,系统会取消安装应用。在Android 6.0(API 23)之后,在安装时,不会提示各种危险权限的申请。应用必须在运行时,请求用户下放权限。用户拒绝后则功能不能继续运行。同意后,则之后不会弹出弹窗。
对于一些使用到系统功能的权限,应用必须在AndroidManifest.xml中先通过<uses-feature>标签去声明需要设备提供哪些硬件支持。如果将required属性设置为false,代表这个硬件功能不是必须的,即使设备没有这个功能,也会安装应用。所以,在应用中必须通过PackageManager.hasSystemFeature()来检测,以避免可能导致的问题。如果没有声明这个功能,而在权限申请中又需要这个权限,则系统会认为你是必须这个硬件,对于没有这个硬件功能的设备,将不被允许安装。
权限许可
- Activity
- Service
- BroadcastReceiver
- ContentProvider
- URI
- Others
保护等级(针对第三方应用)
- Normal permissions:普通权限。指的是那些你的App需要获取沙箱之外的数据或者资源,但是这些对使用者的隐私或者其他App的影响很小。普通权限在安装时会被系统自动下发,而不会提示使用者。
- Signature permissions:签名权限。系统会在安装时下放权限。
- Dangerous permissions:危险权限。指那些App需要获取用户的隐私信息,或者对用户数据和其它应用有潜在影响的权限。在访问危险权限时,系统会有弹窗提示用户,在用户同意时才能继续使用。
- Special permissions:特殊权限。有些权限格外敏感,一般情况下不会被使用。例如: SYSTEM_ALERT_WINDOW 和 WRITE_SETTINGS。必须现在Manifest中申请,然后通过Intent向用户申请权限。
检查是否有权限
/**
* 检测是否具有相机权限,相机权限必须在AndroidManifest.xml中声明
* 如果返回值为PackageManager.PERMISSION_GRANTED:0则为有权限
* 如果返回值为PackageManager.PERMISSION_DENIED:-1则为没有权限
*/
int permissionCheck = ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.CAMERA);
if(PackageManager.PERMISSION_GRANTED== permissionCheck){
//有权限
}else{
//没有权限
}
shouldShowRequestPermissionRationale()方法。如果应用之前请求过此权限但用户拒绝了请求,此方法将返回true。如果用户在过去拒绝了权限请求,并在权限请求系统对话框中选择了 Don't ask again 选项,此方法将返回false。如果设备规范禁止应用具有该权限,此方法也会返回false。
请求所需要的权限
if (ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
Manifest.permission.CAMERA)) {
/**
* 添加一些权限提示
*/
} else {
/**
* 申请权限
* RequestCode:请求码,返回结果时使用
*/
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.CAMERA},
RequestCode);
}
}
处理权限请求响应
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case RequestCode: {
//如果请求被取消,grantResults数组为空
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
/**
* 权限申请通过
*/
} else {
/**
* 权限申请被拒绝
*/
}
return;
}
}
}
使用Android权限的原则
- 仅使用应用正常工作所需的权限
- 注意库所需的权限
- 公开透明
- 让系统以显示方式访问
网友评论