Android 6.0动态权限
新項目,新苦B開始,
從Android 6.0(API 23)開始,允許用戶在應用運行時決定是否允許權限,而不是在應用安裝的時候。這種方法簡化了應用的安裝過程,因為用戶在安裝或更新應用的時候不需要允許權限。他也讓用戶對應用的功能有更多的控制;例如,用戶可以選擇給予相機應用相機的權限但是不允許使用設備位置的權限。用戶可進入應用設置隨時撤銷權限。
系統權限被分為兩種類型,正常的(normal)和敏感的(dangerous):
-
正常的權限不會直接讓用戶的隱私處于危險中。如果你的應用在清單文件中列入了正常的權限,系統會自動允許這些權限。
-
敏感權限給予應用方位用戶的機密數據。如果你的應用在清單文件中列入危險類權限,會明確地讓用戶對你的應用允許權限。
在所有的Android版本中,你的應用需要在清單文件中去申明它需要的正常的和危險的權限。然而,聲明的影響是不同的,依賴于系統版本和你應用的目標SDK等級:
-
如果設備運行在Android 5.1或更低,或者你的應用的 target SDK是22或者更低;如果你在清單文件中加入了敏感權限,當他們在安裝應用的時候必須同意權限;如果他們不同意權限,系統則不會安裝應用。
-
如果設備運行在Android 6.0或更高的版本,或者你的應用的 target SDK是23或者更高。應用必須在manifest文件中加入權限,而且在應用運行過程中必須在它需要的時候請求每一個危險的權限。用戶可以允許或者拒絕每一個權限,即使用戶拒絕了一個權限的請求而應用可以在限制功能地繼續運行。
注意:?從Android6.0(API 23)開始,用戶可以在任何時候撤銷任何應用的權限,即使應用目標SDK低于23。你應該測試你的用用驗證它正常的表現當它缺少需要的權限,不管你的應用的target SDK等級是多少。
不說了,直接上代碼,大家都弄這一行的代碼才是實貨
這是我下面 PermissionManager類
/** * Created by hy * 2017/10/24 15:06 * Note : */ public class PermissionManager {static List<Permission> permissions; public static List<Permission> getPermissions() {if (permissions==null){permissions=new ArrayList<>(); permissions.add(new Permission(Manifest.permission.ACCESS_FINE_LOCATION, "使用設備位置信息", false)); permissions.add(new Permission(Manifest.permission.WRITE_EXTERNAL_STORAGE, "訪問設備存儲空間", false));//讀取文件不需要申請權限 permissions.add(new Permission(Manifest.permission.READ_CALENDAR, "訪問日歷信息", false)); permissions.add(new Permission(Manifest.permission.CALL_PHONE, "撥打電話和管理通話", false));//調用撥號界面不需要申請權限 permissions.add(new Permission(Manifest.permission.CAMERA, "拍攝照片和錄制視頻", false)); permissions.add(new Permission(Manifest.permission.SEND_SMS, "發送和查看短信", false)); permissions.add(new Permission(Manifest.permission.BODY_SENSORS, "訪問傳感器數據", false)); permissions.add(new Permission(Manifest.permission.WRITE_CONTACTS, "使用通訊錄", false)); permissions.add(new Permission(Manifest.permission.RECORD_AUDIO, "錄制音頻", false)); }return permissions; }/** * 授權回調 */ public interface CheckInitPermissionCallback{/** * 權限授權完成 */ void checkOverPass(); /** * 權限申請未授權且點擊提示框取消按鈕 */ void checkOverCancel(); }/** * 授權回調 可選 */ public interface CheckNeedlessPermissionCallback{/** * 權限授權完成 */ void checkOverPass(); /** * 權限申請未授權且點擊提示框取消按鈕 */ void checkOverCancel(); }public static String getCName(String permissionName) {if (permissions==null){getPermissions(); }for (Permission permission :permissions){if (permission.getPermissionName().equals(permissionName)){return permission.getcName(); }}return "NotFound"; }public static class Permission {/** * 權限名 */ private String permissionName; /** * 權限中文名 */ private String cName; /** * 是否時必要的 * 必要權限啟動時檢測 拒絕時退出應用程序 * 非必要權限使用時檢測 */ private boolean isNeedful; public Permission(String permissionName, String cName, boolean isNeedful ) {this.permissionName = permissionName; this.cName = cName; this.isNeedful = isNeedful; }public String getPermissionName() {return permissionName; }public String getcName() {return cName; }public boolean isNeedful() {return isNeedful; }} }
這上面主要是講了,權限檢測,權限授權回調,這些主要是看代碼,理解思路,
1.getPermissions這個方法里面主要一個權限組,要用到的權限放進去,便于后面檢測。
2.CheckInitPermissionCallback,CheckNeedlessPermissionCallback ?一看就知道是權限回調
再看我的BaseActivity基類如何實現6.0權限的
/** * 設置界面返回 */ private final int SET_REQUEST_CODE = 122; /** * 設置界面(NeedLess) */ private final int SET_REQUEST_CODE_NEEDLESS = 123; /** * 必要權限授權界面返回 */ private final int NEEDFUL_PERMISSIONS_RESULT = 101; /** * 非必要權限授權界面返回 */ private final int NEEDLESS_PERMISSIONS_RESULT = 102; private PermissionManager.CheckInitPermissionCallback checkInitPermissionCallback; PermissionManager.CheckNeedlessPermissionCallback checkNeedlessPermissionCallback; /** * 必要權限集中驗證 * (應用程序啟動時調用 如loading界面) * * @param checkInitPermissionCallback */ protected void checkInitPermission(PermissionManager.CheckInitPermissionCallback checkInitPermissionCallback) {this.checkInitPermissionCallback = checkInitPermissionCallback; List<PermissionManager.Permission> permissionList = PermissionManager.getPermissions(); List<PermissionManager.Permission> temp = new ArrayList<>(); for (PermissionManager.Permission permission : permissionList) {if (permission.isNeedful() && ContextCompat.checkSelfPermission(mContext, permission.getPermissionName())!= PackageManager.PERMISSION_GRANTED) {//啟動時檢測是否時必要權限且沒有授權 temp.add(permission); }}if (temp.size() > 0) {String[] permissions = new String[temp.size()]; for (int i = 0; i < temp.size(); i++) {permissions[i] = temp.get(i).getPermissionName(); }ActivityCompat.requestPermissions((Activity) mContext, permissions, NEEDFUL_PERMISSIONS_RESULT); } else {checkInitPermissionCallback.checkOverPass(); } }/** * 非必要權限驗證 * (在打開指定界面或使用特定功能時調用) * * @param permission Manifest.permission.ACCESS_FINE_LOCATION * @param checkNeedlessPermissionCallback */ public void checkNeedlessPermission(String permission, PermissionManager.CheckNeedlessPermissionCallback checkNeedlessPermissionCallback) {this.checkNeedlessPermissionCallback = checkNeedlessPermissionCallback; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {if (mContext.checkSelfPermission(permission)== PackageManager.PERMISSION_GRANTED) {checkNeedlessPermissionCallback.checkOverPass(); } else {checkNeedlessPermissionCallback.checkOverCancel(); }} else {checkNeedlessPermissionCallback.checkOverPass(); } }public void showPremissionDialog(String cName, String cancelText) {new BaseDialog(mContext).setTitleText("提示").setContentText("應用程序 需要 " + cName + " 權限,請將權限開啟\n設置路徑:設置 ->應用管理 ->" + LiPackageUtil.getApplicationName(mContext) + " ->權限").setCancelButtonText(cancelText).setConfirmButtonText("設置").setTypeMode(BaseDialog.WARN_TYPE).setOnClickDialogButtonListener(new BaseDialog.DialogButtonListener() {@Override public void onCancelButtonClicked(int requestCode) {checkInitPermissionCallback.checkOverCancel(); }@Override public void onConfirmeButtonClicked(int requestCode) {try {Intent intent = new Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS); startActivityForResult(intent, SET_REQUEST_CODE); } catch (Exception e) {Intent intent = new Intent(Settings.ACTION_SETTINGS); startActivityForResult(intent, SET_REQUEST_CODE); }}}).show(); }public void showNeedlessPremissionDialog(String contentStr, String cancelText) {new BaseDialog(mContext).setTitleText("提示").setContentText(contentStr + "\n設置路徑:設置 ->應用管理 ->" + LiPackageUtil.getApplicationName(mContext) + " ->權限").setCancelButtonText(cancelText).setConfirmButtonText("設置").setTypeMode(BaseDialog.WARN_TYPE).setOnClickDialogButtonListener(new BaseDialog.DialogButtonListener() {@Override public void onCancelButtonClicked(int requestCode) {}@Override public void onConfirmeButtonClicked(int requestCode) {Intent intent = new Intent(Settings.ACTION_SETTINGS); startActivityForResult(intent, SET_REQUEST_CODE_NEEDLESS); }}).show(); }@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == NEEDFUL_PERMISSIONS_RESULT) {for (int g : grantResults) {if (g == PackageManager.PERMISSION_GRANTED) {checkInitPermission(checkInitPermissionCallback); return; }}showPremissionDialog(PermissionManager.getCName(permissions[0]), "退出"); } else {if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {checkInitPermission(checkInitPermissionCallback); return; }showPremissionDialog(PermissionManager.getCName(permissions[0]), "取消"); }}@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data); if (SET_REQUEST_CODE == requestCode) {checkInitPermission(checkInitPermissionCallback); } }
這下面這一塊主要弄些常量做啥,你們懂的
/** * 設置界面返回 */ private final int SET_REQUEST_CODE = 122; /** * 設置界面(NeedLess) */ private final int SET_REQUEST_CODE_NEEDLESS = 123; /** * 必要權限授權界面返回 */ private final int NEEDFUL_PERMISSIONS_RESULT = 101; /** * 非必要權限授權界面返回 */ private final int NEEDLESS_PERMISSIONS_RESULT = 102;checkInitPermission這個方法里面主要 是必要權限集中驗證比如應用程序啟動時調用 如loading界面
checkNeedlessPermission 而這個主要是非必要權限驗證,比如? Manifest.permission.ACCESS_FINE_LOCATION
這兩個主要是利用接口回調進行驗證。
showPremissionDialog ?自定義的彈框
順便把這貼出來,主要是得到
tApplicationName 名子public static String getApplicationName(Context context) {PackageManager packageManager = null; ApplicationInfo applicationInfo = null; try {packageManager = context.getApplicationContext().getPackageManager(); applicationInfo = packageManager.getApplicationInfo(getPackageName(context), 0); } catch (PackageManager.NameNotFoundException e) {applicationInfo = null; }String applicationName =(String) packageManager.getApplicationLabel(applicationInfo); return applicationName; } 主要是讓大家去理解他,代碼 已測試可以用,除了自定義對話框大兄弟們得要自己定。
總結
以上是生活随笔為你收集整理的Android 6.0动态权限的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 百度地图定位城市
- 下一篇: Android 各种工