市场上各种流氓app, 大部分都申请了”电话”,”短信”之类的权限. 让人很是怀疑他们的动机,
ANdroid6.0之前的版只在安装时提示一次权限情况,而且要想安装只能接受别无选择.
Android6.0开始,一大亮点就是运行时权限管理. 一定程度上可以阻止流氓软件搜集各种用户信息.
实际测试了一下, 大致整理一下
要想让app支持Runtime permission , 需要在Manifast中指定targetSdkVersion为23.
如果targetSdkVersion指定为小于23的值, 安装后会默认获得权限.
但是在6.0以上的手机中还是可以手动禁止掉某个权限, 如果代码中没有权限的判断那就等着程序吧
compileSdkVersion 23
defaultConfig {
...
targetSdkVersion 23
...
}
参考docs/preview/features/runtime-permissions.html
Permission Group | Permissions |
---|---|
android.permission-group.CALENDAR |
|
android.permission-group.CAMERA |
|
android.permission-group.CONTACTS |
|
android.permission-group.LOCATION |
|
android.permission-group.MICROPHONE |
|
android.permission-group.PHONE |
|
android.permission-group.SENSORS |
|
android.permission-group.SMS |
|
android.permission-group.STORAGE |
|
实机效果如下
权限申请的处理流程
Check what platform the app is running on
This permissions model is only supported on devices running the M Developer Preview. Before calling any of these methods, the app should verify what platform it's running on by checking the value ofBuild.VERSION.CODENAME
. If the device is running the M Developer Preview,CODENAME
is"MNC"
.
When the user tries to do something that requires a permission, the app checks to see if it currently has permission to perform this operation. To do this, the app callsContext.checkSelfPermission(permission_name)
. The app should perform this check even if it knows the user has already granted that permission, since the user can revoke an app's permissions at any time. For example, if a user wants to use an app to take a picture, the app callsContext.checkSelfPermission(Manifest.permission.CAMERA)
.
@Override public void onClick(View view) { // 先判断是否已经授权 if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { // 检查是否需要展示请求权限的提示通过 if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_EX_STORAGE); else { // 用户选择了"不再询问", 弹出提示需要到"应用设置"中授权 Snackbar.make(fab, "WRITE_EXTERNAL_STORAGE permission is needed", Snackbar.LENGTH_LONG).setAction("config", new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); Uri uri = Uri.fromParts("package", getPackageName(), null); intent.setData(uri); startActivity(intent); } }).show(); } } else { accessExStorage(true); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_WRITE_EX_STORAGE) { // 授权结束,执行相应处理. 通过grantResults[0] == PackageManager.PERMISSION_GRANTED检查是否授权 accessExStorage(grantResults[0] == PackageManager.PERMISSION_GRANTED); } } public void accessExStorage(boolean permissionGranted) { if (permissionGranted) { Snackbar.make(fab, "WRITE_EXTERNAL_STORAGE Granted", Snackbar.LENGTH_LONG).show(); } else { Snackbar.make(fab, "WRITE_EXTERNAL_STORAGE Denied", Snackbar.LENGTH_LONG).show(); } }
第一步检查Android系统的版本, 我觉得可以省掉, 因为低于23的版本,会直接授予所申请的权限,也就是会走"已经授权"的位置
注意事项
1. Manifest中必须添加uses-permission, 而且如果menifest中没有添加任何权限,调用requestPermissions会crash
2.一旦选择过一次"不再询问", 即便调用了requestPermissions也不会弹出请求权限的提示.而且这个状态会一直被记录(包括卸载->重新安装程序),直到在设定中将其授权
3. 为了兼容更低版本,建议在activity中试用ActivityCompat, 儿不直接调用activity的requestPermissions.