android权限问题一直被用户所诟病,终于google在android M上加入了运行时权限(RuntimePermission)。
对我们的应用有什么影响呢
android M以下(api level<23)仍然是在安装时申请权限,也就是没影响,之前的应用仍然按照之前的逻辑在android M上运行。
android M以上(api level>=23),就需要声请权限啦,开发应用的时候就需要注意啦
下面说说具体使用
哪些权限需要运行时申请
android:protectionLevel=”dangerous”
也就是保护级别为“dangerous”。
系统中保护级别为“dangerous”的权限如下:
Permission Group Permissions
CALENDAR READ_CALENDAR
WRITE_CALENDAR
CAMERA CAMERA
CONTACTS READ_CONTACTS
WRITE_CONTACTS
GET_ACCOUNTS
LOCATION ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION
MICROPHONE RECORD_AUDIO
PHONE READ_PHONE_STATE
CALL_PHONE
READ_CALL_LOG
WRITE_CALL_LOG
ADD_VOICEMAIL
USE_SIP
PROCESS_OUTGOING_CALLS
SENSORS BODY_SENSORS
SMS SEND_SMS
RECEIVE_SMS
READ_SMS
RECEIVE_WAP_PUSH
RECEIVE_MMS
STORAGE READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE
这些权限需要在运行时申请,但是同一组授权只需要申请一次,例如申请READ_EXTERNAL_STORAGE权限,用户授权之后,同时也拥有了WRITE_EXTERNAL_STORAGE。(对于开发者自定义的dangerous权限,也需要申请)
如何申请权限?
Normal permissions只需要在AndroidManifest.xml中注册就可以了。
当然Dangerous permissions也需要在AndroidManifest.xml中注册。
以READ_EXTERNAL_STORAGE为例:
在AndroidManifest.xml中加入:
判断是否有权限
boolean hasPerm = (ContextCompat.checkSelfPermission(context, perm) == PackageManager.PERMISSION_GRANTED)
判断用户拒绝是否勾选不再提醒
ActivityCompat.requestPermissions(activity, perms, requestCode);
申请权限
ActivityCompat.requestPermissions(activty, perms, requestCode);
申请结果在activity或者fragment中重写
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
另外针对上面用户拒绝并勾选不再提醒
我们可以弹窗(Dialog),告知用户为何要申请该权限。
shouldShowRequestPermissionRationale()返回false,即为用户拒绝并勾选了不再提醒。这种情况我们可以通过跳转申请权限
try {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
.setData(Uri.parse("package:" + BaseActivity.this.getPackageName()));
startActivityForResult(intent, requestCode);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
Intent intent = new Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS);
startActivityForResult(intent, requestCode);
}
处理结果在onActivityResult中获取
特殊权限申请
除此之外,android M中还有些特殊权限,通过上面的手段是无法申请权限的。
例如:
申请方法:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if(!Settings.System.canWrite(MainActivity.this)){
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, REQUEST_WRITE_SETTING);
return ;
}
}
结果也是在onActivityResult中获取
另一个特殊权限:
申请办法:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if(!Settings.canDrawOverlays(MainActivity.this)){
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, REQUEST_MANAGE_OVERLAY_PERMISSION);
return ;
}
}