关于android6.0权限
2016-12-05 23:38
330 查看
关于android6.0权限
一,权限变化
android6.0及以后版本权限体制发生变化,权限可以分为系统权限和特殊权限。系统权限中,又分为normal和dangerous类型,危险权限需要程序员显示的向系统申请授权!normal:这个权限类型一般不涉及到用户隐私,可以直接在manifest清单里注册,系统会帮我们默认授权
dangerous:这个权限类型一般是涉及到用户隐私的,不仅需要在manifest清单里注册,同时在使用的时候,需要显示向系统请求授权。一般dangerous类型权限是分组的,组内一个权限被授权其他权限默认也被授权
二,官方相关API解释
1,在AndroidManifest文件中添加需要的权限
2,显示检查权限(对于dangerous类型)
if (checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { } else { }
方法返回值为PackageManager.PERMISSION_DENIED或者PackageManager.PERMISSION_GRANTED
3,显示申请授权(对于dangerous类型)
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, MY_PERMISSIONS_REQUEST_READ_CONTACTS);
该方法是异步的,第一个参数是Context;第二个参数是需要申请的权限的字符串数组;第三个参数为requestCode,主要用于回调的时候检测。
4,处理权限申请回调
@Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case MY_PERMISSIONS_REQUEST_READ_CONTACTS: { if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { // permission was granted, yay! do the // calendar task you need to do. } else { // permission denied, boo! Disable the // functionality that depends on this permission. } return; } // other 'switch' lines to check for other // permissions this app might request } }
5,特殊API
// Should we show an explanation? if (shouldShowRequestPermissionRationale( Manifest.permission.READ_CONTACTS)) { // Explain to the user why we need to read the contacts } /** 1. 关于shouldShowRequestPermissionRationale函数的一点儿注意事项: 2. 应用安装后第一次访问,则直接返回false; 3.第一次请求权限时,用户Deny了,再次调用shouldShowRequestPermissionRationale(),则返回true; 4.第二次请求权限时,用户Deny了,并选择了“dont ask me again”的选项时,再次调用shouldShowRequestPermissionRationale()时,返回false; 5.设备的系统设置中,禁止了应用获取这个权限的授权,则调用shouldShowRequestPermissionRationale(),返回false。 */
三,封装permissionUtil工具类
android6.0以后的权限机制使权限不能泛滥使用了,但每次显示申请重复性代码太多,然后封装个工具类吧整个权限的申请与处理的过程是这样的:
第一次安装并进入软件,首先申请所有的权限;
用户对权限进行授权,有2种情况:
1).用户Allow了权限,则表示该权限已经被授权,无须其它操作;
2).用户Deny了权限,则下次启动Activity会再次弹出系统的Permisssions申请授权对话框。
如果用户Deny了权限,那么下次再次进入Activity,会再次申请权限,这次的权限对话框上,会有一个选项“dont ask me again”:
1).如果用户勾选了“dont ask me again”的checkbox,下次启动时就必须自己写Dialog或者Snackbar引导用户到应用设置里面去手动授予权限;
2).如果用户未勾选上面的选项,若选择了Allow,则表示该权限已经被授权,无须其它操作;
3).如果用户未勾选上面的选项,若选择了Deny,则下次启动Activity会再次弹出系统的Permisssions申请授权对话框。
package com.example.hei.baidumapsdktest.Utils; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; import android.provider.Settings; import android.support.annotation.RequiresApi; import android.support.design.widget.Snackbar; import android.view.View; import com.example.hei.baidumapsdktest.R; import java.util.ArrayList; /** * Created by hei on 2016/12/5. */ public class permissionUtil { private static int MY_PERMISSION_REQUEST_CODE = 666; private static int MY_PERMISSION_REQUEST_SETTING = 555; @RequiresApi(api = Build.VERSION_CODES.M) public static void addPermission(final Activity activity, String [] permissionGroup ) { ArrayList<String> deniedArray = new ArrayList<>(); if (isAppFirstRun(activity)) {//程序安装好第一次进入 for (String permission : permissionGroup) {//遍历需要授权的权限 4000 if (activity.checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {//当该权限未授权时 deniedArray.add(permission);//把未授权权限加入list } } } else {//程序不是第一次进入 for (String permission : permissionGroup) {//遍历需要授权的权限 if (activity.checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {//当该权限未授权时 if (activity.shouldShowRequestPermissionRationale(permission)) {// 当上次弹出系统权限提示框点击deny后返回true deniedArray.add(permission); }else {//当上次系统权限提示框点击deny和不再提示时返回false进入 Snackbar snackbar =Snackbar.make(activity.getWindow().getDecorView().findViewById(android.R.id.content),"请开启权限,否则部分功能不可用", Snackbar.LENGTH_LONG)//自定义提示进入设置界面 .setAction("去设置", new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); Uri uri = Uri.fromParts("package", activity.getPackageName(), null); intent.setData(uri); activity.startActivityForResult(intent, MY_PERMISSION_REQUEST_SETTING); } }); snackbar.show(); } } } } if (deniedArray.size() > 0) { activity.requestPermissions(deniedArray.toArray(new String[deniedArray.size()]), MY_PERMISSION_REQUEST_CODE);//请求list里面的权限并弹出授权选择提示框 } } public static boolean isAppFirstRun(Activity activity) { SharedPreferences sp = activity.getSharedPreferences("config", Context.MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); if (sp.getBoolean("first_run", true)) { editor.putBoolean("first_run", false); editor.commit(); return true; } else { editor.putBoolean("first_run", false); editor.commit(); return false; } } }
四,总结
android6.0及以上版本权限模型跟原来版本不同,normal权限在manifest中申明系统默认授权,而是dangerous不仅需要声明,有需要的时候向系统显示请求授权,提高用户体验。了解权限检测流程,一点注意点是如果系统权限弹窗提示框被不再提醒了,需要我们自定义提示弹窗,引导用户去授权。
掌握系统有关权限接口并封装权限工具类
相关文章推荐
- 论Android代码加固的意义和hook
- 论Android代码加固的意义和hook
- 论Android代码加固的意义和hook
- Android动画----Set
- android raw与assets区别
- Freeline - Android平台上的秒级编译方案
- Android中使用GridView和ImageViewSwitcher实现电子相册简单功能
- android程序如何调用支付宝接口
- android-Ultra-Pull-To-Refresh 源码解析 收藏 项目:android-Ultra-Pull-To-Refresh
- Android Design Support Library(三)用CoordinatorLayout实现Toolbar隐藏和折叠
- Android Design Support Library(二)用NavigationView实现抽屉菜单界面
- 解决ScrollView嵌套Listview 显示问题
- Android 新安全机制之动态权限申请
- Android POPWindow
- 命令模式(Command)
- Android FFMpeg(一)——编译FFmpeg
- Android Design Support Library(一)用TabLayout实现类似网易选项卡动态滑动效果
- Android Studio is on board
- android沉浸式导航栏与键盘的冲突
- android-Ultra-Pull-To-Refresh使用教程