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();

Android 6.0动态添加权限(Finn_ZengYuan博客)的更多相关文章

  1. Android 6.0动态添加权限

    Android 6.0加入了动态权限,权限有普通权限和危险权限两种,其中危险权限在6.0以上的手机是需要动态添加权限的,举例:拨打10086//-----------------布局文件------- ...

  2. Android 6.0 - 动态权限管理的解决方案(转)

    转自:http://www.cnblogs.com/dubo-/p/6018262.html Android 6.0 - 动态权限管理的解决方案   转载请标注 Android 6.0版本(Api 2 ...

  3. android 6.0 动态权限

    Android 6.0 动态权限: 除了要在AndroidManifest.xml中申请外,还需使用时,请求用户允许授权. 以下是需要单独申请的权限,共分为9组,每组只要有一个权限申请成功了,就默认整 ...

  4. Android 6.0动态权限申请

    转载(Android 6.0 动态权限申请简单简洁优雅的处理方式): https://blog.csdn.net/lin_dianwei/article/details/79025324

  5. Android权限管理之Android 6.0运行时权限及解决办法

    前言: 今天还是围绕着最近面试的一个热门话题Android 6.0权限适配来总结学习,其实Android 6.0权限适配我们公司是在今年5月份才开始做,算是比较晚的吧,不过现在Android 6.0以 ...

  6. 【Java EE 学习 75 下】【数据采集系统第七天】【二进制运算实现权限管理】【使用反射初始化权限表】【权限捕获拦截器动态添加权限】

    一.使用反射动态添加权限 在该系统中,我使用struts2的时候非常规范,访问的Action的形式都是"ActionClassName_MethodName.action?参数列表" ...

  7. Android 6.0 如何添加完整的系统服务(app-framework-kernel)

    最近学习了如何在Android 6.0上添加一个系统服务,APP如何通过新增的系统服务访问底层驱动.在这学习过程中,收获颇多,并结合学习了<Embeded Android>--Karim ...

  8. 我的Android进阶之旅------>经典的大牛博客推荐(排名不分先后)!!

    本文来自:http://blog.csdn.net/ouyang_peng/article/details/11358405 今天看到一篇文章,收藏了很多大牛的博客,在这里分享一下 谦虚的天下 柳志超 ...

  9. [置顶] cocos2d-x 3.0游戏开发xcode5帅印博客教学 004.[HoldTail]主角的上下飞行跟移动

    cocos2d-x 3.0游戏开发xcode5帅印博客教学 004.[HoldTail]主角的上下飞行跟移动 写给大家的前言,在学习cocos2d-x的时候自己走了很多的弯路,也遇到了很多很多问题,不 ...

  10. WPF 用代码调用dynamic resource动态更改背景 - CSDN博客

    原文:WPF 用代码调用dynamic resource动态更改背景 - CSDN博客 一般dynamic resoource通常在XAML里调用,如下范例: <Button Click=&qu ...

随机推荐

  1. Nacos服务调用(基于Openfeign)

    在<<Nacos服务注册>>这篇文章里,我搭建了一个nacos服务中心,并且注册了一个服务,下面我们来看在上一篇文章的基础上,怎样用Openfeign来调用这个服务. 0.同上 ...

  2. T-SQL——将字符串转为单列

    目录 0. 背景 1. 使用STRING_SPLIT函数 2. 自定义分裂函数 3. 使用示例 shanzm-2023年2月22日 0. 背景 代码中执行存储过程,参数是多个且不确定数量,期望SQL查 ...

  3. .net mvc 权限验证 Filter(过滤器)

    一.知识了解 Asp.Net MVC提供了以下几种默认的Filter: 大家注意一点,Asp.Net MVC提供的ActionFilterAttribute默认实现了IActionFilter和IRe ...

  4. vue-element-admin 怎么改后端 可以调跳过登录并且发送接口请求

    1.找到根目录的 vue.config.js 添加 proxy 内容 注释掉mock 2.清空 .env.development 里的 VUE_APP_BASE_API  路径 3.user.js 方 ...

  5. mac sourceTree 每次操作提示需要密码

    1.在终端(terminal)打开你的工程目录2.输入git config credential.helper store 3.拉取代码git pull

  6. ASP动态网页(网站)设计教程

    ASP动态网页(网站)设计教程 文件名 大小 ASP获取时间函数大全 35KB 项目6 ASP数据表数据操作功能设计.pptx 3.34 MB 项目5 WEB数据库与数据库管理.pptx 3.34 M ...

  7. js 获取和回填form表格数据

    //将form里面的内容序列化成json数据 $.fn.serializeJson = function (otherString) { var serializeObj = {}, array = ...

  8. k8s-分布式系统架构master-worker

    K8S系列一:概念入门 - 知乎 (zhihu.com) 大白话先了解k8s. k8s是为容器服务而生的一个可移植容器的编排管理工具 概述 Master-Workers 架构(粗译为主从架构)是分布式 ...

  9. vue2中请求函数防抖处理

  10. C++标准库string学习笔记

    string概述 作为c++语言用作字符串处理的标准库,和Python字符串类型有较多相似之处.可以使用'='进行赋值,"=="来比较,"+"进行拼接. 构造函 ...