Android PermissionUtils:运行时权限工具类及申请权限的正确姿势

Android PermissionUtils:运行时权限工具类及申请权限的正确姿势

96 
ifadai 
2017.06.16 16:22* 字数 318 阅读 3637评论 1

PermissionUtil

经常写Android运行时权限申请代码,每次都是复制过来之后,改一下权限字符串就用,把代码搞得乱糟糟的,于是便有了封装工具类的想法,话不多说,先看怎么用:

工具类及Demo:github

简洁版申请权限

申请一个权限:

    PermissionUtils.checkAndRequestPermission(mContext, PERMISSION_CAMERA, REQUEST_CODE_CAMERA,new PermissionUtils.PermissionRequestSuccessCallBack() {@Overridepublic void onHasPermission() { // 权限已被授予 toCamera(); } }); 

然后在onRequestPermissionsResult中:

if(PermissionUtils.isPermissionRequestSuccess(grantResults)){// 权限申请成功toCamera();}

什么?要同时申请多个权限?

    PermissionUtils.checkAndRequestMorePermissions(mContext, PERMISSIONS, REQUEST_CODE_PERMISSIONS,new PermissionUtils.PermissionRequestSuccessCallBack() {@Overridepublic void onHasPermission() { // 权限已被授予 toCamera(); } }); 

当然上面这些都不是申请权限的正确姿势,理想的姿势应该是:

  • 第一次申请权限:按照正常流程走;
  • 如果用户第一次拒绝了权限申请,第二次申请时应向用户解释权限用途;
  • 如果用户勾选了“不再询问”选项,应引导用户去设置页手动开启权限。

如图:

第一次申请权限
第二次申请权限并禁止询问

于是,引申出了复杂版的权限申请方法:

自定义权限申请:

PermissionUtils.checkPermission(mContext, PERMISSION_CAMERA,new PermissionUtils.PermissionCheckCallBack() {@Overridepublic void onHasPermission() { // 已授予权限 toCamera(); } @Override public void onUserHasAlreadyTurnedDown(String... permission) { // 上一次申请权限被拒绝,可用于向用户说明权限原因,然后调用权限申请方法。 } @Override public void onUserHasAlreadyTurnedDownAndDontAsk(String... permission) { // 第一次申请权限或被禁止申请权限,建议直接调用申请权限方法。 } }); 

然后在onRequestPermissionsResult中:

PermissionUtils.onRequestPermissionResult(mContext, PERMISSION_CAMERA, grantResults, new PermissionUtils.PermissionCheckCallBack() {@Overridepublic void onHasPermission() { toCamera(); } @Override public void onUserHasAlreadyTurnedDown(String... permission) { Toast.makeText(mContext, "我们需要"+Arrays.toString(permission)+"权限", Toast.LENGTH_SHORT).show(); } @Override public void onUserHasAlreadyTurnedDownAndDontAsk(String... permission) { Toast.makeText(mContext, "我们需要"+Arrays.toString(permission)+"权限", Toast.LENGTH_SHORT).show(); // 显示前往设置页的dialog showToAppSettingDialog(); } }); 

基本使用就是这些了,包括前往应用设置页的方法,也在工具类里面,具体使用可以看demo。

工具类及Demo:github

贴一下工具类代码:

package com.fadai.library;import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import java.util.ArrayList; import java.util.List; /** * <pre> * author : FaDai * e-mail : i_fadai@163.com * time : 2017/06/13 * desc : xxxx描述 * version: 1.0 * </pre> */ public class PermissionUtils { /** * 检测权限 * * @return true:已授权; false:未授权; */ public static boolean checkPermission(Context context, String permission) { if (ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED) return true; else return false; } /** * 检测多个权限 * * @return 未授权的权限 */ public static List<String> checkMorePermissions(Context context, String[] permissions) { List<String> permissionList = new ArrayList<>(); for (int i = 0; i < permissions.length; i++) { if (!checkPermission(context, permissions[i])) permissionList.add(permissions[i]); } return permissionList; } /** * 请求权限 */ public static void requestPermission(Context context, String permission, int requestCode) { ActivityCompat.requestPermissions((Activity) context, new String[]{permission}, requestCode); } /** * 请求多个权限 */ public static void requestMorePermissions(Context context, List permissionList, int requestCode) { String[] permissions = (String[]) permissionList.toArray(new String[permissionList.size()]); requestMorePermissions(context, permissions, requestCode); } /** * 请求多个权限 */ public static void requestMorePermissions(Context context, String[] permissions, int requestCode) { ActivityCompat.requestPermissions((Activity) context, permissions, requestCode); } /** * 判断是否已拒绝过权限 * * @return * @describe :如果应用之前请求过此权限但用户拒绝,此方法将返回 true; * -----------如果应用第一次请求权限或 用户在过去拒绝了权限请求, * -----------并在权限请求系统对话框中选择了 Don't ask again 选项,此方法将返回 false。 */ public static boolean judgePermission(Context context, String permission) { if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, permission)) return true; else return false; } /** * 检测权限并请求权限:如果没有权限,则请求权限 */ public static void checkAndRequestPermission(Context context, String permission, int requestCode) { if (!checkPermission(context, permission)) { requestPermission(context, permission, requestCode); } } /** * 检测并请求多个权限 */ public static void checkAndRequestMorePermissions(Context context, String[] permissions, int requestCode) { List<String> permissionList = checkMorePermissions(context, permissions); requestMorePermissions(context, permissionList, requestCode); } /** * 检测权限 * * @describe:具体实现由回调接口决定 */ public static void checkPermission(Context context, String permission, PermissionCheckCallBack callBack) { if (checkPermission(context, permission)) { // 用户已授予权限 callBack.onHasPermission(); } else { if (judgePermission(context, permission)) // 用户之前已拒绝过权限申请 callBack.onUserHasAlreadyTurnedDown(permission); else // 用户之前已拒绝并勾选了不在询问、用户第一次申请权限。 callBack.onUserHasAlreadyTurnedDownAndDontAsk(permission); } } /** * 检测多个权限 * * @describe:具体实现由回调接口决定 */ public static void checkMorePermissions(Context context, String[] permissions, PermissionCheckCallBack callBack) { List<String> permissionList = checkMorePermissions(context, permissions); if (permissionList.size() == 0) { // 用户已授予权限 callBack.onHasPermission(); } else { boolean isFirst = true; for (int i = 0; i < permissionList.size(); i++) { String permission = permissionList.get(i); if (judgePermission(context, permission)) { isFirst = false; break; } } String[] unauthorizedMorePermissions = (String[]) permissionList.toArray(new String[permissionList.size()]); if (isFirst)// 用户之前已拒绝过权限申请 callBack.onUserHasAlreadyTurnedDownAndDontAsk(unauthorizedMorePermissions); else // 用户之前已拒绝并勾选了不在询问、用户第一次申请权限。 callBack.onUserHasAlreadyTurnedDown(unauthorizedMorePermissions); } } /** * 检测并申请权限 */ public static void checkAndRequestPermission(Context context, String permission, int requestCode, PermissionRequestSuccessCallBack callBack) { if (checkPermission(context, permission)) {// 用户已授予权限 callBack.onHasPermission(); } else { requestPermission(context, permission, requestCode); } } /** * 检测并申请多个权限 */ public static void checkAndRequestMorePermissions(Context context, String[] permissions, int requestCode, PermissionRequestSuccessCallBack callBack) { List<String> permissionList = checkMorePermissions(context, permissions); if (permissionList.size() == 0) { // 用户已授予权限 callBack.onHasPermission(); } else { requestMorePermissions(context, permissionList, requestCode); } } /** * 判断权限是否申请成功 */ public static boolean isPermissionRequestSuccess(int[] grantResults) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) return true; else return false; } /** * 用户申请权限返回 */ public static void onRequestPermissionResult(Context context, String permission, int[] grantResults, PermissionCheckCallBack callback) { if (PermissionUtils.isPermissionRequestSuccess(grantResults)) { callback.onHasPermission(); } else { if (PermissionUtils.judgePermission(context, permission)) { callback.onUserHasAlreadyTurnedDown(permission); } else { callback.onUserHasAlreadyTurnedDownAndDontAsk(permission); } } } /** * 用户申请多个权限返回 */ public static void onRequestMorePermissionsResult(Context context, String[] permissions, PermissionCheckCallBack callback) { boolean isBannedPermission = false; List<String> permissionList = checkMorePermissions(context, permissions); if (permissionList.size() == 0) callback.onHasPermission(); else { for (int i = 0; i < permissionList.size(); i++) { if (!judgePermission(context, permissionList.get(i))) { isBannedPermission = true; break; } } // 已禁止再次询问权限 if (isBannedPermission) callback.onUserHasAlreadyTurnedDownAndDontAsk(permissions); else // 拒绝权限 callback.onUserHasAlreadyTurnedDown(permissions); } } /** * 跳转到权限设置界面 */ public static void toAppSetting(Context context) { Intent intent = new Intent(); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if (Build.VERSION.SDK_INT >= 9) { intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS"); intent.setData(Uri.fromParts("package", context.getPackageName(), null)); } else if (Build.VERSION.SDK_INT <= 8) { intent.setAction(Intent.ACTION_VIEW); intent.setClassName("com.android.settings", "com.android.settings.InstalledAppDetails"); intent.putExtra("com.android.settings.ApplicationPkgName", context.getPackageName()); } context.startActivity(intent); } public interface PermissionRequestSuccessCallBack { /** * 用户已授予权限 */ void onHasPermission(); } public interface PermissionCheckCallBack { /** * 用户已授予权限 */ void onHasPermission(); /** * 用户已拒绝过权限 * * @param permission:被拒绝的权限 */ void onUserHasAlreadyTurnedDown(String... permission); /** * 用户已拒绝过并且已勾选不再询问选项、用户第一次申请权限; * * @param permission:被拒绝的权限 */ void onUserHasAlreadyTurnedDownAndDontAsk(String... permission); } } 

工具类及Demo:github

转载于:https://www.cnblogs.com/Im-Victor/p/9644568.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/277286.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux基础监控小工具nmon

nmon是一种在AIX与各种Linux操作系统上广泛使用的监控与分析工具&#xff0c; nmon所记录的信息是比较全面的&#xff0c;它能在系统运行过程中实时地捕捉系统资源的使用情况&#xff0c;并且能输出结果到文件中。nmon工具可以帮助在一个屏幕上显示所有重要的性能优化信息&…

vue的配置环境篇

1.电脑已经安装的nodejs和webpack。 2.1&#xff09;打开cmd。winr。可以直接输入node -v查看版本。安装淘宝镜像 npm install -g cnpm --registryhttp://registry.npm.taobao.org &#xff0c;安装成功可以查看下&#xff0c;cnpm -v 3.安装vue脚手架&#xff0c;输入命令&am…

Agilent RF fundamentals (4)- Impedance match and distortions

1 Impedance match&#xff1a; 2 distortions&#xff1a; Solar radiation produces background noise 转载于:https://www.cnblogs.com/huangbaobaoi/p/9650937.html

android论坛功能开发教程,Android教程 如何免费生成论坛App

介绍按照快速集成文档&#xff0c;您可以很容易的把BBSSDK提供的功能集成到您的应用中&#xff0c;然后使用BBSSDK来做开发。在集成前&#xff0c;您也可以先下载示例Sample的源码工程(包含应用内打开pdfoffice等格式文件)。使用Android Studio打开后&#xff0c;编译出网站上提…

自动化测试===adb 解锁手机的思路

在adb里有模拟按键/输入的命令 比如使用 adb shell input keyevent <keycode> 命令&#xff0c;不同的 keycode 能实现不同的功能&#xff0c;完整的 keycode 列表详见 KeyEvent&#xff0c;摘引部分我觉得有意思的如下&#xff1a; keycode含义3HOME 键4返回键5打开拨号…

android 编译器有问题,Android Studio 3.0 Beta 2发布:解决编译器bug

5月18日&#xff0c;IT之家曾经报道&#xff0c;谷歌发布了Android Studio 3.0的测试版&#xff0c;新增了对Kotlin语言的支持&#xff0c;而日前&#xff0c;谷歌发布了Android Studio 3.0的Beta 2版本。此版本并无新功能加入&#xff0c;不过修复了一个困扰开发人员的bug&…

Kali安装magescan评估工具

Magento &#xff08;麦进斗&#xff09; 是一套专业开源的电子商务系统。Magento设计得非常灵活&#xff0c;具有模块化架构体系和丰富的功能。易于与第三方应用系统无缝集成。其面向企业级应用&#xff0c;可处理各方面的需求&#xff0c;以及建设一个多种用途和适用面的电子…

领域驱动设计在马蜂窝优惠中心重构中的实践

前言 正如领域驱动设计之父 Eric Evans 所著一书的书名所述&#xff0c;领域驱动设计&#xff08;Domain Driven Design&#xff09;是一种软件核心复杂性应对之道。 在我们解决现实业务问题时&#xff0c;会面对非常复杂的业务逻辑。即使是同一个事物&#xff0c;在多个子业务…

鸿蒙系统发布会是什么时候,鸿蒙系统2.0发布时间是什么时候?或将与EMUI11一同发布!...

对于鸿蒙系统OS一直以来就备受大家的关注&#xff0c;作为华为自主研发的操作系统&#xff0c;它是华为之光&#xff01;很多人翘首盼望着它的到来&#xff0c;自1.0版本后鸿蒙系统2.0发布时间似乎确定下来了&#xff01;届时会与EMUI11一同向大家介绍&#xff01;今日&#xf…

HZNU 2019 Summer training 8

A - Petya and Origami CodeForces - 1080A 题意&#xff1a;制造一份邀请函需要2份a物品&#xff0c;5份b物品&#xff0c;8份c物品&#xff0c;一个盒子里面有k份物品&#xff08;可以为a或b或c&#xff09;问你制造n份邀请函需要用多少个盒子 题解&#xff1a;加起来就行了…

android layer-list,Android layer-list的属性和使用具体解释

Android layer-list的属性和使用具体解释。layer-list是用来多个图层堆叠显示的&#xff0c;借这个特性能够做一些特别的效果(比方&#xff1a;阴影、以下的效果等)&#xff0c;也能够投机取巧。1.代码片2.布局代码和效果图 (一定要注意在使用RadioGroup的时候要记的写RadioBut…

数据库字段属性配置工具界面[用于代码生成]

在CodeSmith中为了实现对数据库中表字段的选择和针对字段来设置属性&#xff0c;决定用XML文件作为中间数据的交换方式&#xff0c;在CodeSmith中读取数据库对象的信息不再使用SchemaExplorer来读取&#xff0c;而是转为直接对XML文件的读取。<?xml:namespace prefix o ns…

Zookeeper环境安装

源码包下载&#xff1a; http://archive.apache.org/dist/zookeeper/zookeeper-3.4.10 集群环境&#xff1a; master 192.168.1.99 slave1 192.168.1.100 slave2 192.168.1.101 下载安装包&#xff1a; # Mater wget http://archive.apache.org/dist/zookeeper/zookeeper-3.4.1…

鸿蒙系统用没有安卓的代码,套壳?不存在!纯鸿蒙系统不含任何安卓代码,其他手机厂商可使用...

众所周知&#xff0c;华为的鸿蒙系统已经应用于许多华为机型上&#xff0c;例如Mate40、MataX2等&#xff0c;同时不少家电厂商也和华为合作推出了基于鸿蒙的终端设备&#xff0c;比如美的、老板等。那么&#xff0c;和华为处于竞争关系的手机厂商可以使用鸿蒙系统吗&#xff1…

出来乍到

第一篇&#xff0c;还没想到写什么东西&#xff0c;比空的好&#xff0c;先这么挂一下把。转载于:https://www.cnblogs.com/Carlwave/archive/2006/01/24/322413.html

Java消息队列总结只需一篇解决ActiveMQ、RabbitMQ、ZeroMQ、Kafka

一、消息队列概述 消息队列中间件是分布式系统中重要的组件&#xff0c;主要解决应用解耦&#xff0c;异步消息&#xff0c;流量削锋等问题&#xff0c;实现高性能&#xff0c;高可用&#xff0c;可伸缩和最终一致性架构。目前使用较多的消息队列有ActiveMQ&#xff0c;RabbitM…

android 小黄车首页,android采用MVP漫画APP、适配刘海屏、小黄车主界面、录音波浪动画、综合APP等源码...

Android精选源码Android优质博客为什么组件化 随着移动互联网的发展&#xff0c;或许中小型项目还可以用单工程MVC/MVP/MVVM的架构来完成&#xff0c;但当项目到了一定程度之后&#xff0c;编译时间 原来越长&#xff0c;测试或者开发任何一个模块功能都需要整个项目重启运行。…

修改SQL server数据库中的逻辑文件名

使用 FILE_NAME 函数可以返回给定文件标识 (ID) 号的逻辑文件名如下 下例返回 file_ID 为 1 的文件名&#xff08;master 数据库文件&#xff09;。 1USEmaster2SELECTFILE_NAME(1)当我们进行从一个备份中还原数据库时&#xff0c;数据库的逻辑文件名是不会改变的。 可用 ALTER…

java根据模板生成PDF

首先你的制作一个pdf模板&#xff1a; 1.先用word做出模板界面 画单元格的时候需要考虑值的长度&#xff0c;像这里的状态可能会很长 2.文件另存为pdf格式文件 使用福昕PDF 打开&#xff0c;添加文本&#xff0c;以及需要添加值的地方&#xff0c;设置文本域&#xff0c;这个就…

android bilibili搜索框,仿bilibili搜索框效果(三句代码实现)

SearchDialog仿bilibili搜索框效果(只需要三句话即可实现)先看预览图(转换后有一点点失真):前言1,支持搜索历史(已经做了数据库存储了)2,基本与bilibili的搜索效果差不多了3,需要修改更多内容可以下载library自己修改4,本人非大牛,有不妥之处请Issues指出,谢谢5,参考了该po的文…