您的位置:首页 > 移动开发 > Android开发

关于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不仅需要声明,有需要的时候向系统显示请求授权,提高用户体验。

了解权限检测流程,一点注意点是如果系统权限弹窗提示框被不再提醒了,需要我们自定义提示弹窗,引导用户去授权

掌握系统有关权限接口并封装权限工具类
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息