android 執行時許可權工具
阿新 • • 發佈:2019-02-08
申請許可權
一個許可權
AndPermission.with(this) .requestCode(100) .permission(Manifest.permission.WRITE_CONTACTS) .send();
多個許可權
AndPermission.with(this) .requestCode(100) .permission(Manifest.permission.WRITE_CONTACTS, Manifest.permission.READ_SMS) .send();
在使用到特殊許可權時,只需要在Activity
Fragment
中直接呼叫,等到AndPermission
回撥時即可執行相應的程式碼。
注意
1. 如果你的Activity
繼承的是AppCompatActivity
、FragmentActivity
或者它們的子類,那麼你直接請求許可權就可以。
2. 如果你的Fragment
繼承的是android.support.v4.app.Fragment
或者它的子類,那麼你直接請求許可權就可以。
3. 如果你繼承的是android.app.Activity
、android.app.Fragment
、在6.0以下的手機是沒有onRequestPermissionsResult()
方法的,所以需要在申請許可權前判斷:
// 先判斷是否有許可權。 if(AndPermission.hasPermission(this, Manifest.permission.READ_SMS)) { // 有許可權,直接do anything. } else { // 申請許可權。 AndPermission.with(this) .requestCode(100) .permission(Manifest.permission.WRITE_CONTACTS, Manifest.permission.READ_SMS) .send(); }
回撥結果
方式一:利用Listener方式回撥
@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { // 只需要呼叫這一句,其它的交給AndPermission吧,最後一個引數是PermissionListener。 AndPermission.onRequestPermissionsResult(requestCode, permissions, grantResults, listener); } private PermissionListener listener = new PermissionListener() { @Override public void onSucceed(int requestCode, List<String> grantedPermissions) { // 許可權申請成功回撥。 if(requeust == 100) { // TODO 相應程式碼。 } else if(requestCode == 101) { // TODO 相應程式碼。 } } @Override public void onFailed(int requestCode, List<String> deniedPermissions) { // 許可權申請失敗回撥。 // 使用者否勾選了不再提示並且拒絕了許可權,那麼提示使用者到設定中授權。 if (AndPermission.hasAlwaysDeniedPermission(this, deniedPermissions)) { // 第一種:用預設的提示語。 AndPermission.defaultSettingDialog(this, REQUEST_CODE_SETTING).show(); // 第二種:用自定義的提示語。 // AndPermission.defaultSettingDialog(this, REQUEST_CODE_SETTING) // .setTitle("許可權申請失敗") // .setMessage("我們需要的一些許可權被您拒絕或者系統發生錯誤申請失敗,請您到設定頁面手動授權,否則功能無法正常使用!") // .setPositiveButton("好,去設定") // .show(); // 第三種:自定義dialog樣式。 // SettingService settingService = // AndPermission.defineSettingDialog(this, REQUEST_CODE_SETTING); // 你的dialog點選了確定呼叫: // settingService.execute(); // 你的dialog點選了取消呼叫: // settingService.cancel(); } } };
方式二:利用註解回撥 只需要重寫Activity/Fragment的一個方法,然後提供一個授權時回撥的方法即可:
@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { // 只需要呼叫這一句,第一個引數是當前Acitivity/Fragment,回撥方法寫在當前Activity/Framgent。 AndPermission.onRequestPermissionsResult(this, requestCode, permissions, grantResults); } // 成功回撥的方法,用註解即可,裡面的數字是請求時的requestCode。 @PermissionYes(100) private void getLocationYes(List<String> grantedPermissions) { // TODO 申請許可權成功。 } // 失敗回撥的方法,用註解即可,裡面的數字是請求時的requestCode。 @PermissionNo(100) private void getLocationNo(List<String> deniedPermissions) { // 使用者否勾選了不再提示並且拒絕了許可權,那麼提示使用者到設定中授權。 if (AndPermission.hasAlwaysDeniedPermission(this, deniedPermissions)) { // 第一種:用預設的提示語。 AndPermission.defaultSettingDialog(this, REQUEST_CODE_SETTING).show(); } }
如果你會用了,你就可以大刀闊斧的幹了,部落格中講到的各種複雜邏輯,AndPermission自動完成。
Rationale拒絕一次後,再次提示使用者許可權作用
方式一:使用AndPermssion預設MD風格對話方塊
AndPermission.with(this) .requestCode(REQUEST_CODE_PERMISSION_LOCATION) .permission(Manifest.permission.ACCESS_FINE_LOCATION) .rationale((requestCode, rationale) -> // 此對話方塊可以自定義,呼叫rationale.resume()就可以繼續申請。 AndPermission.rationaleDialog(PermissionActivity.this, rationale).show() ) .send()
方式二:自定義對話方塊
AndPermission.with(this) .requestCode(REQUEST_CODE_PERMISSION_LOCATION) .permission(Manifest.permission.ACCESS_FINE_LOCATION) .rationale(rationaleListener) .send() /** * Rationale支援,這裡自定義對話方塊。 */ private RationaleListener rationaleListener = (requestCode, rationale) -> { AlertDialog.build(this) .setTitle("友好提醒") .setMessage("您已拒絕過定位許可權,沒有定位許可權無法為您推薦附近妹子,請把定位許可權賜給我吧!") .setPositiveButton("好,給你", (dialog, which) -> { rationale.resume(); }) .setNegativeButton("我拒絕", (dialog, which) -> { rationale.cancel(); }).show(); };
混淆
1. 如果使用Listener接受回撥結果,不用任何配置。
2. 使用註解的方式回撥結果,在proguard-rules.pro中新增如下配置
-keepclassmembers class ** {
@com.yanzhenjie.permission.PermissionYes <methods>;
}
-keepclassmembers class ** {
@com.yanzhenjie.permission.PermissionNo <methods>;
}