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. 华为云CodeArts Artifact,5大特性守护制品质量与安全

    摘要:2023年2月23日,华为云CodeArts Artifact制品仓库服务正式上线,目标进一步赋能企业伙伴与开发者,实现软件作业中可信制品生产与应用活动快速落地,提高软件交付效率与质量. 本文分 ...

  2. Idea External Libraries 没有导入依赖

    Maven 下面是有依赖的,但是 Idea 的 External Libraries 没有导入进来,就非常奇怪,这个现象我在 Android Studio 也遇到过,要么找到 Maven 仓库,手动把 ...

  3. 基于Vue3的Leaflet基础

    1. 概述 Leaflet 是一个开源.轻量并且对移动端友好的交互式地图 JavaScript 库,大小仅仅只有 39 KB, 拥有绝大部分开发者所需要的所有地图特性 Leaflet 的官网为:Lea ...

  4. postman 使用简单汇总

    postman官网下载地址:https://www.postman.com/downloads/ Postman支持功能 1.快速构建 2.参数化与变量设置提取 3.查看请求数据 4.提供断言功能 5 ...

  5. Deer_GF之图片

    Hi,今天介绍一下Deer_Gf里的图片组件.       框架介绍请移步[Deer_GF之框架介绍]       接下来为大家介绍一下框架里用到的图片组件及加载流程. 目录 大图(Texture)存 ...

  6. python + pyqt 实现的你下载css背景图片的小工具(最终版)

    学习python有三个星期了,算是做的第一个小工具,其实也没必要做成图形界面,只是为的GUI学习(再说技术总归给人使用的,熟练很多shell命令只是个"匠人".) win8下面: ...

  7. oracle 2个数组列,剔除数组重复的数据。

    一.下面这样不规则的,数据如何剔除掉.循环筛选replace替换掉. 序号 正常时间 剔除时间 1    2022-12-19,2022-12-20,2022-12-21,2022-12-22,202 ...

  8. vue学习 第二天 CSS基础

    CSS: 层叠样式表  ( Cascading Style Sheets ) 的简称 1.css简介 1)也是一种标记语言 2)主要用来设置html页面中,标签的样式. 3)css美化了html页面, ...

  9. xampp安装使用

    xampp安装使用 安装 下载xampp bin文件 xampp-linux-x64-8.0.0-3-installer.run 安装 sudo ./xampp-linux-x64-8.0.0-3-i ...

  10. 电商项目maven框架搭建引入dubbo配置文件报错

    解决:dubbo配置文件报红叉的问题 构建dobbo-provider配置文件时,报红叉错误,本质即找不到对应的dubbo.xsd文件. 1.下载模板 模板下载地址:http://download.c ...