相信绝大部分的Android开发者对运行时权限都是很熟悉了的,毕竟运行时权限的用法并不难。但是每次申请权限都要重新编写重复的代码还是很费时间,因此我按照自己的风格对运行时权限进行了简单的封装,下面就把代码贴出来,希望和大家共同分享研究。
public class PermissionHelper {
private PermissionHelper() {
}
public static void requestPermissions(Activity activity, String[] permissions, int requestCode,
PermissionCallback callback) {
boolean isPermissionGranted;
boolean isAllGranted;
boolean doNotRequest = false;
List<String> permissionsRequestList = new ArrayList<String>();
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(activity, permission)
!= PackageManager.PERMISSION_GRANTED) {
permissionsRequestList.add(permission);
isPermissionGranted = false;
} else {
isPermissionGranted = true;
}
if (callback != null) {
doNotRequest = callback.onPermissionGrantedStates(permission, isPermissionGranted,
ActivityCompat.shouldShowRequestPermissionRationale(activity, permission));
}
}
if (permissionsRequestList.size() > 0) {
isAllGranted = false;
if (!doNotRequest) {
ActivityCompat.requestPermissions(activity,
permissionsRequestList.toArray(new String[permissionsRequestList.size()]),
requestCode);
}
} else {
isAllGranted = true;
}
if (callback != null) {
callback.onAllGranted(isAllGranted);
}
}
public static void onRequestPermissionsResult(Activity activity, String[] permissions,
int[] grantResults, PermissionCallback callback) {
boolean isPermissionGranted;
boolean isAllGranted = true;
if (grantResults != null && grantResults.length > 0) {
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
isPermissionGranted = true;
} else {
isAllGranted = false;
isPermissionGranted = false;
}
if (callback != null) {
callback.onPermissionGrantedStates(permissions[i], isPermissionGranted,
ActivityCompat.shouldShowRequestPermissionRationale(activity, permissions[i]));
}
}
if (callback != null) {
callback.onAllGranted(isAllGranted);
}
}
}
public interface PermissionCallback {
boolean onPermissionGrantedStates(String permission, boolean isGranted, boolean shouldShowRationale);
void onAllGranted(boolean isAllGranted);
}
}
我将功能封装成了两个静态方法:requestPermissions和onRequestPermissionsResult,分别用于请求权限和接收权限请求结果。
我们先通过两个例子来实践一下:
例子一:
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_CODE = 1000;
private static final String[] PERMISSION_NEEDED = {
Manifest.permission.CALL_PHONE};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
private void call() {
String number = "1234";
Intent intent = new Intent(Intent.ACTION_CALL);
Uri data = Uri.parse("tel:" + number);
intent.setData(data);
startActivity(intent);
}
public void onClick(View v) {
PermissionHelper.requestPermissions(this, PERMISSION_NEEDED, REQUEST_CODE,
new PermissionHelper.PermissionCallback() {
@Override
public boolean onPermissionGrantedStates(String permission, boolean isGranted,
boolean shouldShowRationale) {
if (permission.equals(Manifest.permission.CALL_PHONE)) {
if (isGranted) {
call();
} else if (shouldShowRationale) {
AlertDialog.Builder builder = new AlertDialog.Builder(
MainActivity.this);
builder.setTitle("获取权限原因")
.setMessage("需要此权限才能实现功能")
.setCancelable(false)
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(MainActivity.this,
PERMISSION_NEEDED, REQUEST_CODE);
}
}).create().show();
return true;
}
}
return false;
}
@Override
public void onAllGranted(boolean isAllGranted) {
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode,
final String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE:
PermissionHelper.onRequestPermissionsResult(this, permissions, grantResults,
new PermissionHelper.PermissionCallback() {
@Override
public boolean onPermissionGrantedStates(String permission,
boolean isGranted,
boolean shouldShowRationale) {
if (permission.equals(Manifest.permission.CALL_PHONE)) {
if (isGranted) {
call();
}
}
return false;
}
@Override
public void onAllGranted(boolean isAllGranted) {
}
});
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
break;
}
}
}
在例子一中,我申请了Manifest.permission.CALL_PHONE这个权限,当获取到这个权限时就拨打1234这个号码。
例子二:
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_CODE = 1000;
private static final String[] PERMISSION_NEEDED = {
Manifest.permission.READ_CONTACTS,
Manifest.permission.CALL_PHONE};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
private void call() {
String number = "1234";
Cursor cursor = getContentResolver().query(ContactsContract
.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
number = cursor.getString(cursor.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.NUMBER));
}
}
Intent intent = new Intent(Intent.ACTION_CALL);
Uri data = Uri.parse("tel:" + number);
intent.setData(data);
startActivity(intent);
}
public void onClick(View v) {
PermissionHelper.requestPermissions(this, PERMISSION_NEEDED, REQUEST_CODE,
new PermissionHelper.PermissionCallback() {
@Override
public boolean onPermissionGrantedStates(String permission, boolean isGranted,
boolean shouldShowRationale) {
return false;
}
@Override
public void onAllGranted(boolean isAllGranted) {
if (isAllGranted) {
call();
}
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode,
final String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE:
PermissionHelper.onRequestPermissionsResult(this, permissions, grantResults,
new PermissionHelper.PermissionCallback() {
@Override
public boolean onPermissionGrantedStates(String permission,
boolean isGranted,
boolean shouldShowRationale) {
return false;
}
@Override
public void onAllGranted(boolean isAllGranted) {
if (isAllGranted) {
call();
}
}
});
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
break;
}
}
}
在例子二中,我需要拨打通讯录中的第一个号码,所以需要Manifest.permission.CALL_PHONE和Manifest.permission.READ_CONTACTS权限,并且在这两个权限都获取到的时候才调用call方法。
代码都比较简单,我就不多做解释了,需要重点关注的就只有PermissionCallback这个内部接口。
requestPermissions和onRequestPermissionsResult都接收一个PermissionCallback,这个接口有两个方法需要实现,分别是onPermissionGrantedStates和onAllGranted。
onPermissionGrantedStates方法会传入对应权限的状态,包括权限是否已经获取,是否应该向用户展现获取权限的原因。我们可以在这个方法中根据参数做出相应的逻辑。同时注意到onPermissionGrantedStates方法会有一个返回值,当onPermissionGrantedStates是在requestPermissions方法中被调用,且返回true时,requestPermissions方法不会主动去申请权限,这点稍微看一下方法的实现就能明白。这么做的原因是为了更加灵活,比如我们需要向用户弹出一个Dialog展示获取权限的原因时,我们就不应该让requestPermissions方法去申请权限,因为这样会使得弹出框和Dialog重叠。
onAllGranted方法会在所有申请的权限对应的onPermissionGrantedStates方法执行完之后执行,我们可以根据该方法中的isAllGranted参数判断是否所有权限都已经获取到,并做出相应的逻辑处理。