Android 6.0动态权限
新項(xiàng)目,新苦B開(kāi)始,
從Android 6.0(API 23)開(kāi)始,允許用戶在應(yīng)用運(yùn)行時(shí)決定是否允許權(quán)限,而不是在應(yīng)用安裝的時(shí)候。這種方法簡(jiǎn)化了應(yīng)用的安裝過(guò)程,因?yàn)橛脩粼诎惭b或更新應(yīng)用的時(shí)候不需要允許權(quán)限。他也讓用戶對(duì)應(yīng)用的功能有更多的控制;例如,用戶可以選擇給予相機(jī)應(yīng)用相機(jī)的權(quán)限但是不允許使用設(shè)備位置的權(quán)限。用戶可進(jìn)入應(yīng)用設(shè)置隨時(shí)撤銷權(quán)限。
系統(tǒng)權(quán)限被分為兩種類型,正常的(normal)和敏感的(dangerous):
-
正常的權(quán)限不會(huì)直接讓用戶的隱私處于危險(xiǎn)中。如果你的應(yīng)用在清單文件中列入了正常的權(quán)限,系統(tǒng)會(huì)自動(dòng)允許這些權(quán)限。
-
敏感權(quán)限給予應(yīng)用方位用戶的機(jī)密數(shù)據(jù)。如果你的應(yīng)用在清單文件中列入危險(xiǎn)類權(quán)限,會(huì)明確地讓用戶對(duì)你的應(yīng)用允許權(quán)限。
在所有的Android版本中,你的應(yīng)用需要在清單文件中去申明它需要的正常的和危險(xiǎn)的權(quán)限。然而,聲明的影響是不同的,依賴于系統(tǒng)版本和你應(yīng)用的目標(biāo)SDK等級(jí):
-
如果設(shè)備運(yùn)行在Android 5.1或更低,或者你的應(yīng)用的 target SDK是22或者更低;如果你在清單文件中加入了敏感權(quán)限,當(dāng)他們?cè)诎惭b應(yīng)用的時(shí)候必須同意權(quán)限;如果他們不同意權(quán)限,系統(tǒng)則不會(huì)安裝應(yīng)用。
-
如果設(shè)備運(yùn)行在Android 6.0或更高的版本,或者你的應(yīng)用的 target SDK是23或者更高。應(yīng)用必須在manifest文件中加入權(quán)限,而且在應(yīng)用運(yùn)行過(guò)程中必須在它需要的時(shí)候請(qǐng)求每一個(gè)危險(xiǎn)的權(quán)限。用戶可以允許或者拒絕每一個(gè)權(quán)限,即使用戶拒絕了一個(gè)權(quán)限的請(qǐng)求而應(yīng)用可以在限制功能地繼續(xù)運(yùn)行。
注意:?從Android6.0(API 23)開(kāi)始,用戶可以在任何時(shí)候撤銷任何應(yīng)用的權(quán)限,即使應(yīng)用目標(biāo)SDK低于23。你應(yīng)該測(cè)試你的用用驗(yàn)證它正常的表現(xiàn)當(dāng)它缺少需要的權(quán)限,不管你的應(yīng)用的target SDK等級(jí)是多少。
不說(shuō)了,直接上代碼,大家都弄這一行的代碼才是實(shí)貨
這是我下面 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, "使用設(shè)備位置信息", false)); permissions.add(new Permission(Manifest.permission.WRITE_EXTERNAL_STORAGE, "訪問(wèn)設(shè)備存儲(chǔ)空間", false));//讀取文件不需要申請(qǐng)權(quán)限 permissions.add(new Permission(Manifest.permission.READ_CALENDAR, "訪問(wèn)日歷信息", false)); permissions.add(new Permission(Manifest.permission.CALL_PHONE, "撥打電話和管理通話", false));//調(diào)用撥號(hào)界面不需要申請(qǐng)權(quán)限 permissions.add(new Permission(Manifest.permission.CAMERA, "拍攝照片和錄制視頻", false)); permissions.add(new Permission(Manifest.permission.SEND_SMS, "發(fā)送和查看短信", false)); permissions.add(new Permission(Manifest.permission.BODY_SENSORS, "訪問(wèn)傳感器數(shù)據(jù)", false)); permissions.add(new Permission(Manifest.permission.WRITE_CONTACTS, "使用通訊錄", false)); permissions.add(new Permission(Manifest.permission.RECORD_AUDIO, "錄制音頻", false)); }return permissions; }/** * 授權(quán)回調(diào) */ public interface CheckInitPermissionCallback{/** * 權(quán)限授權(quán)完成 */ void checkOverPass(); /** * 權(quán)限申請(qǐng)未授權(quán)且點(diǎn)擊提示框取消按鈕 */ void checkOverCancel(); }/** * 授權(quán)回調(diào) 可選 */ public interface CheckNeedlessPermissionCallback{/** * 權(quán)限授權(quán)完成 */ void checkOverPass(); /** * 權(quán)限申請(qǐng)未授權(quán)且點(diǎn)擊提示框取消按鈕 */ 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 {/** * 權(quán)限名 */ private String permissionName; /** * 權(quán)限中文名 */ private String cName; /** * 是否時(shí)必要的 * 必要權(quán)限啟動(dòng)時(shí)檢測(cè) 拒絕時(shí)退出應(yīng)用程序 * 非必要權(quán)限使用時(shí)檢測(cè) */ 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; }} }
這上面主要是講了,權(quán)限檢測(cè),權(quán)限授權(quán)回調(diào),這些主要是看代碼,理解思路,
1.getPermissions這個(gè)方法里面主要一個(gè)權(quán)限組,要用到的權(quán)限放進(jìn)去,便于后面檢測(cè)。
2.CheckInitPermissionCallback,CheckNeedlessPermissionCallback ?一看就知道是權(quán)限回調(diào)
再看我的BaseActivity基類如何實(shí)現(xiàn)6.0權(quán)限的
/** * 設(shè)置界面返回 */ private final int SET_REQUEST_CODE = 122; /** * 設(shè)置界面(NeedLess) */ private final int SET_REQUEST_CODE_NEEDLESS = 123; /** * 必要權(quán)限授權(quán)界面返回 */ private final int NEEDFUL_PERMISSIONS_RESULT = 101; /** * 非必要權(quán)限授權(quán)界面返回 */ private final int NEEDLESS_PERMISSIONS_RESULT = 102; private PermissionManager.CheckInitPermissionCallback checkInitPermissionCallback; PermissionManager.CheckNeedlessPermissionCallback checkNeedlessPermissionCallback; /** * 必要權(quán)限集中驗(yàn)證 * (應(yīng)用程序啟動(dòng)時(shí)調(diào)用 如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) {//啟動(dòng)時(shí)檢測(cè)是否時(shí)必要權(quán)限且沒(méi)有授權(quán) 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(); } }/** * 非必要權(quán)限驗(yàn)證 * (在打開(kāi)指定界面或使用特定功能時(shí)調(diào)用) * * @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("應(yīng)用程序 需要 " + cName + " 權(quán)限,請(qǐng)將權(quán)限開(kāi)啟\n設(shè)置路徑:設(shè)置 ->應(yīng)用管理 ->" + LiPackageUtil.getApplicationName(mContext) + " ->權(quán)限").setCancelButtonText(cancelText).setConfirmButtonText("設(shè)置").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設(shè)置路徑:設(shè)置 ->應(yīng)用管理 ->" + LiPackageUtil.getApplicationName(mContext) + " ->權(quán)限").setCancelButtonText(cancelText).setConfirmButtonText("設(shè)置").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); } }
這下面這一塊主要弄些常量做啥,你們懂的
/** * 設(shè)置界面返回 */ private final int SET_REQUEST_CODE = 122; /** * 設(shè)置界面(NeedLess) */ private final int SET_REQUEST_CODE_NEEDLESS = 123; /** * 必要權(quán)限授權(quán)界面返回 */ private final int NEEDFUL_PERMISSIONS_RESULT = 101; /** * 非必要權(quán)限授權(quán)界面返回 */ private final int NEEDLESS_PERMISSIONS_RESULT = 102;checkInitPermission這個(gè)方法里面主要 是必要權(quán)限集中驗(yàn)證比如應(yīng)用程序啟動(dòng)時(shí)調(diào)用 如loading界面
checkNeedlessPermission 而這個(gè)主要是非必要權(quán)限驗(yàn)證,比如? Manifest.permission.ACCESS_FINE_LOCATION
這兩個(gè)主要是利用接口回調(diào)進(jìn)行驗(yàn)證。
showPremissionDialog ?自定義的彈框
順便把這貼出來(lái),主要是得到
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; } 主要是讓大家去理解他,代碼 已測(cè)試可以用,除了自定義對(duì)話框大兄弟們得要自己定。
總結(jié)
以上是生活随笔為你收集整理的Android 6.0动态权限的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 百度地图定位城市
- 下一篇: 灼口综合征,部分人认为或与精神因素相关?