关于动态管理权限说明:
官方6.0之后对权限进行了一些设置,导致6.0以上的安卓手机在获取部分权限的时候需要动态申请!
下面来说下
(注:以下9组权限,只要每组中获取组中的一个权限,就可以认为是获取了该组全部权限)
//联系人权限
group:android.permission-group.CONTACTS
permission:android.permission.WRITE_CONTACTS
permission:android.permission.GET_ACCOUNTS
permission:android.permission.READ_CONTACTS
//手机状态权限
group:android.permission-group.PHONE
permission:android.permission.READ_CALL_LOG
permission:android.permission.READ_PHONE_STATE
permission:android.permission.CALL_PHONE
permission:android.permission.WRITE_CALL_LOG
permission:android.permission.USE_SIP
permission:android.permission.PROCESS_OUTGOING_CALLS
permission:com.android.voicemail.permission.ADD_VOICEMAIL
//日历权限
group:android.permission-group.CALENDAR
permission:android.permission.READ_CALENDAR
permission:android.permission.WRITE_CALENDAR
//相机权限
group:android.permission-group.CAMERA
permission:android.permission.CAMERA
//传感器权限
group:android.permission-group.SENSORS
permission:android.permission.BODY_SENSORS
//定位权限
group:android.permission-group.LOCATION
permission:android.permission.ACCESS_FINE_LOCATION
permission:android.permission.ACCESS_COARSE_LOCATION
//SD卡权限
group:android.permission-group.STORAGE
permission:android.permission.READ_EXTERNAL_STORAGE
permission:android.permission.WRITE_EXTERNAL_STORAGE
//麦克相关权限
group:android.permission-group.MICROPHONE
permission:android.permission.RECORD_AUDIO
//短信权限
group:android.permission-group.SMS
permission:android.permission.READ_SMS
permission:android.permission.RECEIVE_WAP_PUSH
permission:android.permission.RECEIVE_MMS
permission:android.permission.RECEIVE_SMS
permission:android.permission.SEND_SMS
permission:android.permission.READ_CELL_BROADCASTS
其余的是原来的基础权限
android.permission.ACCESS_LOCATION_EXTRA_COMMANDS
android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_NOTIFICATION_POLICY
android.permission.ACCESS_WIFI_STATE
android.permission.ACCESS_WIMAX_STATE
android.permission.BLUETOOTH
android.permission.BLUETOOTH_ADMIN
android.permission.BROADCAST_STICKY
android.permission.CHANGE_NETWORK_STATE
android.permission.CHANGE_WIFI_MULTICAST_STATE
android.permission.CHANGE_WIFI_STATE
android.permission.CHANGE_WIMAX_STATE
android.permission.DISABLE_KEYGUARD
android.permission.EXPAND_STATUS_BAR
android.permission.FLASHLIGHT
android.permission.GET_ACCOUNTS
android.permission.GET_PACKAGE_SIZE
android.permission.INTERNET
android.permission.KILL_BACKGROUND_PROCESSES
android.permission.MODIFY_AUDIO_SETTINGS
android.permission.NFC
android.permission.READ_SYNC_SETTINGS
android.permission.READ_SYNC_STATS
android.permission.RECEIVE_BOOT_COMPLETED
android.permission.REORDER_TASKS
android.permission.REQUEST_INSTALL_PACKAGES
android.permission.SET_TIME_ZONE
android.permission.SET_WALLPAPER
android.permission.SET_WALLPAPER_HINTS
android.permission.SUBSCRIBED_FEEDS_READ
android.permission.TRANSMIT_IR
android.permission.USE_FINGERPRINT
android.permission.VIBRATE
android.permission.WAKE_LOCK
android.permission.WRITE_SYNC_SETTINGS
com.android.alarm.permission.SET_ALARM
com.android.launcher.permission.INSTALL_SHORTCUT
com.android.launcher.permission.UNINSTALL_SHORTCUT
这个权限,在使用 api 23开发环境 开发的时候
默认写在AndroidManifest.xml 清单文件中,如果是用debug运行的项目,是获取不到这个权限的,即如果使用到这个权限,会报错这个权限未授权。
只能用打了签名,即release的才能获取到权限。
这个问题我查了下 属于官方开发环境的bug,官方在7.0开发环境(api25)之后修复了这个bug。
所以用api23开发环境的时候 注意下这个问题就好了。
官方权限demo
ActivityCompat.checkSelfPermission(activity,permission)
返回的结果有两个
PackageManager.PERMISSION_GRANTED 权限允许
PackageManager.PERMISSION_DENIED 权限拒绝
ActivityCompat.requestPermissions(activity, permissions, code);
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
在反馈中判断用户点击的权限是否获取或者拒绝,其实就在这个反馈中在判断一次权限是否获取
ActivityCompat.shouldShowRequestPermissionRationale(activity, permission)
这个是当被拒绝的时候可以调用下。不过目前安卓系统太多,例如小米的系统 导致这个方法一直返回的都是false 所以这边就提及下就好了
例如我在一个activity中获取相机权限
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
if(ActivityCompat.checkSelfPermission(this,Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.CAMERA},0);
}else{
//权限以获取 进行下一步
}
}
然后再onRequestPermissionsResult方法中判断回调
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
if (requestCode == 0){
//由于只有一个权限 所以这边可以直接获取第一个就好了
if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
//被用户允许 进行下一步
}else{
//被用户拒绝 进行后续逻辑
//如 打开软件设置让用户自己设置
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
intent.setData(Uri.fromParts("package", getPackageName(), null));
startActivity(intent);
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
流程特别的简单
先判断权限是否获取 未获取 去申请权限 在等反馈 告知用户是否同意权限
基于以上 写了一个简单的工具类
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.support.v4.app.ActivityCompat;
import android.util.Log;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* PermissionUtils
* Author: gjn.
* Time: 2017/11/3.
*/
public class PermissionUtils {
private static final String TAG = "PermissionUtils";
public static final int CODE_CALENDAR = 0; //日历权限
public static final int CODE_CAMERA = 1; //相机权限
public static final int CODE_CONTACTS = 2; //联系人权限
public static final int CODE_LOCATION = 3; //定位权限
public static final int CODE_MICROPHONE = 4; //麦克相关权限
public static final int CODE_PHONE = 5; //手机状态权限
public static final int CODE_SENSORS = 6; //传感器权限
public static final int CODE_SMS = 7; //短信权限
public static final int CODE_STORAGE = 8; //SD卡权限
public static final int CODE_MULTI = 111; //多个权限
public static final String PERMISSION_READ_CALENDAR = Manifest.permission.READ_CALENDAR;
public static final String PERMISSION_CAMERA = Manifest.permission.CAMERA;
public static final String PERMISSION_WRITE_CONTACTS = Manifest.permission.WRITE_CONTACTS;
public static final String PERMISSION_ACCESS_FINE_LOCATION = Manifest.permission.ACCESS_FINE_LOCATION;
public static final String PERMISSION_RECORD_AUDIO = Manifest.permission.RECORD_AUDIO;
public static final String PERMISSION_READ_PHONE_STATE = Manifest.permission.READ_PHONE_STATE;
public static final String PERMISSION_BODY_SENSORS = Manifest.permission.BODY_SENSORS;
public static final String PERMISSION_READ_SMS = Manifest.permission.READ_SMS;
public static final String PERMISSION_READ_EXTERNAL_STORAGE = Manifest.permission.READ_EXTERNAL_STORAGE;
public static final Map codePermissions = new HashMap<>();
static {
codePermissions.put(CODE_CALENDAR, "日历权限");
codePermissions.put(CODE_CAMERA, "相机权限");
codePermissions.put(CODE_CONTACTS, "联系人权限");
codePermissions.put(CODE_LOCATION, "定位权限");
codePermissions.put(CODE_MICROPHONE, "麦克相关权限");
codePermissions.put(CODE_PHONE, "手机状态权限");
codePermissions.put(CODE_SENSORS, "传感器权限");
codePermissions.put(CODE_SMS, "短信权限");
codePermissions.put(CODE_STORAGE, "SD卡权限");
codePermissions.put(CODE_MULTI, "多个权限");
}
public interface PermissionCallBack {
void onSuccess(int code);
void onFaile(int code);
void onConsumer(int code);
}
/**
* 判断是否需要获取权限
* @param activity
* @param code
* @param permissions
* @return
*/
public static boolean requestPermissions(Activity activity, int code, String... permissions){
if (Build.VERSION.SDK_INT < 23) {
Log.d(TAG, "api < 23");
return false;
}
List notGranted = new ArrayList<>();
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(activity, permission)
!= PackageManager.PERMISSION_GRANTED){
notGranted.add(permission);
}
}
if (notGranted.size() != 0){
ActivityCompat.requestPermissions(activity,
notGranted.toArray(new String[notGranted.size()]), code);
return true;
}
return false;
}
/**
* 判断是否需要获取权限
* @param activity
* @param code
* @return
*/
public static boolean requestPermissions(Activity activity, Integer... code){
List permissions = new ArrayList<>();
List codes = Arrays.asList(code);
//日历权限
if (codes.contains(CODE_CALENDAR)) {
permissions.add(PERMISSION_READ_CALENDAR);
}
//相机权限
if (codes.contains(CODE_CAMERA)) {
permissions.add(PERMISSION_CAMERA);
}
//联系人权限
if (codes.contains(CODE_CONTACTS)) {
permissions.add(PERMISSION_WRITE_CONTACTS);
}
//定位权限
if (codes.contains(CODE_LOCATION)) {
permissions.add(PERMISSION_ACCESS_FINE_LOCATION);
}
//麦克相关权限
if (codes.contains(CODE_MICROPHONE)) {
permissions.add(PERMISSION_RECORD_AUDIO);
}
//手机状态权限
if (codes.contains(CODE_PHONE)) {
permissions.add(PERMISSION_READ_PHONE_STATE);
}
//传感器权限
if (codes.contains(CODE_SENSORS)) {
permissions.add(PERMISSION_BODY_SENSORS);
}
//短信权限
if (codes.contains(CODE_SMS)) {
permissions.add(PERMISSION_READ_SMS);
}
//SD卡权限
if (codes.contains(CODE_STORAGE)) {
permissions.add(PERMISSION_READ_EXTERNAL_STORAGE);
}
if (permissions.size() == 0){
return false;
}
return requestPermissions(activity,CODE_MULTI,
permissions.toArray(new String[permissions.size()]));
}
public static void requestPermissionsResult(Activity activity, int requestCode,
String[] permissions, int[] grantResults,
PermissionCallBack callBack){
if (Build.VERSION.SDK_INT < 23) {
Log.d(TAG, "api < 23");
return;
}
List notGranted = new ArrayList<>();
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] != PackageManager.PERMISSION_GRANTED){
notGranted.add(permissions[i]);
}
}
if (notGranted.size() != 0) {
StringBuilder notGrantedString = new StringBuilder();
notGrantedString.append("被拒绝权限:\n");
for (String s : notGranted) {
notGrantedString.append(s+"\n");
}
notGrantedString.append("请进入 软件设置 -> 权限管理 中获取");
showPermissionDialog(activity, notGrantedString.toString(),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
startAppSettingIntent(activity);
callBack.onConsumer(requestCode);
}
}, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
callBack.onFaile(requestCode);
}
});
}else{
callBack.onSuccess(requestCode);
}
}
public static void startAppSettingIntent(Activity activity) {
Toast.makeText(activity, "获取权限之后,请重启软件!", Toast.LENGTH_SHORT).show();
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
intent.setData(Uri.fromParts("package", activity.getPackageName(), null));
activity.startActivity(intent);
}
public static void showPermissionDialog(Activity activity, String message,
DialogInterface.OnClickListener oklistener,
DialogInterface.OnClickListener canclelistener) {
new AlertDialog.Builder(activity)
.setTitle("帮助")
.setMessage(message)
.setCancelable(false)
.setPositiveButton("获取", oklistener)
.setNegativeButton("退出", canclelistener)
.create()
.show();
}
}
if(!PermissionUtils.requestPermissions(mActivity,
PermissionUtils.CODE_CAMERA,
PermissionUtils.CODE_PHONE,
PermissionUtils.CODE_STORAGE)){
//权限已经获取 直接下一步
}
然后再反馈中加入反馈就好了
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
PermissionUtils.requestPermissionsResult(mActivity, requestCode,
permissions, grantResults, new PermissionUtils.PermissionCallBack() {
@Override
public void onSuccess(int code) {
Log.e("-s-", "成功"+code);
}
@Override
public void onFaile(int code) {
Log.e("-s-", "失败"+code);
}
@Override
public void onConsumer(int code) {
Log.e("-s-", "自定义"+code);
}
});
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
以上就是一个简单的6.0动态权限获取工具类
最后还是要说一下 记得在清单文件先写入权限