Android 6.0动态添加权限(Finn_ZengYuan博客)
1,随着手机版本变高,各种权限也有所限制;以下代码可人性化添加动态权限;
权限工具类1,2,3,4:
1,FinnPermissionConfig.CLass
package com.finn.tools.finnpermission; import android.os.Parcel; import android.os.Parcelable; /** * Author : Finn * E-mail : 892603597@qq.com * Date : 2019/12/5 16:03 * Blog : https://www.cnblogs.com/finn21/ * Describe: * TODO : */ public class FinnPermissionConfig implements Parcelable { //必须要所有的权限都通过才能通过 private boolean forceAllPermissionsGranted; //设置用户点击不再提示之后的弹窗文案 private String forceDeniedPermissionTips; public String getForceDeniedPermissionTips() { return forceDeniedPermissionTips; } public FinnPermissionConfig setForceDeniedPermissionTips(String forceDeniedPermissionTips) { this.forceDeniedPermissionTips = forceDeniedPermissionTips; return this; } private FinnPermissionUtils check; public FinnPermissionConfig(FinnPermissionUtils check) { this.check = check; } public boolean isForceAllPermissionsGranted() { return forceAllPermissionsGranted; } public FinnPermissionConfig setForceAllPermissionsGranted(boolean forceAllPermissionsGranted) { this.forceAllPermissionsGranted = forceAllPermissionsGranted; return this; } public FinnPermissionUtils buildConfig() { return check; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeByte(this.forceAllPermissionsGranted ? (byte) 1 : (byte) 0); dest.writeString(this.forceDeniedPermissionTips); } protected FinnPermissionConfig(Parcel in) { this.forceAllPermissionsGranted = in.readByte() != 0; this.forceDeniedPermissionTips = in.readString(); } public static final Creator<FinnPermissionConfig> CREATOR = new Creator<FinnPermissionConfig>() { @Override public FinnPermissionConfig createFromParcel(Parcel source) { return new FinnPermissionConfig(source); } @Override public FinnPermissionConfig[] newArray(int size) { return new FinnPermissionConfig[size]; } }; }
2,FinnPermissionFragment.Class
package com.finn.tools.finnpermission; import android.annotation.TargetApi; import android.app.Activity; import android.app.AlertDialog; import android.app.Fragment; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Looper; import java.util.ArrayList; import java.util.List; import android.provider.Settings; import android.support.annotation.Nullable; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.text.TextUtils; /***/ public class FinnPermissionFragment extends Fragment { private String[] permissions = null; public static final int PERMISSION_REQUEST_CODE = 1001; public static final int REQUEST_PERMISSION_SETTING = 1002; private FinnPermissionListener permissionCheckListener; private Activity mContext; private FinnPermissionConfig checkConfig; private String forceDeniedPermissionTips = ""; public FinnPermissionFragment setPermissionCheckListener(FinnPermissionListener listener) { this.permissionCheckListener = listener; return this; } public static FinnPermissionFragment newInstance(String[] permissions, FinnPermissionConfig checkConfig) { Bundle args = new Bundle(); args.putStringArray("permissions", permissions); args.putParcelable("config", checkConfig); FinnPermissionFragment fragment = new FinnPermissionFragment(); fragment.setArguments(args); return fragment; } /** * 开始请求 */ public void start(Activity activity) { if (activity != null) { mContext = activity; if (Looper.getMainLooper() != Looper.myLooper()) { return; } activity.getFragmentManager().beginTransaction().add( this, activity.getClass().getName()).commit(); } } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); forceDeniedPermissionTips = "请前往设置->应用->【" + FinnPermissionUtils.getAppName(mContext) + "】->权限中打开相关权限,否则功能无法正常运行!"; //获取传输过来的权限 permissions = this.getArguments().getStringArray("permissions"); checkConfig = this.getArguments().getParcelable("config"); if (checkConfig != null && TextUtils.isEmpty(checkConfig.getForceDeniedPermissionTips())) { checkConfig.setForceDeniedPermissionTips(forceDeniedPermissionTips); } if ((Build.VERSION.SDK_INT < Build.VERSION_CODES.M)) { requestPermissionsSuccess(); } else { requestPermission(); } } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == PERMISSION_REQUEST_CODE) { //记录点击了不再提醒的未授权权限 List<String> forceDeniedPermissions = new ArrayList<>(); //记录点击了普通的未授权权限 List<String> normalDeniedPermissions = new ArrayList<>(); List<String> grantedPermissions = new ArrayList<>(); for (int i = 0; i < grantResults.length; i++) { int grantResult = grantResults[i]; String permission = permissions[i]; if (grantResult == PackageManager.PERMISSION_GRANTED) { //授权通过 nothing to do grantedPermissions.add(permission); } else { //授权拒绝 if (!ActivityCompat.shouldShowRequestPermissionRationale(mContext, permission)) { forceDeniedPermissions.add(permission); } else { normalDeniedPermissions.add(permission); } } } if (forceDeniedPermissions.size() == 0 && normalDeniedPermissions.size() == 0) { //全部授权通过 requestPermissionsSuccess(); } else { //部分授权通过 如果用户希望一直提示授权直到给权限位置 那么就一直去请求权限 if (checkConfig != null && checkConfig.isForceAllPermissionsGranted()) { if (normalDeniedPermissions.size() != 0) { //还有普通拒绝的权限可以弹窗 requestPermission(); } else { //所有没有通过的权限都是用户点击了不再提示的 我擦 这里本来是想把未授权的所有权限的名称列出来展示的 后来想想觉得配置有点麻烦 // StringBuilder deniedString = new StringBuilder(); // for (String forceDeniedPermission : forceDeniedPermissions) { // deniedString.append(forceDeniedPermission + ","); // } // String denied = deniedString.substring(0, deniedString.length() - 1); new AlertDialog.Builder(mContext) .setTitle(mContext.getString(R.string.permissions_check_warn))//警告 .setMessage(checkConfig == null ? forceDeniedPermissionTips : checkConfig.getForceDeniedPermissionTips()) .setCancelable(false) .setPositiveButton(mContext.getString(R.string.permissions_check_ok), new DialogInterface.OnClickListener() {//确定 @Override public void onClick(DialogInterface dialog, int which) { openSettingPage(); } }).show(); } } else { for (String permission : this.permissions) { if (grantedPermissions.contains(permission) || normalDeniedPermissions.contains(permission) || forceDeniedPermissions.contains(permission)) { } else { //如果三者都不包含他 包名这个权限不是隐私权限 直接给就完事了 所以要放到已授权的权限列表里面去 grantedPermissions.add(permission); } } requestPermissionsFail(grantedPermissions.toArray(new String[grantedPermissions.size()]), normalDeniedPermissions.toArray(new String[normalDeniedPermissions.size()]), forceDeniedPermissions.toArray(new String[forceDeniedPermissions.size()])); } } } } private void openSettingPage() { Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); Uri uri = Uri.fromParts("package", mContext.getPackageName(), null); intent.setData(uri); startActivityForResult(intent, REQUEST_PERMISSION_SETTING); } private void requestPermissionsSuccess() { if (permissionCheckListener != null) { permissionCheckListener.permissionRequestSuccess(); } mContext.getFragmentManager().beginTransaction().remove(this).commit(); } private void requestPermissionsFail(String[] grantedPermissions, String[] deniedPermissions, String[] forceDeniedPermissions) { if (permissionCheckListener != null) { permissionCheckListener.permissionRequestFail(grantedPermissions, deniedPermissions, forceDeniedPermissions); } mContext.getFragmentManager().beginTransaction().remove(this).commit(); } /** * 获取权限 */ @TargetApi(Build.VERSION_CODES.M) public void requestPermission() { //记录未授权的权限 List<String> deniedPermissions = new ArrayList<>(); for (String permission : permissions) { int check = ContextCompat.checkSelfPermission(getActivity(), permission); if (check == PackageManager.PERMISSION_GRANTED) { //授权通过了已经 do nothing } else { deniedPermissions.add(permission); } } if (deniedPermissions.size() != 0) { //有权限没有通过 requestPermissions(deniedPermissions.toArray(new String[deniedPermissions.size()]), PERMISSION_REQUEST_CODE); } else { //授权全部通过 requestPermissionsSuccess(); } } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_PERMISSION_SETTING) { //设置页面回来了 requestPermission(); } } }
3, FinnPermissionListener.Class
package com.finn.tools.finnpermission; /** * Author : Finn * E-mail : 892603597@qq.com * Date : 2019/12/5 16:03 * Blog : https://www.cnblogs.com/finn21/ * Describe: * TODO : * @desc: 授权反馈事件 */ public interface FinnPermissionListener { /* * 授权全部通过 */ void permissionRequestSuccess(); /* * 授权未通过 * @param grantedPermissions 已通过的权限 * @param deniedPermissions 拒绝的权限 * @param forceDeniedPermissions 永久拒绝的权限(也就是用户点击了不再提醒的那些权限) */ void permissionRequestFail(String[] grantedPermissions, String[] deniedPermissions, String[] forceDeniedPermissions); }
4, FinnPermissionUtils.Class
package com.finn.tools.finnpermission; import android.app.Activity; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import java.util.ArrayList; import java.util.List; /** * Author : Finn * E-mail : 892603597@qq.com * Date : 2019/12/5 16:03 * Blog : https://www.cnblogs.com/finn21/ * Describe: * TODO : * @desc: 权限检查主要帮助类 */ public class FinnPermissionUtils { //宿主Activity private Activity mContext; //回调监听 private FinnPermissionListener listener; //存储所有的权限列表 private List<String> permissions = new ArrayList<>(); private FinnPermissionConfig checkConfig; private FinnPermissionUtils(Activity mContext) { this.mContext = mContext; } public static FinnPermissionUtils with(Activity context) { return new FinnPermissionUtils(context); } public FinnPermissionConfig createConfig() { checkConfig = new FinnPermissionConfig(this); return checkConfig; } /** * 添加权限 * @param permission */ public FinnPermissionUtils addPermissions(String permission) { if (!permissions.contains(permission)) permissions.add(permission); return this; } /** * 添加权限监听 * @param listener */ public FinnPermissionUtils setPermissionsCheckListener(FinnPermissionListener listener) { this.listener = listener; return this; } /** * 开始申请权限 */ public void startCheckPermission() { FinnPermissionFragment.newInstance(permissions.toArray(new String[permissions.size()]), checkConfig).setPermissionCheckListener(listener).start(mContext); } /** * 获取App的名称 * * @param context 上下文 * @return 名称 */ public static String getAppName(Context context) { PackageManager pm = context.getPackageManager(); //获取包信息 try { PackageInfo packageInfo = pm.getPackageInfo(context.getPackageName(), 0); //获取应用 信息 ApplicationInfo applicationInfo = packageInfo.applicationInfo; //获取albelRes int labelRes = applicationInfo.labelRes; //返回App的名称 return context.getResources().getString(labelRes); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } return null; } }
以上为工具类,现在我们来在Activity里面调用权限,其实很简单就是一段调用代码就行;
FinnPermissionUtils.with(MainActivity.this) //添加所有你需要申请的权限 .addPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE) .addPermissions(Manifest.permission.ACCESS_FINE_LOCATION) .addPermissions(Manifest.permission.CALL_PHONE) .addPermissions(Manifest.permission.ACCESS_WIFI_STATE) .addPermissions(Manifest.permission.CAMERA) //添加权限申请回调监听 如果申请失败 会返回已申请成功的权限列表,用户拒绝的权限列表和用户点击了不再提醒的永久拒绝的权限列表 .setPermissionsCheckListener(new FinnPermissionListener() { @Override public void permissionRequestSuccess() { //所有权限授权成功才会回调这里 Toast.makeText(MainActivity.this, "所有权限都授权成功", Toast.LENGTH_SHORT).show(); } @Override public void permissionRequestFail(String[] grantedPermissions, String[] deniedPermissions, String[] forceDeniedPermissions) { //当有权限没有被授权就会回调这里 StringBuilder result = new StringBuilder("授权结果\n授权失败\n\n"); result.append("授权通过的权限:\n"); for (String grantedPermission : grantedPermissions) { result.append(grantedPermission + "\n"); } result.append("\n临时拒绝的权限:\n"); for (String deniedPermission : deniedPermissions) { result.append(deniedPermission + "\n"); } result.append("\n永久拒绝的权限:\n"); for (String forceDeniedPermission : forceDeniedPermissions) { result.append(forceDeniedPermission + "\n"); } Toast.makeText(MainActivity.this, "授权失败", Toast.LENGTH_SHORT).show(); } }) //生成配置 .createConfig() //配置是否强制用户授权才可以使用,当设置为true的时候,如果用户拒绝授权,会一直弹出授权框让用户授权 .setForceAllPermissionsGranted(aSwitch.isChecked()) //配置当用户点击了不再提示的时候,会弹窗指引用户去设置页面授权,这个参数是弹窗里面的提示内容 .setForceDeniedPermissionTips("请前往设置->应用->【" + FinnPermissionUtils.getAppName(MainActivity.this) + "】->权限中打开相关权限!") //构建配置并生效 .buildConfig() //开始授权 .startCheckPermission();
一个成功的人,会不但的学习,不但的提升自己!一个成功的程序猿也是如此!