【Android 应用开发】动态权限管理示例 ( 使用原生代码实现 | 申请权限 | 判定权限申请结果 | 判定 “ 不再询问 “ 情况 )
文章目錄
- 一、申請權限
- 二、判定權限申請結果
- 三、判定 " 不再詢問 " 情況
- 四、完整代碼示例
- 1、權限管理代碼
- 2、主界面代碼
- 3、執行結果
- 五、博客資源
一、申請權限
首先 , 判定權限是否已經通過 , 如果沒有通過再進行申請 ;
如果下面函數返回值為 PackageManager.PERMISSION_GRANTED , 說明權限申請通過 ;
如果返回值為 PackageManager.PERMISSION_DENIED , 說明權限沒有被授予 ;
然后 , 申請沒有通過的權限 ;
第 222 個參數是 String 數組 , 內容是權限字符串 ;
完整過程 :
在 Build.VERSION_CODES.M , Android 6.0 ( API 23 ) 才啟用動態權限申請 ;
只要有 111 個權限沒有通過 , 就需要權限申請 ;
二、判定權限申請結果
在 Activity 的 onRequestPermissionsResult 回調方法中 , 可以獲取到權限是否授予 ;
@Overridepublic void onRequestPermissionsResult(int requestCode,@NonNull String[] permissions,@NonNull int[] grantResults) {}遍歷第 333 個參數 grantResults 數組 , 如果指定索引的元素為 ?1-1?1 , 說明 permissions 數組中指定的權限沒有授予通過 , 被用戶拒絕了 ;
如果 grantResults 數組中所有的值都為 000 , 說明所有權限授予通過 , 可以繼續執行后續操作 ;
代碼示例 :
public void onRequestPermissionsResult(int requestCode,@NonNull String[] permissions,@NonNull int[] grantResults) {if (REQUEST_CODE != requestCode) {return;}// 權限是否賦予完畢, 如果有任意一個沒有同意, 則判定權限申請失敗boolean allAgree = true;// 遍歷 grantResults 數組, 判定哪個權限被拒絕了for (int i = 0; i < grantResults.length; i++) {if (grantResults[i] == -1) {if (ActivityCompat.shouldShowRequestPermissionRationale(mActivity, permissions[i])) {// 被用戶拒絕了, 但是還可以申請, 說明沒有設置 "不再詢問" 選項} else {// 被用戶拒絕了, 不能彈出, 說明用戶設置了 "不再詢問" 選項showDialog();}allAgree = false;}}// 如果都同意, 則執行相關操作if (allAgree) {Toast.makeText(mActivity, "權限設置完畢, 執行相關操作", Toast.LENGTH_LONG).show();}}三、判定 " 不再詢問 " 情況
使用 ActivityCompat.shouldShowRequestPermissionRationale 方法判定用戶是否選擇了 " 不再詢問 " 選項 ;
ActivityCompat.shouldShowRequestPermissionRationale(mActivity, 權限字符串) ;shouldShowRequestPermissionRationale 方法的含義是當前是否 提示用戶進行權限申請 , 指的是顯示給用戶申請權限的理由 ;
是否顯示申請權限的原理 , 也就是 顯示給用戶 " 為什么應用需要你授予這個權限 " , 要想方設法勸用戶授予這個權限 , 以及說明不授予權限不能使用的哪些功能 ;
如果該方法 返回 true , 則顯示 ; 如果該方法返回 false , 則不顯示 ;
分為四種情況 :
① 首次申請 : 由于是第 111 次申請權限 , 直接申請即可 , 不需要給用戶顯示申請權限的理由 , 返回 false ;
② 用戶拒絕了申請 : 如果用戶拒絕了權限的申請 , 開發者需要給用戶顯示 " 為什么申請該權限 , 要使用權限做那些事 " , 因此需要給用戶提示 , 返回 true ;
③ 用戶拒絕申請并選擇 " 不再詢問 " : 用戶已經明確拒絕 , 就不要再騷擾用戶了 , 不用給出進一步的提示信息 , 返回 false ;
④ 用戶同意權限申請 : 用戶已經同意了 , 也不用給用戶進行原理提示 , 返回 false ;
Google 的意思是如果用戶選擇了 " 不再詢問 " , 那開發者就不能在提及與該權限相關的事了 ;
但是我們開發時總想把用戶引導到權限設置界面 , 讓用戶自己設置 , 因此這里就有了這個 " 不再詢問 " 判定問題 ;
有點反直覺 ;
判定 " 不再詢問 " 情況 :
在 Activity 的 onRequestPermissionsResult 方法中 ,
public void onRequestPermissionsResult(int requestCode,@NonNull String[] permissions,@NonNull int[] grantResults) {判定 grantResults 數組 , 查看用戶是否拒絕該權限 ;
在用戶拒絕權限的前提下 , 如果
ActivityCompat.shouldShowRequestPermissionRationale(mActivity, 權限字符串)方法返回 false , 此時就是用戶點擊了 " 不再詢問 " 選項 ;
只能在上述情況下判定 , 其它情況都判定不了 ;
四、完整代碼示例
1、權限管理代碼
權限管理代碼 :
package com.example.permission;import android.Manifest; import android.app.Activity; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; import android.provider.Settings; import android.widget.Toast;import androidx.annotation.NonNull; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat;public class PermissionManager {/*** 申請權限的 Activity 界面*/private Activity mActivity;/*** "不再詢問" 后的引導對話框*/private AlertDialog mAlertDialog;/*** 申請權限的請求碼, 要求必須 >0*/public final int REQUEST_CODE = 100;/*** 需要申請的權限*/protected String[] mRequestPermissions = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE};public PermissionManager(Activity activity) {this.mActivity = activity;}/*** 請求動態權限** @return*/public boolean requestPermission() {// Android 6.0 ( API 23 ) 才啟用動態權限申請if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {// 用戶是否不同意權限, 只要有 1 個不同意, 則為 true, 默認 falseboolean isDisagree = false;// 判定是否有權限未獲取for (int i = 0; i < mRequestPermissions.length; i++) {if (ContextCompat.checkSelfPermission(mActivity,mRequestPermissions[i]) != PackageManager.PERMISSION_GRANTED) {isDisagree = true;}}if (isDisagree) {// 存在權限沒有通過,需要申請ActivityCompat.requestPermissions(mActivity, mRequestPermissions, REQUEST_CODE);return false;} else {// 所有權限都已同意return true;}} else {// 6.0 以下默認有動態權限return true;}}public void onRequestPermissionsResult(int requestCode,@NonNull String[] permissions,@NonNull int[] grantResults) {if (REQUEST_CODE != requestCode) {return;}// 權限是否賦予完畢, 如果有任意一個沒有同意, 則判定權限申請失敗boolean allAgree = true;// 遍歷 grantResults 數組, 判定哪個權限被拒絕了for (int i = 0; i < grantResults.length; i++) {if (grantResults[i] == -1) {if (ActivityCompat.shouldShowRequestPermissionRationale(mActivity, permissions[i])) {// 被用戶拒絕了, 但是還可以申請, 說明沒有設置 "不再詢問" 選項} else {// 被用戶拒絕了, 不能彈出, 說明用戶設置了 "不再詢問" 選項showDialog();}allAgree = false;}}// 如果都同意, 則執行相關操作if (allAgree) {Toast.makeText(mActivity, "權限設置完畢, 執行相關操作", Toast.LENGTH_LONG).show();}}/*** 用戶選擇 "不再詢問" 后的提示方案*/protected void showDialog() {// 不管同意/拒絕 , 只彈出一次if (mAlertDialog != null){return;}mAlertDialog = new AlertDialog.Builder(mActivity).setMessage("手動設置權限").setPositiveButton("設置", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {// 跳轉到設置界面Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,Uri.parse("package:com.example.permission"));mActivity.startActivity(intent);mAlertDialog.cancel();}}).setNegativeButton("取消", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {mAlertDialog.cancel();}}).create();mAlertDialog.show();} }2、主界面代碼
package com.example.permission;import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle; import android.view.View;import com.example.permission.databinding.ActivityMainBinding;public class MainActivity extends AppCompatActivity {/*** 權限管理*/private PermissionManager mPermissionManager;/*** 視圖綁定*/private ActivityMainBinding binding;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);binding = ActivityMainBinding.inflate(getLayoutInflater());setContentView(binding.getRoot());binding.button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mPermissionManager = new PermissionManager(MainActivity.this);mPermissionManager.requestPermission();}});}@Overridepublic void onRequestPermissionsResult(int requestCode,@NonNull String[] permissions,@NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);mPermissionManager.onRequestPermissionsResult(requestCode,permissions, grantResults);} }
3、執行結果
五、博客資源
博客源碼 :
- GitHub : https://github.com/han1202012/PermissionManager
總結
以上是生活随笔為你收集整理的【Android 应用开发】动态权限管理示例 ( 使用原生代码实现 | 申请权限 | 判定权限申请结果 | 判定 “ 不再询问 “ 情况 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【OkHttp】OkHttp Get 和
- 下一篇: 【OkHttp】OkHttp 上传图片