一.前言
上一节中我们讨论了安卓运行时权限的基本API,和简单的使用方法。但是,在实际使用中,不能每次在需要授权时都写一堆代码,而且也有可能一次性要授予多个权限。这就需要对运行时权限的授权过程进行一个封装,本节就着重讨论这个问题。
二.设计思路
1.定义抽象类
考虑定义一个抽象类,让需要进行授权操作的Activity实现这个类。所以,我们首先定义一个抽象类AbstractPermissionActivity,令其继承AppCompatActivity类。
public abstract class AbstractPermissionActivity extends AppCompatActivity
{ @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
2.定义一个抽象回调函数接口,该函数在子类中实现,这样在子类中可以获取授权结果。
public abstract void requestPermissionResult(boolean requestResult);
3.定义一个检测是否需要进行授权的函数
有2种情况是不需要进行运行时授权的,一是,安卓系统版本小于6.0(SDK小于23);二是,所有请求的权限都已经被授权。
public boolean needRequestPermission(String[] permissions, AppCompatActivity activity)
{
/*如果是安卓6.0之前的版本,不需要授权*/
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return false;
}
for (String perm:permissions) {
//若存在没授权的权限,则需要授权,返回true
if(ContextCompat.checkSelfPermission(activity, perm) != PackageManager.PERMISSION_GRANTED)
{
return true;
}
}
return false;
}
4.定义一个提取未授权权限的函数
申请授权的权限数组中可能包含已经授权的权限,所以我们可以定义一个函数,将权限数组中未被授权的权限提取出来。该函数在申请函数前调用,避免重复申请。
private List<String> findDeniedPermissions(String[] permissions, AppCompatActivity activity) {
List<String> permissonList = new ArrayList<String>();
for (String perm : permissions) {
if (ContextCompat.checkSelfPermission(activity, perm) != PackageManager.PERMISSION_GRANTED) //检查权限授予情况
{
permissonList.add(perm);
}
}
return permissonList;
}
5.封装权限申请函数
在申请权限之前,调用函数4,将未被授权的权限提取出来,申请权限。
public boolean requestPermission(String[] permissions, AppCompatActivity activity) {
List<String> permissonList = findDeniedPermissions(permissions,activity);
if (null != permissonList && permissonList.size() > 0)
{
String[] needRequestPer = permissonList.toArray(new String[permissonList.size()]);
ActivityCompat.requestPermissions(activity, needRequestPer, REQUESTCODE);//申请权限
return true;
}
else
{
return false;
}
}
6.在申请结果回调函数中,调用上文的函数接口,将申请结果传入
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
{
if (requestCode ==REQUESTCODE) {
if (verify(grantResults)) {
requestPermissionResult(true);
}
else {
requestPermissionResult(false);
}
}
}
/*确认所有权限都被授予*/
private boolean verify(int[] grantResults) {
if (grantResults==null||grantResults.length<=0)
return false;
for (int result : grantResults) {
if (result != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
三.源代码
源代码已经传入github上,大家可以参考,多多指导和纠正不足。源代码