Android權(quán)限如何禁止以及友好提示用戶開通必要權(quán)限詳解
Android權(quán)限
Android安全架構(gòu)規(guī)定:默認情況下,任何應(yīng)用都沒有權(quán)限執(zhí)行對其他應(yīng)用、操作系統(tǒng)或用戶有不利影響的任何操作。這包括讀寫用戶的私有數(shù)據(jù)(聯(lián)系人,短信,相冊,位置)、讀寫其他應(yīng)用的文件、執(zhí)行網(wǎng)絡(luò)訪問、使設(shè)備保持喚醒狀態(tài)等等。
如果是一些正常的權(quán)限(非高危權(quán)限),比如網(wǎng)絡(luò)訪問等在應(yīng)用清單文件(AndroidManifest.xml)中配置,系統(tǒng)會自動授予,
但是如果有一些高危權(quán)限,位置,文件存儲,短信等這個時候系統(tǒng)會要求用戶授予權(quán)限,Android 發(fā)出權(quán)限請求的方式取決于系統(tǒng)版本:
1、如果設(shè)備運行的是Android 6.0(Marshmallow,API 23)或更高版本,并且應(yīng)用的targetSdkVersion是23或更高版本,則應(yīng)用將在運行時向用戶請求權(quán)限(Runtime Permissions)。用戶可隨時撤銷權(quán)限,因此應(yīng)用每次運行時都應(yīng)該檢查自身是否具備所需的權(quán)限。
2、如果設(shè)備運行的是Android 5.1(LOLLIPOP_MR1,API 22)或更低版本,并且應(yīng)用的targetSdkVersion是22或更低版本,則系統(tǒng)在用戶安裝應(yīng)用時就要求用戶授予權(quán)限。如果更新應(yīng)用時又新增了權(quán)限,系統(tǒng)會在用戶更新應(yīng)用時要求授予該權(quán)限。用戶一旦安裝應(yīng)用,他們撤銷權(quán)限的唯一方式是卸載應(yīng)用。
如果我們程序中某些功能,發(fā)布一些圖片等操作,這個時候避免不了要訪問用戶設(shè)備的圖片,但是用戶開始的時候禁止了,用戶并不知道,這個時候訪問就會有問題了,那么怎樣去提示用戶并且引導(dǎo)用戶去授予這些權(quán)限呢,看下面的效果(說的再多都不如圖來的實際)
下面就開始擼碼了
private void getpermission() { //兩個日歷權(quán)限和一個數(shù)據(jù)讀寫權(quán)限 String[] permissions = new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.READ_PHONE_STATE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA}; // PermissionsUtils.showSystemSetting = true;//是否支持顯示系統(tǒng)設(shè)置權(quán)限設(shè)置窗口跳轉(zhuǎn) //這里的this不是上下文,是Activity對象! PermissionsUtils.getInstance().chekPermissions(this, permissions, permissionsResult); }
首先在頁面Activity啟動之后調(diào)用這個方法(注意:數(shù)組中的權(quán)限可以自己配置,這里我寫了四個)
權(quán)限監(jiān)聽接口對象
//創(chuàng)建監(jiān)聽權(quán)限的接口對象 PermissionsUtils.IPermissionsResult permissionsResult = new PermissionsUtils.IPermissionsResult() { @Override public void passPermissons() { //權(quán)限通過執(zhí)行的方法 //權(quán)限通過驗證 } @Override public void forbitPermissons() { //這是沒有通過權(quán)限的時候提示的內(nèi)容,自定義即可 Toast.makeText(mContext, "您沒有允許部分權(quán)限,可能會導(dǎo)致部分功能不能正常使用,如需正常使用 請允許權(quán)限", Toast.LENGTH_SHORT).show(); finish(); // Tool.exitApp(); } };
還需要在activity中重寫一個方法
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); //就多一個參數(shù)this PermissionsUtils.getInstance().onRequestPermissionsResult(this, requestCode, permissions, grantResults); }
權(quán)限以及彈窗設(shè)置權(quán)限工具類PermissionsUtils.java
/** * 權(quán)限工具類 */ public class PermissionsUtils { private final int mRequestCode = 100;//權(quán)限請求碼 public static boolean showSystemSetting = true; private PermissionsUtils() { } private static PermissionsUtils permissionsUtils; private IPermissionsResult mPermissionsResult; public static PermissionsUtils getInstance() { if (permissionsUtils == null) { permissionsUtils = new PermissionsUtils(); } return permissionsUtils; } public void chekPermissions(Activity context, String[] permissions, @NonNull IPermissionsResult permissionsResult) { mPermissionsResult = permissionsResult; if (Build.VERSION.SDK_INT < 23) { //6.0才用動態(tài)權(quán)限 permissionsResult.passPermissons(); return; } //創(chuàng)建一個mPermissionList,逐個判斷哪些權(quán)限未授予,未授予的權(quán)限存儲到mPerrrmissionList中 List<String> mPermissionList = new ArrayList<>(); //逐個判斷你要的權(quán)限是否已經(jīng)通過 for (int i = 0; i < permissions.length; i++) { if (ContextCompat.checkSelfPermission(context, permissions[i]) != PackageManager.PERMISSION_GRANTED) { mPermissionList.add(permissions[i]);//添加還未授予的權(quán)限 } } //申請權(quán)限 if (mPermissionList.size() > 0) {//有權(quán)限沒有通過,需要申請 ActivityCompat.requestPermissions(context, permissions, mRequestCode); } else { //說明權(quán)限都已經(jīng)通過,可以做你想做的事情去 permissionsResult.passPermissons(); return; } } //請求權(quán)限后回調(diào)的方法 //參數(shù): requestCode 是我們自己定義的權(quán)限請求碼 // 參數(shù): permissions 是我們請求的權(quán)限名稱數(shù)組 // 參數(shù): grantResults 是我們在彈出頁面后是否允許權(quán)限的標(biāo)識數(shù)組,數(shù)組的長度對應(yīng)的是權(quán)限名稱數(shù)組的長度,數(shù)組的數(shù)據(jù)0表示允許權(quán)限,-1表示我們點擊了禁止權(quán)限 public void onRequestPermissionsResult(Activity context, int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { boolean hasPermissionDismiss = false; //有權(quán)限沒有通過 if (mRequestCode == requestCode) { for (int i = 0; i < grantResults.length; i++) { if (grantResults[i] == -1) { hasPermissionDismiss = true; } } //如果有權(quán)限沒有被允許 if (hasPermissionDismiss) { if (showSystemSetting) { showSystemPermissionsSettingDialog(context);//跳轉(zhuǎn)到系統(tǒng)設(shè)置權(quán)限頁面,或者直接關(guān)閉頁面,不讓他繼續(xù)訪問 } else { mPermissionsResult.forbitPermissons(); } } else { //全部權(quán)限通過,可以進行下一步操作。。。 mPermissionsResult.passPermissons(); } } } /** * 不再提示權(quán)限時的展示對話框 */ AlertDialog mPermissionDialog; private void showSystemPermissionsSettingDialog(final Activity context) { final String mPackName = context.getPackageName(); if (mPermissionDialog == null) { mPermissionDialog = new AlertDialog.Builder(context).setMessage("已禁用權(quán)限,請手動授予").setPositiveButton("設(shè)置", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { cancelPermissionDialog(); Uri packageURI = Uri.parse("package:" + mPackName); Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, packageURI); context.startActivity(intent); context.finish(); } }).setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //關(guān)閉頁面或者做其他操作 cancelPermissionDialog(); //mContext.finish(); mPermissionsResult.forbitPermissons(); } }).create(); } mPermissionDialog.show(); //放在show()之后,不然有些屬性是沒有效果的,比如height和width //以下代碼設(shè)置解決彈窗不居中問題,一側(cè)有邊距,一側(cè)沒有 Window dialogWindow = mPermissionDialog.getWindow(); WindowManager m = context.getWindowManager(); Display d = m.getDefaultDisplay(); // 獲取屏幕寬、高 WindowManager.LayoutParams p = dialogWindow.getAttributes(); // 獲取對話框當(dāng)前的參數(shù)值 // 設(shè)置寬度 p.width = (int) (d.getWidth() * 0.95); // 寬度設(shè)置為屏幕的0.95 p.gravity = Gravity.CENTER;//設(shè)置位置 //p.alpha = 0.8f;//設(shè)置透明度 dialogWindow.setAttributes(p); } //關(guān)閉對話框 private void cancelPermissionDialog() { if (mPermissionDialog != null) { mPermissionDialog.cancel(); mPermissionDialog = null; } } public interface IPermissionsResult { void passPermissons(); void forbitPermissons(); } }
以上這些代碼就可以實現(xiàn)gif圖的效果,當(dāng)然可以自定義任意效果
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對腳本之家的支持。
- android10 隱藏SystemUI鎖屏下的多用戶圖標(biāo)的示例代碼
- Android 如何攔截用戶頻繁操作(點擊事件)
- Android實現(xiàn)用戶圓形頭像和模糊背景
- Android實現(xiàn)簡單用戶注冊案例
- Android啟動頁用戶相關(guān)政策彈框的實現(xiàn)代碼
- 詳解Android Studio實現(xiàn)用戶登陸界面demo(xml實現(xiàn))
- android實現(xiàn)記住用戶名和密碼以及自動登錄
- Android百度地圖定位、顯示用戶當(dāng)前位置
- Android模擬用戶點擊的實現(xiàn)方法
- Android EditText 監(jiān)聽用戶輸入完成的實例
- Android 用戶Session管理的設(shè)計方案
- Android基于AlarmManager實現(xiàn)用戶在線心跳功能示例
- Android 多用戶詳情
相關(guān)文章
完美實現(xiàn)ExpandableListView二級分欄效果
這篇文章主要為大家詳細介紹了ExpandableListView實現(xiàn)二級分欄效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-11-11Android 實現(xiàn)獲取手機里面的所有圖片詳解及實例
這篇文章主要介紹了Android 實現(xiàn)獲取手機里面的所有圖片詳解及實例的相關(guān)資料,需要的朋友可以參考下2017-05-05React Native中Android物理back鍵按兩次返回鍵即退出應(yīng)用
這篇文章主要給大家介紹了關(guān)于React Native中Android物理back鍵按兩次返回鍵即退出應(yīng)用的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-10-10