- 1:android 6.0(版本号23)以后,权限系统发生了变化,有些权限决定给了用户,需要用户同意后才能获取此权限
- 2:Google将权限分为两类,一类是Normal Permissions,这类权限一般不涉及用户隐私,是不需要用户进行授权的,比如手机震动、访问网络等;另一类是Dangerous Permission,一般是涉及到用户隐私的,需要用户进行授权,比如读取sdcard、访问通讯录等。
Normal Permissions
ACCESS_LOCATION_EXTRA_COMMANDSACCESS_NETWORK_STATEACCESS_NOTIFICATION_POLICYACCESS_WIFI_STATEBLUETOOTHBLUETOOTH_ADMINBROADCAST_STICKYCHANGE_NETWORK_STATECHANGE_WIFI_MULTICAST_STATECHANGE_WIFI_STATEDISABLE_KEYGUARDEXPAND_STATUS_BARGET_PACKAGE_SIZEINSTALL_SHORTCUTINTERNET //网络权限KILL_BACKGROUND_PROCESSESMODIFY_AUDIO_SETTINGSNFCREAD_SYNC_SETTINGSREAD_SYNC_STATSRECEIVE_BOOT_COMPLETEDREORDER_TASKSREQUEST_INSTALL_PACKAGESSET_ALARMSET_TIME_ZONESET_WALLPAPERSET_WALLPAPER_HINTSTRANSMIT_IRUNINSTALL_SHORTCUTUSE_FINGERPRINTVIBRATEWAKE_LOCKWRITE_SYNC_SETTINGS
Dangerous Permissions:
group:android.permission-group.CONTACTS permission:android.permission.WRITE_CONTACTS permission:android.permission.GET_ACCOUNTS permission:android.permission.READ_CONTACTSgroup:android.permission-group.PHONE permission:android.permission.READ_CALL_LOG
//读取手机状态。比如IMEI号 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_VOICEMAILgroup: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_SENSORSgroup:android.permission-group.LOCATION permission:android.permission.ACCESS_FINE_LOCATION permission:android.permission.ACCESS_COARSE_LOCATION//读取,写入手机存储权限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_AUDIOgroup: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
注意:如果你申请某个危险的权限,假设你的app早已被用户授权了同一组的某个危险权限,那么系统会立即授权,而不需要用户去点击授权
- 3:动态权限的使用
if(Build.VERSION.SDK_INT>=23){ //判断是否有这个权限 if(ContextCompat.checkSelfPermission(context,Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){
//第一请求权限被取消显示的判断,一般可以不写
if(ActivityCompat.shouldShowRequestPermissionRationale(WechatQrcodeActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)){
showAlert();
}else {
//2、申请权限: 参数二:权限的数组;参数三:请求码
ActivityCompat.requestPermissions(WechatQrcodeActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
//fragment 申请
xxxFragment.this.requestPermissions( new String[]{Manifest.permission.CAMERA},1);
}
}else {
}
} else{
}
private void showAlert(){
Dialog alertDialog = new AlertDialog.Builder(this).
setTitle("权限说明").
setMessage("我们需要这个权限给你提供存储服务").
setIcon(R.mipmap.icon).
setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(WechatQrcodeActivity.this,
new String[{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
}
}).
setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}).
create();
alertDialog.show();
}
1:检查权限
ContextCompat.checkSelfPermission,主要用于检测某个权限是否已经被授予,方法返回值为PackageManager.PERMISSION_DENIED或者PackageManager.PERMISSION_GRANTED。当返回DENIED就需要进行申请授权了。
2:申请授权 该方法是异步的,第一个参数是Context;第二个参数是需要申请的权限的字符串数组;第三个参数为requestCode,主要用于回调的时候检测。可以从方法名requestPermissions以及第二个参数看出,是支持一次性申请多个权限的,系统会通过对话框逐一询问用户是否授权。
3:第一请求权限被取消后,这里可以提醒用户
if(ActivityCompat.shouldShowRequestPermissionRationale(WechatQrcodeActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
4:处理权限申请回调
//判断授权的方法 授权成功直接调用写入方法 这是监听的回调
//参数 上下文 授权结果的数组 申请授权的数组
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode==1&&grantResults[0]== PackageManager.PERMISSION_GRANTED){
}
}
ok,对于权限的申请结果,首先验证requestCode定位到你的申请,然后验证grantResults对应于申请的结果,这里的数组对应于申请时的第二个权限字符串数组。如果你同时申请两个权限,那么grantResults的length就为2,分别记录你两个权限的申请结果。如果申请成功,就可以做你的事情了
- 4封装框架
https://github.com/lovedise/PermissionGen
- 用户拒接授权。不在提示
监听用户选取不在提示,跳转到应用管理
//不在提示监听
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if(!ActivityCompat.shouldShowRequestPermissionRationale(ProductCommentActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE){
//跳转到权限管理
PermissionUtil.gotoPermission(ProductCommentActivity.this, "存储和拍摄照
片");
}
}
/*
*系统权限管理设置
*/
public class PermissionUtil {
//直接跳转到应用信息
public static void gotoPermission(final Context context,String info) {
String msg ="你未开启允许***访问"+info+"选项,请到系统设置中开启。";
DialogUtils.customDialog(context, "***", msg, new View.OnClickListener() {
@Override
public void onClick(View view) {
context.startActivity(getAppDetailSettingIntent(context));
}
});
}
//跳转到应用列表,不同的手机厂商。不一样。
public static void gotoPermission(final Context contex) {
String brand = Build.BRAND;//手机厂商
try {
if (TextUtils.equals(brand.toLowerCase(), "redmi") || TextUtils.equals(brand.toLowerCase(), "xiaomi")) {
PermissionUtil.gotoMiuiPermission(context);//小米
} else if (TextUtils.equals(brand.toLowerCase(), "meizu")) {
PermissionUtil.gotoMeizuPermission(context);
} else if (TextUtils.equals(brand.toLowerCase(), "huawei") || TextUtils.equals(brand.toLowerCase(), "honor")) {
PermissionUtil.gotoHuaweiPermission(context);
} else if (TextUtils.equals(brand.toLowerCase(), "Sony")) {
PermissionUtil.gotoSony(context);
}else if (TextUtils.equals(brand.toLowerCase(), "OPPO")) {
PermissionUtil.gotoOppo(context);
}
else if (TextUtils.equals(brand.toLowerCase(), "LG")) {
PermissionUtil.gotoLg(context);
} else if (TextUtils.equals(brand.toLowerCase(), "360")) {
PermissionUtil.goto360(context);
}
else {
context.startActivity(PermissionUtil.getAppDetailSettingIntent(context));
}
} catch (Exception e) {
e.printStackTrace();
context.startActivity(getAppDetailSettingIntent(context));
}
}
private static void gotoOppo(Context context) throws Exception{
Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("packageName", BuildConfig.APPLICATION_ID);
ComponentName comp = new ComponentName("com.color.safecenter", "com.color.safecenter.permission.PermissionManagerActivity");
intent.setComponent(comp);
context.startActivity(intent);
}
private static void goto360(Context context) throws Exception{
Intent intent = new Intent("android.intent.action.MAIN");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("packageName", BuildConfig.APPLICATION_ID);
ComponentName comp = new ComponentName("com.qihoo360.mobilesafe", "com.qihoo360.mobilesafe.ui.index.AppEnterActivity");
intent.setComponent(comp);
context. startActivity(intent);
}
private static void gotoLg(Context context) throws Exception{
Intent intent = new Intent("android.intent.action.MAIN");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("packageName", BuildConfig.APPLICATION_ID);
ComponentName comp = new ComponentName("com.android.settings", "com.android.settings.Settings$AccessLockSummaryActivity");
intent.setComponent(comp);
context. startActivity(intent);
}
private static void gotoSony(Context context) throws Exception{
Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("packageName", BuildConfig.APPLICATION_ID);
ComponentName comp = new ComponentName("com.sonymobile.cta", "com.sonymobile.cta.SomcCTAMainActivity");
intent.setComponent(comp);
context.startActivity(intent);
}
/**
* 跳转到miui的权限管理页面
*/
private static void gotoMiuiPermission(Context context) {
try { // MIUI 8
Intent localIntent = new Intent("miui.intent.action.APP_PERM_EDITOR");
localIntent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.PermissionsEditorActivity");
localIntent.putExtra("extra_pkgname", context.getPackageName());
context.startActivity(localIntent);
} catch (Exception e) {
try { // MIUI 5/6/7
Intent localIntent = new Intent("miui.intent.action.APP_PERM_EDITOR");
localIntent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.AppPermissionsEditorActivity");
localIntent.putExtra("extra_pkgname", context.getPackageName());
context.startActivity(localIntent);
} catch (Exception e1) { // 否则跳转到应用详情
context.startActivity(getAppDetailSettingIntent(context));
}
}
}
/**
* 跳转到魅族的权限管理系统
*/
private static void gotoMeizuPermission(Context context) {
try {
Intent intent = new Intent("com.meizu.safe.security.SHOW_APPSEC");
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.putExtra("packageName", BuildConfig.APPLICATION_ID);
context.startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
context.startActivity(getAppDetailSettingIntent(context));
}
}
/**
* 华为的权限管理页面
*/
private static void gotoHuaweiPermission(Context context) {
LogPrinter.debugError("————————huawei-----------------");
try {
Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("packageName", BuildConfig.APPLICATION_ID);
ComponentName comp = new ComponentName("com.huawei.systemmanager",
"com.huawei.permissionmanager.ui.MainActivity");//华为权限管理
intent.setComponent(comp);
context.startActivity(intent);
intent.setComponent(comp);
} catch (Exception e) {
e.printStackTrace();
context.startActivity(getAppDetailSettingIntent(context));
}
}
/**
* 获取应用详情页面intent(如果找不到要跳转的界面,也可以先把用户引导到系统设置页面)
*/
private static Intent getAppDetailSettingIntent(Context context) {
LogPrinter.debugError("————————系统设置页面-----------------");
Intent localIntent = new Intent();
localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
localIntent.setData(Uri.fromParts("package", context.getPackageName(), null));
context.startActivity(localIntent);
return localIntent;
}
}