利用PermissionsDispatcher解决运行时权限异常

安卓6.0以后申请部分权限需要在应用程序中提醒用户去开通,这些需要运行时申请的权限都是影响到用户信息安全的,6.0之前只要在AndroidManifest注册即可,6.0以后必须先申请,因此增加了安全性,但是给开发人员带来了麻烦。因此从网上找到了一个第三方库PermissionsDispatcher很容易处理运行时的异常。

PermissionsDispatcher 

github地址:https://github.com/hotchemi/PermissionsDispatcher

说明文档:https://hotchemi.github.io/PermissionsDispatcher/

它以依赖注入的方式进行运行时异常的操作,我们以READ_CONTACTS读取通讯录权限为例,简要说明下调用过程。

1.首先还是得需要在AndriodManifest文件中注册READ_CONTACTS权限。

 

<uses-permission android:name="android.permission.READ_CONTACTS"/>

 

 

2.给相应方法提供注解

我们先来了解下PermissionsDispatcher都有哪些注解

@RuntimePermissions:注册一个Activity或者Fragment处理权限。

@NeedsPermission:注解一个方法,可以用来申请一个或者多个权限,当权限全都通过的时候,进行回调。

@OnShowRationale:注解一个方法,用来解释用户为什么需要这个权限,用PermissionRequest 来决定是继续,不做任何处理,还是去申请权限。

                                request.proceed() 代表用户同意开通此权限,request.cancel() 代表不做任何处理。(一般该方式是写一个AlertDialog,提醒用户是否开通权限)

当用户没有开通权限的时候调用此方法。

@OnPermissionDenied:用户禁止了权限时,调用此方法。

@OnNeverAskAgain:用户点击了申请权限框中的“never ask again”回调此方法。

注意:被注解的方法不能被private修饰。

 

@RuntimePermissions
public class AuthContactActivity extends AppCompatActivity {
    @NeedsPermission(Manifest.permission.READ_CONTACTS)
    void checkContactPermission(){
        MyLogger.i(TAG,"checkContactPermission");
        Uri uri = ContactsContract.Contacts.CONTENT_URI;
        Intent intent = new Intent(Intent.ACTION_PICK, uri);
        activity.startActivityForResult(intent, requestCode);
    }
	
    @OnShowRationale(Manifest.permission.READ_CONTACTS)
    void showRationaleForContact(final PermissionRequest request) {
        if (mAlertDialog==null) {
            mAlertDialog = new AlertDialog.Builder(this)
                    .setMessage(BaseUtils.getStringByResouceId(R.string.auth_contact_permission_remind))
                    .setPositiveButton(R.string.auth_contact_permission_open, (dialog, button) -> request.proceed())
                    .setNegativeButton(R.string.auth_contact_permission_cancel, (dialog, button) -> request.cancel())
                    .create();            
        mAlertDialog.setCancelable(false);
       mAlertDialog.setCanceledOnTouchOutside(false);
        }
        mAlertDialog.show();
    }
    @OnPermissionDenied(Manifest.permission.READ_CONTACTS)
    void showDeniedForContact() {
        MyLogger.i(TAG,"READ_CONTACTS Denied");
    }
	
    @OnNeverAskAgain(Manifest.permission.READ_CONTACTS)       
    void showNeverAskForContact() {
        MyLogger.i(TAG,"READ_CONTACTS NeverAskFor");
        if (notAskDialog==null) {
            notAskDialog = new AlertDialog.Builder(this)
                    .setMessage(BaseUtils.getStringByResouceId(R.string.auth_contact_permission_not_ask))
                    .setPositiveButton(R.string.auth_contact_permission_do_open, (dialog, button) -> "跳转到系统权限管理界面或者其他")
                    .setNegativeButton(R.string.auth_contact_permission_cancel, (dialog, button) -> notAskDialog.dismiss())
                    .create();
	    notAskDialog.setCancelable(false);
        notAskDialog.setCanceledOnTouchOutside(false);
        }
        notAskDialog.show();
    }
	

	    notAskDialog.setCancelable(false);
        notAskDialog.setCanceledOnTouchOutside(false);
        }
        notAskDialog.show();
    }
	

 

 

 

3.委托生成一个帮助类

 

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);
	findViewById(R.id.button_contact).setOnClickListener(v -> {
		AuthContactActivityPermissionsDispatcher.checkContactPermissionWithCheck(this);
	});
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        AuthContactActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);
}	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);
	findViewById(R.id.button_contact).setOnClickListener(v -> {
		AuthContactActivityPermissionsDispatcher.checkContactPermissionWithPermissionCheck(this);
	});
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        AuthContactActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);
}


注解方法都已完成,需要根据需求调用他们,这里是当用户点击按钮时候判断是否开通了读取通讯录权限。

 

调用方法是[被@RuntimePermissions注释的Activity] + PermissionsDispatcher.[被@NeedsPermission注释的方法名称]+WithPermissionCheck(Context)

例如:AuthContactActivityPermissionsDispatcher.checkContactPermissionWithCheck(this)

用户选择完系统权限框的选项后,将结果回传给onRequestPermissionsResult,这里也用到了[被@RuntimePermissions注释的Activity] + PermissionsDispatcher的onRequestPermissionsResult方法。
 

本案例调用过程为:

用户点击按钮,调用xxxWithCheck方法

     如果此应用通过了权限,那么直接执行checkContactPermission方法;

     如果用户没有通过此权限,弹框提示是否开通此权限

          用户点击“开通”:调用 PermissionRequest的proceed方法,默认是调用系统的申请权限提示框(具体的实现可以看源码)

               系统提示框点击“始终允许”执行 checkContactPermission方法 

               系统提示框点击“禁止”执行 showDeniedForContact方法

               系统提示框点击“禁止后不再询问”执行 showNeverAskForContact方法

                (这里在showNeverAskForContact方法中设置了继续弹出一个弹框提示用户去系统权限界面设置)

         用户点击“取消”:调用 PermissionRequest的cancel方法,默认调用showDeniedForContact方法

 

 

附:危险权限组和权限

 



 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值