Android6.0仿微信權限設置
Android 6.0版本對于程序員兄弟來說最不友好的就是權限的問題,動態(tài)權限的設置曾經(jīng)讓我很苦惱,目前大部分關于6.0權限設置的框架基本都是一次性訪問多個權限(EasyPermissions),這樣導致的問題就是如果我們申請了三種權限,而用戶只同意了其中一種,下次再申請權限又是一次性申請三種,很不方便對于用戶來說很不友好,偶然情況下發(fā)現(xiàn)了安卓猴的這篇文章,
http://sunjiajia.com/2016/04/19/android-m-permissions/
在此基礎上做了修改,就實現(xiàn)了想要的那種效果(仿照微信獲取權限設置,在啟動頁每次只訪問一個權限,用戶同意則繼續(xù)訪問下一個權限,如果用戶選擇拒絕,不管用戶選擇的是“不再詢問”還是“拒絕”都視為拒絕,就彈出提示框提示該權限的必要性,指引用戶去打開權限)
下面我們以存儲空間、電話、相機權限為例,
圖片做的不太好,見諒見諒~~
添加權限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.CALL_PHONE" />
權限處理工具類
package com.fly.permissiondemo; /* * * * * * * =================================== * * * Copyright (c) 2016. * * * 作者:安卓猴 * * * 微博:@安卓猴 * * * 博客:http://sunjiajia.com * * * Github:https://github.com/opengit * * * * * * 注意**:如果您使用或者修改該代碼,請務必保留此版權信息。 * * * =================================== * * * * * */ import android.Manifest; import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.os.Build; import android.support.v4.app.ActivityCompat; import java.util.ArrayList; import java.util.List; /** * 權限控制工具類: * 為了適配API23,即Android M 在清單文件中配置use permissions后,還要在程序運行的時候進行申請。 * <p/> * ***整個權限的申請與處理的過程是這樣的: * *****1.進入主Activity,首先申請所有的權限; * *****2.用戶對權限進行授權,有2種情況: * ********1).用戶Allow了權限,則表示該權限已經(jīng)被授權,無須其它操作; * ********2).用戶Deny了權限,則下次啟動Activity會再次彈出系統(tǒng)的Permisssions申請授權對話框。 * *****3.如果用戶Deny了權限,那么下次再次進入Activity,會再次申請權限,這次的權限對話框上,會有一個選項“dont ask me again”: * ********1).如果用戶勾選了“dont ask me again”的checkbox,下次啟動時就必須自己寫Dialog或者Snackbar引導用戶到應用設置里面去手動授予權限; * ********2).如果用戶未勾選上面的選項,若選擇了Allow,則表示該權限已經(jīng)被授權,無須其它操作; * ********3).如果用戶未勾選上面的選項,若選擇了Deny,則下次啟動Activity會再次彈出系統(tǒng)的Permisssions申請授權對話框。 */ public class PermissionsUtil { // 狀態(tài)碼、標志位 public static final int REQUEST_STATUS_CODE = 0x001; public static final int REQUEST_PERMISSION_SETTING = 0x002; //常量字符串數(shù)組,將需要申請的權限寫進去,同時必須要在Androidmanifest.xml中聲明。 public static String[] PERMISSIONS_GROUP_SORT = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.CALL_PHONE, Manifest.permission.CAMERA }; private static PermissionCallbacks callbacks; public interface PermissionCallbacks { void onPermissionsGranted();//權限都有 void onPermissionsDenied(int requestCode, List<String> perms); } public static void checkAndRequestPermissions(final Activity activity, PermissionCallbacks callback) { if (Build.VERSION.SDK_INT >= 23) { callbacks = callback; // 一個list,用來存放沒有被授權的權限 ArrayList<String> denidArray = new ArrayList<>(); // 遍歷PERMISSIONS_GROUP,將沒有被授權的權限存放進denidArray for (String permission : PERMISSIONS_GROUP_SORT) { int grantCode = ActivityCompat.checkSelfPermission(activity, permission); if (grantCode == PackageManager.PERMISSION_DENIED) { denidArray.add(permission); } } // 如果該字符串數(shù)組長度大于0,說明有未被授權的權限 if (denidArray.size() > 0) { //循環(huán)處理所有未授權的權限,每次只添加一個權限進行獲取 ArrayList<String> denidArrayNew = new ArrayList<>(); denidArrayNew.add(denidArray.get(0)); // 將denidArray轉化為字符串數(shù)組,方便下面調用requestPermissions來請求授權 String[] denidPermissions = denidArrayNew.toArray(new String[denidArrayNew.size()]); requestPermissions(activity, denidPermissions); } else { //已授權 callbacks.onPermissionsGranted(); } } } /** * 關于shouldShowRequestPermissionRationale函數(shù)的一點兒注意事項: * ***1).應用安裝后第一次訪問,則直接返回false; * ***2).第一次請求權限時,用戶Deny了,再次調用shouldShowRequestPermissionRationale(),則返回true; * ***3).第二次請求權限時,用戶Deny了,并選擇了“dont ask me again”的選項時,再次調用shouldShowRequestPermissionRationale()時,返回false; * ***4).設備的系統(tǒng)設置中,禁止了應用獲取這個權限的授權,則調用shouldShowRequestPermissionRationale(),返回false。 */ public static boolean showRationaleUI(Activity activity, String permission) { return ActivityCompat.shouldShowRequestPermissionRationale(activity, permission); } /** * 對權限字符串數(shù)組中的所有權限進行申請授權,如果用戶選擇了“dont ask me again”,則不會彈出系統(tǒng)的Permission申請授權對話框 */ public static void requestPermissions(Activity activity, String[] permissions) { ActivityCompat.requestPermissions(activity, permissions, REQUEST_STATUS_CODE); } /** * 用來判斷,App是否是首次啟動: * ***由于每次調用shouldShowRequestPermissionRationale得到的結果因情況而變,因此必須判斷一下App是否首次啟動,才能控制好出現(xiàn)Dialog和SnackBar的時機 */ public static boolean isAppFirstRun(Activity activity) { SharedPreferences sp = activity.getSharedPreferences("config", Context.MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); if (sp.getBoolean("first_run", true)) { editor.putBoolean("first_run", false); editor.commit(); return true; } else { editor.putBoolean("first_run", false); editor.commit(); return false; } } }
使用方法:
在啟動頁AppStart跳轉首頁的時候,調用
PermissionsUtil.checkAndRequestPermissions(AppStart.this, new PermissionsUtil.PermissionCallbacks() { @Override public void onPermissionsGranted() { //所有權限都已經(jīng)獲取到跳轉 toMainActivity(); } @Override public void onPermissionsDenied(int requestCode, List<String> perms) { } });
這個是在AppStart中的回調,現(xiàn)在的處理辦法是,根據(jù)每一次提出的權限申請的回調結果來處理對應權限,并且是每一次處理完都會遍歷一次
“PERMISSIONS_GROUP_SORT”,循環(huán)處理所有的權限,直到每個權限都獲取到,在“onPermissionsGranted()”中進行跳轉。這樣處理就可以在下次啟動時直接詢問沒有獲得的權限。
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == PermissionsUtil.REQUEST_STATUS_CODE) { if (permissions[0].equals(Manifest.permission.READ_EXTERNAL_STORAGE)) {//讀寫權限 if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {//同意 PermissionsUtil.checkAndRequestPermissions(this, new PermissionsUtil.PermissionCallbacks() { @Override public void onPermissionsGranted() { toMainActivity(); } @Override public void onPermissionsDenied(int requestCode, List<String> perms) { } });//請求 } else {//不同意-提示信息 createLoadedAlertDialog("在設置-應用-"+ getString(R.string.app_name) +"-權限中開啟存儲空間權限,以正常使用App功能"); } } if (permissions[0].equals(Manifest.permission.CALL_PHONE)) {//電話權限 if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {//同意 PermissionsUtil.checkAndRequestPermissions(this, new PermissionsUtil.PermissionCallbacks() { @Override public void onPermissionsGranted() { toMainActivity(); } @Override public void onPermissionsDenied(int requestCode, List<String> perms) { } }); } else {//不同意-提示信息 createLoadedAlertDialog("在設置-應用-" + getString(R.string.app_name) + "-權限中開啟電話權限,以正常使用App功能"); } } if (permissions[0].equals(Manifest.permission.CAMERA)) {//電話權限 if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {//同意 //所有權限均獲取 toMainActivity(); } else {//不同意-提示信息 createLoadedAlertDialog("在設置-應用-"+ getString(R.string.app_name) +"-權限中開啟照相機權限,以正常使用App功能"); } } } }
在設置的權限組里邊有幾個權限就需要在這個回調中寫幾個判斷來處理對應的友好提示信息,單對單處理,這種方式避免了跟用戶不斷扯犢子,簡單粗暴提示用戶獲取權限,一旦用戶不從,直接跳設置,負責就退出應用。
下面是git地址 https://git.oschina.net/feiyangwei/PermissionDemo.git
這個方案目前還需要完善,如果用戶在打開應用的情況下,去設置里邊修改權限,我不清楚怎么監(jiān)聽這塊權限的修改,微信是直接重新打開應用,這樣就會重新獲取權限,如果有知道的大神可以討論一下 。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Android SwipeRefreshLayout下拉刷新組件示例
SwipeRefrshLayout是Google官方更新的一個Widget,可以實現(xiàn)下拉刷新的效果。本文主要介紹了Android之SwipeRefreshLayout下拉刷新組件示例,有興趣的可以了解一下。2017-02-02Android入門之Gallery+ImageSwitcher用法實例解析
這篇文章主要介紹了Android入門之Gallery+ImageSwitcher用法,對Android初學者有很好的參考借鑒價值,需要的朋友可以參考下2014-08-08Android 實現(xiàn)夜間模式的快速簡單方法實例詳解
這篇文章主要介紹了Android 實現(xiàn)夜間模式的快速簡單方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-09-09開源自研內(nèi)存分析利器Android?Bitmap?Monitor圖片定位詳解
這篇文章主要為大家介紹了Android?Bitmap?Monitor開源自研內(nèi)存分析利器,助你定位不合理的圖片使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-03-03android startActivityForResult的使用方法介紹
android startActivityForResult的使用方法介紹,需要的朋友可以參考一下2013-05-05Android中利用matrix 控制圖片的旋轉、縮放、移動
本篇文章是對Android中利用matrix 控制圖片的旋轉、縮放、移動進行了詳細的分析介紹,需要的朋友參考下2013-06-06