在Android6.0之前只需在AndroidManifest.xml文件写明权限即可。但是在Android6.0之后也就是SDK>=23的时候,一些隐私权限需要动态申请,而且在用户同意授权之后App才能拥有该权限。
如下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
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.REA
D_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
动态权限总共有三个方法:
ContextCompat.checkSelfPermission() 检查权限是否已经授权
ActivityCompat.requestPermissions()动态申请权限,并弹出对话框。
onRequestPermissionsResult()在activity里面重写该方法该方法是权限申请之后的回调方法。
当然。动态权限申请也要在AndroidManifest.xml里面写明。附上代码
public class MainActivity extends Activity {
DynamicPermissions mPer = new DynamicPermissions();
public static String[] mPermissions = new String[]{
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPer.setInitData(this, mPermissions, new DynamicPermissions.PermissionsTo() {
/**
* 已经授权
* */
@Override
public void hasAuthorizeinit(Context context) {
init();
}
/**
* 低版本无需授权
* */
@Override
public void noAuthorizeinit(Context context) {
init();
}
/**
* 授权完成且成功
* */
@Override
public void authorizeinitSuccess(Context context) {
init();
}
/**
* 授权失败
* */
@Override
public void authorizeinitFail(Context context) {
}
});
mPer.destroy();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
mPer.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
如果有多项权限需要动态申请。那么只需要把权限写入permission数组即可。下面也给出修改后的代码
public class DynamicPermissions {
private String TAG = "DynamicPermissions";
public PermissionsTo mPermissionsTo;
private int KEY = 101;
/*
要添加List原因是想判断数组里如果有个别已经授权的权限,就不需要再添加到List中。添加到List中的权限后续将转成数组去申请权限
*/
private List<String> mList = new ArrayList<>();
private Context mContext;
private String[] mPermissionsGroup;
public DynamicPermissions() {
}
/**
* 导入数据的方法
*
* @param context 上下文
* @param permissionsGroup 需要授权的权限数组
* @param permissionsTo 授权后处理事件的接口回调
*/
public void setInitData(Context context, String[] permissionsGroup, PermissionsTo permissionsTo) {
this.mContext = context;
this.mPermissionsGroup = permissionsGroup;
this.mPermissionsTo = permissionsTo;
privilege();
}
//授权
private void privilege() {
mList.clear();//清除权限
//判断系统版本
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
for (int i = 0; i < mPermissionsGroup.length; i++) {
//判断权限是否已经允许授权,如果没有授权就会将单个未授权的权限添加到List里面
if (ContextCompat.checkSelfPermission(mContext, mPermissionsGroup[i]) != PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "privilege: 需要授权的权限=" + mPermissionsGroup[i]);
mList.add(mPermissionsGroup[i]);
}
}
//判断List不是空的,如果有内容就运行获取权限
if (!mList.isEmpty()) {
String[] permissions = mList.toArray(new String[mList.size()]);
//执行授权的代码。此处执行后会弹窗授权
ActivityCompat.requestPermissions((Activity) mContext, permissions, KEY);
Log.i(TAG, "privilege: 正在授权");
} else { //如果是空的说明全部权限都已经授权了,就不授权了,吊起接口
Log.i(TAG, "privilege: 已经授权,不需要授权");
if (mPermissionsTo != null) {
this.mPermissionsTo.hasAuthorizeinit(mContext);
}
}
} else {
Log.i(TAG, "privilege:6.0以下的版本无需授权");
if (mPermissionsTo != null) {
this.mPermissionsTo.noAuthorizeinit(mContext);
}
}
}
/**
* 处理授权后的接口回调,请将这个方法在外部需要授权的activity的授权回调里重写
*
* @param requestCode
* @param permissions
* @param grantResults
*/
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == KEY) {
int count = 0;
if (grantResults.length > 0) {//安全写法,如果小于0,肯定会出错了
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "onRequestPermissionsResult:授权成功" + permissions[i].toString());
count++;
} else {
Log.e(TAG, "onRequestPermissionsResult:授权失败" + permissions[i].toString());
}
}
}
if (count == grantResults.length && count != 0) {
Log.i(TAG, "onRequestPermissionsResult:全部权限都授权成功");
if (mPermissionsTo != null) {
this.mPermissionsTo.authorizeinitSuccess(mContext);
}
} else {
Log.e(TAG, "onRequestPermissionsResult:有授权失败的item");
if (mPermissionsTo != null) {
mPermissionsTo.authorizeinitFail(mContext);
}
}
}
/* 单个判断 Permissions_READ_PHONE_KEY 就是集合集合里面的权限,可以传一个变量过来单个判断
if (requestCode == Permissions_READ_PHONE_KEY) {
if (grantResults.length > 0) { //安全写法,如果小于0,肯定会出错了
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
Log.e(TAG, "全部权限都成功授权进入");
// code
} else {
finish();
Toast.makeText(getBaseContext(), "授权失败", Toast.LENGTH_SHORT).show();
Log.e(TAG, "读取手机授权失败");
}
}
}
}else if (requestCode == Permissions_WRITE_EX_KEY) {
if (requestCode == Permissions_WRITE_EX_KEY) {
if (grantResults.length > 0) {
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
Log.e(TAG, "全部权限都成功授权进入");
// code
} else {
finish();
Toast.makeText(getBaseContext(), "授权失败", Toast.LENGTH_SHORT).show();
Log.e(TAG, "sd卡授权失败");
}
}
}
}
}*/
}
//创建回调接口
public interface PermissionsTo {
void hasAuthorizeinit(Context context); //已经授权
void noAuthorizeinit(Context context); //低版本无需授权
void authorizeinitSuccess(Context context); //授权完成且成功
void authorizeinitFail(Context context); //授权失败
}
public void destroy() {
this.mContext = null;
}
}