前言
android開發權限授權因為版本的不同有不同的授權方式,6.0以下的版本使用的是在注冊表中添加權限的靜態授權(這種授權權限提示只會出現在app安裝的時候),而6.0以上(包含6.0)就需要動態授權的方式。
實現思維:
1.就算是動態授權依然需要在AndroidManifest.xml里添加靜態權限。
2.動態權限的數組寫法與KEY。
3.判斷系統版本。
4.判斷權限是否獲取
5.授權完成后的回調方法執行
講解部分
1.在AndroidManifest.xml里添加靜態權限。
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.lenovo.mydemoapp"> <!--此處添加靜態權限--> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.CAMERA"/> <application android:name=".myAppCompatActivity.MyApplication" android:allowBackup="true" 以下略....
2.動態權限的數組寫法與KEY。
//因為本人是寫一個頭像設置的功能,所以需要在進入相機拍照或者相冊選擇圖像中做區分。所以寫了一個KEY來處理不同的Button private static final int Permissions_GALLERY_KEY = 1; private static final int Permissions_CAMERA_KEY = 2; //需要的權限 注意請不要將數組寫成 private String mPermissions[] = {"Manifest.permission.WRITE_EXTERNAL_STORAGE"}; //這樣加了引號的是錯誤的,我犯過這種低級錯誤 private String mPermissions[] = {Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.CAMERA};
另外附危險權限清單(一般情況下只需要關注下面的危險權限一共9組24個,正常權限系統會自動添加,不需要另外授權)
危險權限組和權限:
每個組申請一個權限,這個組的其他權限也一並申請了。
所有危險的 Android 系統權限都屬於權限組。如果設備運行的是 Android 6.0(API 級別 23),並且應用的 targetSdkVersion 是 23 或更高版本,則當用戶請求危險權限時系統會發生以下行為:
- 如果應用請求其清單中列出的危險權限,而應用目前在權限組中沒有任何權限,則系統會向用戶顯示一個對話框,描述應用要訪問的權限組。對話框不描述該組內的具體權限。例如,如果應用請求
READ_CONTACTS權限,系統對話框只說明該應用需要訪問設備的聯系信息。如果用戶批准,系統將向應用授予其請求的權限。 - 如果應用請求其清單中列出的危險權限,而應用在同一權限組中已有另一項危險權限,則系統會立即授予該權限,而無需與用戶進行任何交互。例如,如果某應用已經請求並且被授予了
READ_CONTACTS權限,然后它又請求WRITE_CONTACTS,系統將立即授予該權限。
任何權限都可屬於一個權限組,包括正常權限和應用定義的權限。但權限組僅當權限危險時才影響用戶體驗。可以忽略正常權限的權限組。
如果設備運行的是 Android 5.1(API 級別 22)或更低版本,並且應用的 targetSdkVersion 是 22 或更低版本,則系統會在安裝時要求用戶授予權限。再次強調,系統只告訴用戶應用需要的權限組,而不告知具體權限。
具體的危險權限組和權限如下:
CALENDAR 日歷
READ_CALENDAR 讀日歷
WRITE_CALENDAR 寫日歷
CAMERA 相機
CONTACTS 通訊錄
READ_CONTACTS 讀通訊錄WRITE_CONTACTS 寫通訊錄GET_ACCOUNTS 得到賬號
LOCATION 位置
ACCESS_FINE_LOCATION 訪問精准位置ACCESS_COARSE_LOCATION 訪問大概位置
MICROPHONE 麥克風
RECORD_AUDIO 錄制音頻
PHONE 電話
READ_PHONE_STATE 讀電話狀態CALL_PHONE 打電話READ_CALL_LOG 讀通話記錄WRITE_CALL_LOG 寫通話記錄ADD_VOICEMAIL 添加語音信箱USE_SIP 使用SIP服務PROCESS_OUTGOING_CALLS 處理傳出呼叫
SENSORS 傳感器
BODY_SENSORS 物體傳感器(一般指距離,光感,重力等等這些感應接收器)
SMS 信息
SEND_SMS 發送信息RECEIVE_SMS 接收信息READ_SMS 讀信息RECEIVE_WAP_PUSH 接收WAP推送RECEIVE_MMS 接收彩信
STORAGE 存儲
代碼部分
下面是一個工具類
public class PermissionUtil { private static final int PERMISSION_REQUEST_CODE = 0xab; /** * 檢查單個權限 * * @param context * @return true = 已獲得授權. * false = 未獲得授權 */ public static boolean checkPermission(Context context, String permission) { int result = ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION); if (result == PackageManager.PERMISSION_GRANTED) { return true; } return false; } /** * 檢查一組權限 * * @param context * @param permissionArray * @return 返回未授權的權限list, 如果返回null等於全部權限都已經被授予. */ public static String[] checkPermissions(Context context, String[] permissionArray) { if (permissionArray == null || permissionArray.length == 0) { return null; } List<String> notPermissionList = new ArrayList<>(); for (String permission : permissionArray) { int result = ContextCompat.checkSelfPermission(context, permission); if (result != PackageManager.PERMISSION_GRANTED) { notPermissionList.add(permission); } } if (notPermissionList.size() == 0) { return null; } return notPermissionList.toArray(new String[notPermissionList.size()]); } /** * 申請權限 * * @param activity */ public static void applyPermission(Activity activity, String[] permissionArray, int designationRequestCode) { ActivityCompat.requestPermissions(activity, permissionArray, designationRequestCode); } /** * 申請權限 * * @param activity */ public static void applyPermission(Activity activity, String[] permissionArray) { ActivityCompat.requestPermissions(activity, permissionArray, PERMISSION_REQUEST_CODE); } /** * 處理申請權限返回后的結果,此方法可以指定requestCode * * @param requestCode 返回code * @param designationRequestCode 你指定的返回code * @param permissions 申請權限 * @param grantResults 權限申請結果 * @return String[] == null : 1.requestCode不等於designationRequestCode 2.權限申請未知錯誤 grantResults小於0 * String[]長度等於0:全部權限都申請成功 * String[]長度不等於0:未申請成功的權限 */ public static String[] handlerPermissionApplyResults(int requestCode, int designationRequestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { return handlerResults(requestCode, designationRequestCode, permissions, grantResults); } /** * 處理申請權限返回后的結果,此方法使用默認requestCode > PERMISSION_REQUEST_CODE * * @param requestCode 返回code * @param permissions 申請權限 * @param grantResults 權限申請結果 * @return String[] == null : 1.requestCode不等於默認PERMISSION_REQUEST_CODE 2.權限申請未知錯誤 grantResults小於0 * String[]長度等於0:全部權限都申請成功 * String[]長度不等於0:未申請成功的權限 */ public static String[] handlerPermissionApplyResults(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { return handlerResults(requestCode, PERMISSION_REQUEST_CODE, permissions, grantResults); } private static String[] handlerResults(int requestCode, int designationRequestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == designationRequestCode) { if (grantResults.length > 0) { List<String> notPermissionList = new ArrayList<>(); for (int i = 0; i < grantResults.length; i++) { int result = grantResults[i]; String permission = permissions[i]; if (result != PackageManager.PERMISSION_GRANTED) { notPermissionList.add(permission); } } if (!notPermissionList.isEmpty()) { return notPermissionList.toArray(new String[notPermissionList.size()]); } return new String[0]; } else { return null; } } else { return null; } } }
End
