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. Centos7-RAID冗余磁盘阵列

    转载csdn: Centos7-RAID冗余磁盘阵列_黏住你不让你的博客-CSDN博客

  2. aspnetcore读取配置【源码分析】

    总的逻辑 继承 IConfigurationSource 这个接口的子类是配置源 ,其中的build方法,创建并返回对应的ConfigurationProvider. 继承 IConfiguratio ...

  3. 组织炎症水平高的RA患者接受TNF拮抗剂治疗的效果更好

    组织炎症水平高的RA患者接受TNF拮抗剂治疗的效果更好van der Pouw Kraan TC, et al. Ann Rheum Dis. 2008;67(4):563-6.目的:不同患者对TNF ...

  4. 【Linux SPI】RFID RC522 设备驱动

    一.概述 MFRC522 支持 SPI.I2C.UART 接口,我在某宝上购买了一个 SPI 接口的 RC522 模块.此笔记主要要是通过 RC522 模块学习 linux 中的 SPI 驱动,方便今 ...

  5. rotate matrix

  6. 富士胶片2105N打印机安装说明

    打开驱动文件,执行软件 自定义安装驱动 手动输入IP地址 下一步安装完成 自定义安装扫描软件 选择print & scan 下一步安装完成

  7. Linux驱动、应用调试技巧

    原文地址:https://hceng.cn/2019/04/08/Linux%E9%A9%B1%E5%8A%A8%E3%80%81%E5%BA%94%E7%94%A8%E8%B0%83%E8%AF%9 ...

  8. vscode的python开发环境搭建,环境变量支持终端命令行(执行当前

    vscode的python开发环境设置 安装vscode,这里不介绍了 安装插件 在${workspaceFolder}的目录下,新建.vscode文件夹(或者修改一下配置,也可以自动生成该文件夹) ...

  9. gitlab中CI/CD过程中的坑

    先上观点,azure的pipeline比gitlab ce版好用,gitlab收费版没有用过. 在.gitlab-ci.yml中的特殊字符处理: 解决方法: cmd="[$var1] &am ...

  10. Python爬取亚马逊商品页面

    仍然利用Requests库来实现 1 import requests 2 r=requests.get('https://www.amazon.cn/gp/product/B01M8L5Z3Y') 3 ...