日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android权限管理及动态申请权限

發布時間:2023/12/14 Android 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android权限管理及动态申请权限 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Android權限管理


一、基本介紹

??Android安全架構規定:默認情況下,任何應用都沒有權限執行對其他應用、操作系統或用戶有不利影響的任何操作。這包括讀寫用戶的私有數據(如聯系人或電子郵件等)、讀寫其他應用的文件、執行網絡訪問、使設備保持喚醒狀態等等。
??應用權限基于系統安全功能,并有助于 Android 支持與用戶隱私相關的以下目標:

  • 控制:用戶可以控制他們與應用分享的數據。
  • 透明度:用戶可以了解應用使用了哪些數據以及應用為何訪問相關數據。
  • 數據最小化:應用僅能訪問和使用用戶調用的特定任務或操作所需的數據。

權限類型

??Android將權限分為不同的類型,包括安裝時權限、運行時權限和特殊權限。每種權限類型都指明了當系統授予應用該權限后,應用可以訪問的受限數據范圍以及應用可以執行的受限操作范圍。

1、安裝時權限

??安裝時權限會授予應用對受限數據的受限訪問權限,并允許應用執行對系統或其他應用只有最低影響的受限操作。如果在應用中聲明了安裝時權限,系統會在用戶允許該應用安裝時自動授予相應權限。
??安裝時權限分為多個子類型,包括普通權限和簽名權限。

  • 普通權限
    此類權限允許訪問超出應用沙盒的數據和執行超出應用沙盒的操作。但是,這些數據和操作對用戶隱私及對其他應用的操作帶來的風險非常小。系統會為普通權限分配“normal”保護級別。

  • 簽名權限
    當應用聲明了其他應用已定義的簽名權限時,如果兩個應用使用同一個簽名文件進行簽名,系統會在安裝時向前者授予該權限。否則,系統無法向前者授予該權限。系統會為簽名權限分配“signature”保護級別。

2、運行時權限

??運行時權限也稱為危險權限,此類權限會授予應用對受限數據的額外訪問權限,并允許應用執行對系統和其他應用具有更嚴重影響的受限操作。所以需要在運行時請求權限,然后才能訪問受限數據或執行受限操作。當應用請求運行時權限時,系統會彈框顯示運行時權限申請提示。許多運行時權限會訪問用戶私有數據,這是一種特殊的受限數據,其中包含可能比較敏感的信息。例如,位置信息和聯系信息就屬于用戶私人數據。系統會為運行時權限分配“dangerous”保護級別。
??運行時權限機制是Android 6.0(M)的新特性,因此不同Android版本的設備以及應用設置的targetSdkVersion都會影響到應用申請危險權限時的表現。

  • 在Android6.0版本之前的設備上使用時,應用還是使用舊的權限系統,危險權限還是在應用安裝時就會進行申請,不管targetSdkVersion是否大于23。
  • 在Android6.0版本及更高版本的設備上使用時,則會根據應用中設置的targetSdkVersion進行判斷:1)若targetSdkVersion低于23,則繼續使用舊規則,危險權限在安裝時進行申請;2)若targetSdkVersion大于等于23時,則應用需要在運行時進行權限動態申請。

注:從Android 6.0(Marshmallow,API 23)開始,用戶可以在任何時候撤銷應用的某個權限,即使應用的targetSdkVersion小于23。因此必須確保在請求權限失敗后,應用還能表現良好。


??如果設備運行的是Android 6.0或更高版本,并且應用的targetSdkVersion是23或更高版本,則當用戶請求危險權限時系統會發生以下行為:

  • 如果應用請求一個已經在其清單文件中列出的危險權限,并且應用當前沒有擁有該權限組的任何權限,那么系統就會向用戶顯示一個對話框詢問用戶是否授權,該對話框會描述應用想要訪問的權限組而不是組內的特定權限。例如,如果一個應用請求READ_CONTACTS權限,系統會彈出對話框告知用戶應用需要訪問設備的聯系人,如果用戶允許授權,那么系統將授予應用所需的權限。
  • 如果應用請求一個已經在其清單文件中列出的危險權限,并且應用當前已經擁有了該權限組的其它危險權限,系統會立即授予該權限而不需要通知用戶。例如,如果一個應用之前已經請求過并已經被授予了READ_CONTACTS權限,那么之后它請求WRITE_CONTACTS時系統將立即授予該權限。

權限組概念:
??根據設備的功能和特性,權限被分為權限組。系統以權限組的形式來處理權限請求,一個權限組可能對應Manifest中申請的幾個權限。例如,STORAGE權限組包括READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE權限。權限組的方式讓用戶更容易理解權限,和更方便處理APP的權限請求,防止過多的復雜的授予單獨的權限。
??任何權限都可以屬于一個權限組,包括正常權限和應用自定義的權限。但權限組僅當權限危險時才影響用戶體驗。可以忽略正常權限的權限組。

危險權限以及對應分組如下:

3、特殊權限

??特殊權限與特定的應用操作相對應。只有平臺和原始設備制造商 (OEM) 可以定義特殊權限。此外,如果平臺和 OEM 想要防止有人執行功能特別強大的操作(例如通過其他應用繪圖),通常會定義特殊權限。系統會為特殊權限分配“appop”保護級別。在Android 6.0以后,只有系統應用才能夠使用這些特殊權限。




二、動態權限申請

1、主要使用方法

(1)ContextCompat.checkSelfPermission
??檢查應用是否具有某個危險權限,如果應用具有此權限,方法將返回 PackageManager.PERMISSION_GRANTED;如果應用不具有此權限,方法將返回 PackageManager.PERMISSION_DENIED。

(2)ActivityCompat.requestPermissions
??應用可以通過這個方法動態申請權限,調用后會彈出一個對話框提示用戶授權所申請的權限組。

(3)ActivityCompat.shouldShowRequestPermissionRationale
??檢查此權限上次是否被拒絕過。如果應用之前請求過此權限但用戶拒絕了請求,但可繼續請求,則此方法將返回 true。而以下幾種情況均返回false: 1)用戶從未申請過該權限;2)用戶在過去拒絕了權限請求,并在權限請求系統對話框中選擇了 Don’t ask again 選項;3)用戶允許了該權限申請請求;4)設備規范禁止應用具有該權限。
??因此單獨使用該方法去做判斷,是沒用的,應該在請求權限回調中使用。

注:不同手機系統對于權限處理方面可能存在差異,部分手機系統在彈出授權申請時選擇拒絕就默認了不再彈出,此時調用此方法返回false。

(4)onRequestPermissionsResult
??當應用請求權限時,系統將向用戶顯示一個對話框。當用戶響應時,系統將調用應用的 onRequestPermissionsResult() 方法,向其傳遞用戶響應,處理對應的場景。

2、調用流程

(1)在AndroidManifest.xml中對要申請的權限進行申明。

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> <uses-permission android:name="android.permission.CAMERA"></uses-permission> <uses-permission android:name="android.permission.WRITE_CONTACTS"></uses-permission> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>

(2)申請權限前對權限進行檢查,若應用不具有該權限,則進行權限申請;若一次申請多個權限,則應該逐個進行權限檢查,最后對未授權的權限進行統一申請。

private String PM_SINGLE=Manifest.permission.WRITE_EXTERNAL_STORAGE; //申請單個權限 public void applyForSinglePermission(){Log.i(TAG,"applyForSinglePermission");try{//如果操作系統SDK級別在23之上(android6.0),就進行動態權限申請if(Build.VERSION.SDK_INT>=23){//判斷是否擁有權限int nRet=ContextCompat.checkSelfPermission(this,PM_SINGLE);Log.i(TAG,"checkSelfPermission nRet="+nRet);if(nRet!= PackageManager.PERMISSION_GRANTED){Log.i(TAG,"進行權限申請...");ActivityCompat.requestPermissions(this,new String[]{PM_SINGLE},10000);}else{showToast("權限已授權");}}}catch(Exception e){e.printStackTrace();} }private String[] PM_MULTIPLE={Manifest.permission.ACCESS_COARSE_LOCATION,Manifest.permission.CAMERA,Manifest.permission.WRITE_CONTACTS }; //申請多個權限 public void applyForMultiplePermissions(){Log.i(TAG,"applyForMultiplePermissions");try{//如果操作系統SDK級別在23之上(android6.0),就進行動態權限申請if(Build.VERSION.SDK_INT>=23){ArrayList<String> pmList=new ArrayList<>();//獲取當前未授權的權限列表for(String permission:PM_MULTIPLE){int nRet=ContextCompat.checkSelfPermission(this,permission);Log.i(TAG,"checkSelfPermission nRet="+nRet);if(nRet!= PackageManager.PERMISSION_GRANTED){pmList.add(permission);}}if(pmList.size()>0){Log.i(TAG,"進行權限申請...");String[] sList=pmList.toArray(new String[0]);ActivityCompat.requestPermissions(this,sList,10000);}else{showToast("全部權限都已授權");}}}catch(Exception e){e.printStackTrace();} }

(3)重寫onRequestPermissionsResult回調方法,對用戶的權限授權操作進行監聽處理。

@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);try{ArrayList<String> requestList=new ArrayList<>();//允許詢問列表ArrayList<String> banList=new ArrayList<>();//禁止列表for(int i=0;i<permissions.length;i++){if(grantResults[i] == PackageManager.PERMISSION_GRANTED){Log.i(TAG,"【"+permissions[i]+"】權限授權成功");}else{//判斷是否允許重新申請該權限boolean nRet=ActivityCompat.shouldShowRequestPermissionRationale(this,permissions[i]);Log.i(TAG,"shouldShowRequestPermissionRationale nRet="+nRet);if(nRet){//允許重新申請requestList.add(permissions[i]);}else{//禁止申請banList.add(permissions[i]);}}}//優先對禁止列表進行判斷if(banList.size()>0){//告知該權限作用,要求手動授予權限showFinishedDialog();}else if(requestList.size()>0){//告知權限的作用,并重新申請showTipDialog(requestList);}else{showToast("權限授權成功");}}catch (Exception e){e.printStackTrace();showToast("權限申請回調中發生異常");} }public void showFinishedDialog(){AlertDialog dialog = new AlertDialog.Builder(this).setTitle("警告").setMessage("請前往設置中打開相關權限,否則功能無法正常運行!").setPositiveButton("確定", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {// 一般情況下如果用戶不授權的話,功能是無法運行的,做退出處理finish();}}).create();dialog.show(); }public void showTipDialog(ArrayList<String> pmList){AlertDialog dialog = new AlertDialog.Builder(this).setTitle("提示").setMessage("【"+pmList.toString()+"】權限為應用必要權限,請授權").setPositiveButton("確定", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {String[] sList=pmList.toArray(new String[0]);//重新申請該權限ActivityCompat.requestPermissions(MainActivity.this,sList,10000);}}).create();dialog.show(); }


三、PermissionUtil工具類

??這個類是自己封裝的一個Android權限申請的工具類,可以通過權限組名或權限名來對多個權限進行申請,并將對用戶授權操作的處理邏輯封裝起來,可以通過傳入回調接口,針對用戶授權情況來定義不同的響應處理。

PermissionUtil實現:

import android.Manifest; import android.app.Activity; import android.content.Context; import android.content.pm.PackageManager; import android.os.Build; import android.util.Log;import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat;import java.util.ArrayList; import java.util.HashMap; import java.util.Map;/*** author:chenjs*/ public class PermissionUtil {private static final String TAG=PermissionUtil.class.getSimpleName();private static final boolean LOG_FLAG=true;//日志標識//日歷private static final String[] Group_Calendar={Manifest.permission.READ_CALENDAR,Manifest.permission.WRITE_CALENDAR};//照相機private static final String[] Group_Camera={Manifest.permission.CAMERA};//通訊錄private static final String[] Group_Contacts={Manifest.permission.WRITE_CONTACTS,Manifest.permission.GET_ACCOUNTS,Manifest.permission.READ_CONTACTS};//定位private static final String[] Group_Location={Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION};//麥克風private static final String[] Group_Microphone={Manifest.permission.RECORD_AUDIO};//電話private static final String[] Group_Phone={Manifest.permission.READ_PHONE_STATE,Manifest.permission.CALL_PHONE,Manifest.permission.READ_CALL_LOG,Manifest.permission.WRITE_CALL_LOG,Manifest.permission.ADD_VOICEMAIL,Manifest.permission.USE_SIP,Manifest.permission.PROCESS_OUTGOING_CALLS};//傳感器private static final String[] Group_Sensors={Manifest.permission.BODY_SENSORS};//短信private static final String[] Group_Sms={Manifest.permission.READ_SMS,Manifest.permission.SEND_SMS,Manifest.permission.RECEIVE_SMS,Manifest.permission.RECEIVE_MMS,Manifest.permission.RECEIVE_WAP_PUSH};//存儲private static final String[] Group_Storage={Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE};private static Map<String,String[]> m_PermissionGroupList=null;static{initMap();}/*** 通過權限組名來申請一組權限* @param context* @param permissionGroupName* @param requestCode* @param listener*/public static void requestByGroupName(Activity context, String permissionGroupName,int requestCode,OnPermissionsListener listener){requestByGroupName(context, new String[]{permissionGroupName}, requestCode, listener);}/*** 通過權限組名來申請多組權限* @param context Activity上下文* @param pgNameArray 多個要申請的權限組名稱* @param requestCode 請求碼* @param listener 回調接口*/public static void requestByGroupName(Activity context, String[] pgNameArray,int requestCode,OnPermissionsListener listener){showLog("requestByPermissionGroup");try{//如果操作系統SDK級別在23之上(android6.0),就進行動態權限申請if(Build.VERSION.SDK_INT>=23 && pgNameArray!=null){String[] permissionsList=getAppPermissionsList(context);//應用權限列表ArrayList<String> targetList=new ArrayList<>();if(permissionsList==null || permissionsList.length==0){showLog("獲得權限列表為空");return;}for(String groupName:pgNameArray){ArrayList<String> tmpPermissionList=isPermissionDeclared(permissionsList,groupName);if(tmpPermissionList==null){//未找到showLog("未找到["+groupName+"]中的權限");continue;}for(int i=0;i<tmpPermissionList.size();i++){//判斷是否擁有權限int nRet=ContextCompat.checkSelfPermission(context,tmpPermissionList.get(i));if(nRet!= PackageManager.PERMISSION_GRANTED){targetList.add(tmpPermissionList.get(i));}}}if(targetList.size()>0){showLog("進行以下權限申請:"+targetList.toString());String[] sList=targetList.toArray(new String[0]);ActivityCompat.requestPermissions(context,sList,requestCode);}else{showLog("全部權限都已授權");if(listener!=null){listener.onPermissionsOwned();}}}}catch(Exception e){e.printStackTrace();}}/*** 通過權限名來申請一組權限* @param context* @param permission* @param requestCode* @param listener*/public static void requestByPermissionName(Activity context, String permission,int requestCode,OnPermissionsListener listener){requestByPermissionName(context, new String[]{permission}, requestCode, listener);}/*** 通過權限名來申請多組權限* @param context Activity上下文* @param permissionArray 多個要申請的權限名稱* @param requestCode 請求碼* @param listener 回調接口*/public static void requestByPermissionName(Activity context, String[] permissionArray,int requestCode,OnPermissionsListener listener){showLog("requestPermissions");try{//如果操作系統SDK級別在23之上(android6.0),就進行動態權限申請if(Build.VERSION.SDK_INT>=23 && permissionArray!=null){ArrayList<String> targetList=new ArrayList<>();for(String strPermission:permissionArray){//判斷是否擁有權限int nRet=ContextCompat.checkSelfPermission(context,strPermission);if(nRet!= PackageManager.PERMISSION_GRANTED){targetList.add(strPermission);}}if(targetList.size()>0){showLog("進行以下權限申請:"+targetList.toString());String[] sList=targetList.toArray(new String[0]);ActivityCompat.requestPermissions(context,sList,requestCode);}else{showLog("全部權限都已授權");if(listener!=null){listener.onPermissionsOwned();}}}}catch(Exception e){e.printStackTrace();}}/*** 針對申請權限時的用戶操作進行處理* @param context* @param permissions 申請的權限* @param grantResults 各權限的授權狀態* @param listener 回調接口* @param controlFlag 控制標識,用于判斷當響應禁止列表后,是否繼續處理可再申請列表(避免出現同時處理禁止列表和可再申請列表,互相干擾,比如彈出兩個提示框)*/public static void onRequestPermissionsResult(Activity context,String[] permissions, int[] grantResults,OnPermissionsListener listener,boolean controlFlag) {try{ArrayList<String> requestList=new ArrayList<>();//可再申請列表ArrayList<String> banList=new ArrayList<>();//禁止列表for(int i=0;i<permissions.length;i++){if(grantResults[i] == PackageManager.PERMISSION_GRANTED){showLog("["+permissions[i]+"]權限授權成功");}else{boolean nRet=ActivityCompat.shouldShowRequestPermissionRationale(context,permissions[i]);//Log.i(TAG,"shouldShowRequestPermissionRationale nRet="+nRet);if(nRet){//允許重新申請requestList.add(permissions[i]);}else{//禁止申請banList.add(permissions[i]);}}}do{//優先對禁止列表進行判斷if(banList.size()>0){if(listener!=null){listener.onPermissionsForbidden(permissions,grantResults,banList);}if(!controlFlag){//對禁止列表處理后,且控制標識為false,則跳過對可再申請列表的處理break;}}if(requestList.size()>0){if(listener!=null){listener.onPermissionsDenied(permissions,grantResults,requestList);}}if(banList.size()==0 && requestList.size()==0){showLog("權限授權成功");if(listener!=null){listener.onPermissionsSucceed();}}}while (false);}catch (Exception e){e.printStackTrace();}}/*** 判斷權限狀態* @param context* @param permission 權限名* @return*/public static boolean checkPermission(Context context,String permission){try{//如果操作系統SDK級別在23之上(android6.0),就進行動態權限申請if(Build.VERSION.SDK_INT>=23){int nRet= ContextCompat.checkSelfPermission(context,permission);showLog("checkSelfPermission nRet="+nRet);return nRet==PackageManager.PERMISSION_GRANTED? true : false;}return true;}catch(Exception e){e.printStackTrace();return false;}}/*** 獲得當前應用清單中的權限列表* @param context 應用上下文* @return*/public static String[] getAppPermissionsList(Context context){try{PackageManager packageManager = context.getApplicationContext().getPackageManager();String packageName=context.getApplicationContext().getPackageName();String[] array = packageManager.getPackageInfo(packageName,PackageManager.GET_PERMISSIONS).requestedPermissions;return array;}catch (Exception e){e.printStackTrace();}return null;}/*** 判斷權限列表中是否聲明了指定權限組中的權限* @param permissionList 權限列表* @param permissionGroup 權限組名* @return 存在則返回找到的權限組權限,否則返回null*/public static ArrayList<String> isPermissionDeclared(String[] permissionList, String permissionGroup){try{if(permissionList!=null && permissionGroup!=null){String[] pmGroup=m_PermissionGroupList.get(permissionGroup);if(pmGroup!=null){ArrayList<String> arrayList=new ArrayList<>();//遍歷for(int i=0;i<pmGroup.length;i++){String strPermission=pmGroup[i];for(int j=0;j< permissionList.length;j++){if(strPermission.equals(permissionList[j])){//找到指定權限組中的權限arrayList.add(strPermission);break;}}}if(arrayList.size()==0){return null;}return arrayList;}}}catch (Exception e){e.printStackTrace();}return null;}private static void initMap(){if(m_PermissionGroupList==null){m_PermissionGroupList=new HashMap<>();m_PermissionGroupList.put(Manifest.permission_group.CALENDAR,Group_Calendar);m_PermissionGroupList.put(Manifest.permission_group.CAMERA,Group_Camera);m_PermissionGroupList.put(Manifest.permission_group.CONTACTS,Group_Contacts);m_PermissionGroupList.put(Manifest.permission_group.LOCATION,Group_Location);m_PermissionGroupList.put(Manifest.permission_group.MICROPHONE,Group_Microphone);m_PermissionGroupList.put(Manifest.permission_group.PHONE,Group_Phone);m_PermissionGroupList.put(Manifest.permission_group.SENSORS,Group_Sensors);m_PermissionGroupList.put(Manifest.permission_group.SMS,Group_Sms);m_PermissionGroupList.put(Manifest.permission_group.STORAGE,Group_Storage);}}private static void showLog(String str){if(LOG_FLAG){Log.i(TAG,str);}}public interface OnPermissionsListener {/*** 權限都已擁有時的處理*/void onPermissionsOwned();/*** 權限被禁止時的處理* @param permissions 申請的全部權限* @param grantResults 各權限的授權狀態* @param pmList 禁止申請的權限列表*/void onPermissionsForbidden(String[] permissions, int[] grantResults,ArrayList<String> pmList);/*** 權限被拒絕時的處理* @param permissions* @param grantResults* @param pmList 可再申請的權限列表*/void onPermissionsDenied(String[] permissions, int[] grantResults,ArrayList<String> pmList);/*** 權限申請成功時的處理*/void onPermissionsSucceed();} }

使用方式可以參考以下例子:

private final int RequestCode3_1 =10004; //由使用者根據自身需求進行重寫 private PermissionUtil.OnPermissionsListener mListener3_1=new PermissionUtil.OnPermissionsListener() {@Overridepublic void onPermissionsOwned() {showTip("該權限已擁有");}@Overridepublic void onPermissionsForbidden(String[] permissions, int[] grantResults, ArrayList<String> pmList) {showTip("以下權限被禁止:"+pmList.toString());AlertDialog dialog = new AlertDialog.Builder(mContext).setTitle("警告").setMessage("請前往設置中手動打開"+pmList.toString()+"權限!").setPositiveButton("確定", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {}}).create();dialog.show();}@Overridepublic void onPermissionsDenied(String[] permissions, int[] grantResults, ArrayList<String> pmList) {showTip("以下權限被拒絕授權:"+pmList.toString());//重新請求權限AlertDialog dialog = new AlertDialog.Builder(mContext).setTitle("提示").setMessage("【"+pmList.toString()+"】權限為應用必要權限,請授權").setPositiveButton("確定", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {String[] sList=pmList.toArray(new String[0]);//重新申請權限,通過權限名的方式申請多組權限PermissionUtil.requestByPermissionName(mContext,sList, RequestCode3_1,mListener3_1);}}).create();dialog.show();}@Overridepublic void onPermissionsSucceed() {showTip("權限申請成功");} };public void requestPermission3_1(){String[] pgArray=new String[]{Manifest.permission_group.SENSORS,Manifest.permission_group.SMS,Manifest.permission_group.STORAGE};showTip("進行[傳感器+短信+存儲]權限申請...");//通過權限組名來申請指定權限PermissionUtil.requestByGroupName(mContext,pgArray, RequestCode3_1,mListener3_1); }@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);switch (requestCode){//可以針對不同的權限申請操作進行不同處理,也可以統一以相同方式處理(不對requestCode進行判斷)case RequestCode3_1:{PermissionUtil.onRequestPermissionsResult(mContext,permissions,grantResults,mListener3_1,false);break;}} }

具體的工具類以及演示工程放在Github上,感興趣的同學可以了解一下。如果有什么問題,歡迎來一起討論,共同進步。

GitHub地址:https://github.com/JINSHENGCCC/Android_Common/tree/master/AndroidPermission/src




四、參考

  • Android 中的權限
  • 秒懂Android開發之權限總結
  • Android權限管理詳解
  • Android 運行時權限處理
  • Android 6.0動態權限申請
  • Android6.0危險權限列表
  • 總結

    以上是生活随笔為你收集整理的Android权限管理及动态申请权限的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。