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.pswp.cn/news/277286.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/277286.shtml
英文地址,請注明出處:http://en.pswp.cn/news/277286.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

實現帶下拉菜單的工具欄按鈕

在工具欄中使用真彩色圖標 實現帶下拉菜單的工具欄按鈕 20050916轉載于:https://www.cnblogs.com/henryzc/archive/2005/11/08/271346.html

文件目錄管理與顯示c語言,Centos 7 文件和目錄管理

查看權限在終端輸入:ls -l xxx.xxx (xxx.xxx是文件名)那么就會出現相類似的信息&#xff0c;主要都是這些&#xff1a;-rw-rw-r--其中&#xff1a; 最前面那個 - 代表的是類型中間那三個 rw- 代表的是所有者(user)然后那三個 rw- 代表的是組群(group)最后那三個 r-- 代表的是…

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…

最近比較毀硬件

上上周末公司機器主板南橋在一股青煙中壯烈犧牲……前天家里機器的GF4 Ti4600也半死不活了&#xff0c;不能裝驅動&#xff0c;只能用640x480 16色裝了驅動系統就無法啟動&#xff0c;靠靠的從肥巖那弄了塊GF FX5600XT 機器算是能亮了郁悶阿轉載于:https://www.cnblogs.com/sko…

行列式運算算法c語言,新手作品:行列式計算C語言版

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓對話 ControlHeightDecrease ShiftUp Arrow 向上調整選定的控件或對話一個對話單位對話 ControlHeightIncrease ShiftDown Arrow 向下調整選定的控件或對話一個對話單位對話 ControlMoveDown Dow…

CentOSLinux安裝Docker容器

Docker 使用 環境說明 CentOS 7.3&#xff08;不準確地說&#xff1a;要求必須是 CentOS 7 64位&#xff09;不建議在 Windows 上使用Docker 基本概念 官網&#xff1a;https://www.docker.com/宿主機&#xff1a;安裝 Docker 的那臺電腦Docker&#xff1a;一個虛擬化軟件&…

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

怎樣才能娶到比爾-蓋茨的女兒

怎樣才能娶到比爾-蓋茨的女兒 一位優秀的商人杰克&#xff0c;有一天告訴他的兒子杰克&#xff1a;我已經決定好了一個女孩子&#xff0c;我要你娶她兒子&#xff1a;我自己要娶的新娘我自己會決定杰克&#xff1a;但我說的這女孩可是比爾蓋茨的女兒喔兒子&#xff1a;哇&…

Android動態賦權限,安卓6.0以上動態添加權限超簡單模板

今天又是“咔嚓”、“窟窿”、“轟隆”&#xff0c;不曉得哪位大仙在渡劫。真的是風生水起&#xff0c;虎虎生威&#xff01;&#xff01;&#xff01;言歸正傳&#xff1a;描述&#xff1a;最近做了從服務器下載apk到手機內存&#xff0c;然后安裝打開以及 從服務器下載pdf文件…

web前端常用代碼于面試等資源

https://www.cnblogs.com/moqiutao/p/4766146.html轉載于:https://www.cnblogs.com/as3lib/p/9654925.html

html 跳轉到本頁面指定位置

1 <html xmlns"http://www.w3.org/1999/xhtml"> 2 <head> 3 </head> 4 <body> 5 <a href"#ct1">跳轉到詞條1</a> 6 7   <a href"#ct2">跳轉到詞條2</a> 8   <br> 9   <di…

事情太多了,我實在支持不住了轉載于:https://www.cnblogs.com/zjblue/archive/2005/12/03/290186.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打開撥號…

linux 去掉 ^M 的方法

在linux上經常遇到這種問題&#xff0c;從網上下載文件到 linux 上后&#xff0c;就多了很多 ^M這種東西&#xff0c;如何集體刪除這種東西呢&#xff01; 用 vim 打開文件 進行如下設置 將文件格式轉化為unix :set ffunix :x 轉載于:https://www.cnblogs.com/0820LL/p/11174…

What's NEW in C++/CLI Language

作為同時適用于本地/托管環境的新一代C語言擴充&#xff0c;C/CLI的定位與原有的Managed Extensions for C基本一致&#xff0c;在CLR 2.0環境中&#xff0c;它主要承載了如下5個使命&#xff1a; A. 源碼級集成 (本地/托管/混合代碼編譯) B. 對象模型集成 (本地類型/指針、…

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;在多個子業務…