Android动态权限申请
最近接到公司对相关产品进行适配优化的任务,其中很重要的一点就是Android 6.0以上版本的动态权限申请,故记录下解决方法,若有不足望指出。
危险的权限(需要申请)
动态权限封装(父类Activity)
BaseActivity.java
public class BaseActivity extends AppCompatActivity {
private Context mContext;
private onPermissionCallbackInterface mListener;
private static final int CODE_FOR_PERMISSION = 100;
private AlertDialog dialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
}
/**
* 申请权限
* @param permissions
* @param listener
*/
public void onRequestPermission(String[] permissions, onPermissionCallbackInterface listener){
List<String> permissionList = new ArrayList<>();
this.mListener = listener;
//哪些权限需要申请
for (String permission : permissions){
if (ActivityCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED){
//权限没有申请 添加到要申请的权限列表中
permissionList.add(permission);
}
}
if (!permissionList.isEmpty()) {
ActivityCompat.requestPermissions(this, permissionList.toArray(new String[permissionList.size()]), CODE_FOR_PERMISSION);
} else {
//所有权限都同意了
mListener.onGranted();
}
}
/**
* 权限申请回调
* @param requestCode
* @param permissions
* @param grantResults
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == CODE_FOR_PERMISSION) {
List<String> deniedPermissions = new ArrayList<>();
if (grantResults.length > 0) {
for (int i = 0; i < grantResults.length; i++) {
int grantResult = grantResults[i];
if (grantResult != PackageManager.PERMISSION_GRANTED) {
deniedPermissions.add(permissions[i]);
}
}
}
if (!deniedPermissions.isEmpty()) {
mListener.onDenied(deniedPermissions);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// 用户还是想用我的 APP 的
// 提示用户去应用设置界面手动开启权限
showDialogTipUserGoToAppSetting();
}
}else {
mListener.onGranted();
}
} else {
//所有的权限都被接受了
mListener.onGranted();
}
}
/**
* 提示用户去应用设置界面手动开启权限
*/
private void showDialogTipUserGoToAppSetting(){
dialog = new AlertDialog.Builder(this)
.setTitle("提示")
.setMessage("已禁用权限,请手动开启")
.setPositiveButton("设置", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//
goToAppSetting();
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//新提示AlertDialog
new AlertDialog.Builder(mContext)
.setTitle("提示")
.setMessage("您后续可进入设置开启权限")
.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}).setCancelable(false).show();
}
}).setCancelable(false).show();
}
/**
* 跳转至当前应用的设置界面
*/
private void goToAppSetting(){
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package",getPackageName(),null);
intent.setData(uri);
startActivity(intent);
}
}
onPermissionCallbackInterface.java接口
package com.example.administrator.myapplication;
import java.util.List;
public interface onPermissionCallbackInterface {
void onGranted();
void onDenied(List<String> deniedPermissions);
}
MainActivity.java子类调用
public class MainActivity extends BaseActivity{
private String[] permissionList = new String[]{
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.ACCESS_FINE_LOCATION
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
onRequestPermission(permissionList, new onPermissionCallbackInterface() {
@Override
public void onGranted() {
Log.i("permission", "Permissions granted");
}
@Override
public void onDenied(List<String> deniedPermissions) {
Log.i("permission", "Permissions denied");
}
});
}
}
动态权限封装(工具类)
PermissionUtils.java
public class PermissionUtils {
private final int mRequestCode = 100;//权限请求码
private AlertDialog dialog;
private onPermissionCallbackListener mListener;
private static PermissionUtils permissionUtils;
private PermissionUtils() {
}
public static PermissionUtils getInstance() {
if (permissionUtils == null) {
synchronized (PermissionUtils.class) {
if (permissionUtils == null) {
permissionUtils = new PermissionUtils();
}
}
}
return permissionUtils;
}
public void onRequestPermission(Activity context, String[] permissions, onPermissionCallbackListener listener) {
mListener = listener;
if (Build.VERSION.SDK_INT >= 23) {//6.0才用动态权限
//创建一个mPermissionList,逐个判断哪些权限未授予,未授予的权限存储到mPermissionList中
List<String> mPermissionList = new ArrayList<>();
//逐个判断你要的权限是否已经通过
for (int i = 0; i < permissions.length; i++) {
if (ContextCompat.checkSelfPermission(context, permissions[i]) != PackageManager.PERMISSION_GRANTED) {
mPermissionList.add(permissions[i]);//添加还未授予的权限
}
}
//申请权限
if (mPermissionList.size() > 0) {//有权限没有通过,需要申请
ActivityCompat.requestPermissions(context, mPermissionList.toArray(new String[mPermissionList.size()]), mRequestCode);
} else {
//说明权限都已经通过,可以做你想做的事情去
mListener.onGranted();
}
}
}
//请求权限后回调的方法
//参数: requestCode 是我们自己定义的权限请求码
//参数: permissions 是我们请求的权限名称数组
//参数: grantResults 是我们在弹出页面后是否允许权限的标识数组,数组的长度对应的是权限名称数组的长度,数组的数据0表示允许权限,-1表示我们点击了禁止权限
public void onRequestPermissionsResult(Activity context, int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == mRequestCode) {
List<String> deniedPermissions = new ArrayList<>();
if (grantResults.length > 0) {
for (int i = 0; i < grantResults.length; i++) {
int grantResult = grantResults[i];
if (grantResult != PackageManager.PERMISSION_GRANTED) {
deniedPermissions.add(permissions[i]);
}
}
}
if (!deniedPermissions.isEmpty()) {
mListener.onDenied(deniedPermissions);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// 用户还是想用我的 APP 的
// 提示用户去应用设置界面手动开启权限
showDialogTipUserGoToAppSetting(context);
}
}else {
mListener.onGranted();
}
} else {
//所有的权限都被接受了
mListener.onGranted();
}
}
/**
* 提示用户去应用设置界面手动开启权限
*/
private void showDialogTipUserGoToAppSetting(final Activity context){
dialog = new AlertDialog.Builder(context)
.setTitle(context.getResources().getString(R.string.alert_title))
.setMessage(context.getResources().getString(R.string.alert_content))
.setPositiveButton(context.getResources().getString(R.string.confirm_btn), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//
goToAppSetting(context);
}
})
.setNegativeButton(context.getResources().getString(R.string.cancel_btn), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//新提示AlertDialog
new AlertDialog.Builder(context)
.setTitle(context.getResources().getString(R.string.alert_title))
.setMessage(context.getResources().getString(R.string.alert_content1))
.setPositiveButton(context.getResources().getString(R.string.confirm), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}).setCancelable(false).show();
}
}).setCancelable(false).show();
}
/**
* 跳转至当前应用的设置界面
*/
private void goToAppSetting(final Activity context){
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package",context.getPackageName(),null);
intent.setData(uri);
context.startActivity(intent);
}
}
Activity调用
//单例模式获取PermissionUtils对象
PermissionUtils.getInstance().onRequestPermission(MainActivity.this, adasPermissionList, new onPermissionCallbackListener() {
@Override
public void onGranted() {
Log.e(TAG, navigationPermissionList.length + "Granted");
}
@Override
public void onDenied(List<String> deniedPermissions) {
Log.e(TAG, deniedPermissions.size() + "Permissions Denied");
}
});
//重写回调方法
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
PermissionUtils.getInstance().onRequestPermissionsResult(this,
requestCode, permissions, grantResults);
}
总结
参考其他博主总结的两种方法,个人偏向工具类,复用性更高。当然开发过程中遇到的实际情况不同,至于用哪一种就看各位喜好了。