出于问题中所述的原因,我不想使用任何可用的库,因此我自己开发了一些东西。
我所有需要一个或多个权限的活动都继承自一个处理所有权限相关任务的PermissionActivity
。
它的工作原理是您的活动调用
if (checkHasPermission(Manifest.permission.ACCESS_FINE_LOCATION)) { }
从父类继承。如果权限已经被授予,代码可以继续执行。如果没有被授予,父类将使用一个抽象方法和/或一个或多个可重写的方法请求权限并将结果发送给子类。
父类
除了messageForRationale()
和requestCodeForPermission()
中的switch块以外,可以保留此类的原样。请根据您的应用程序需要更新这些内容的权限。
public abstract class PermissionActivity extends AppCompatActivity {
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == RequestCode.PERMISSION_MULTIPLE) {
boolean allPermissionsGranted = true;
for (int grantResult : grantResults) {
if (grantResult != PackageManager.PERMISSION_GRANTED) {
allPermissionsGranted = false;
}
}
if (allPermissionsGranted) {
onAllPermissionsGranted(permissions);
return;
}
}
for (int i = 0; i < permissions.length; i++) {
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
onPermissionGranted(permissions[i]);
} else {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[i])) {
onPermissionDenied(permissions[i]);
} else {
onPermissionBlocked(permissions[i]);
}
}
}
}
public boolean checkHasPermission(int requestCode, String... permissions) {
if (!(permissions.length > 0)) {
throw new IllegalArgumentException("must request at least one permission");
}
if (requestCode == RequestCode.PERMISSION_MULTIPLE) {
List<String> permissions_ = new ArrayList<>();
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(this, permission) !=
PackageManager.PERMISSION_GRANTED) {
permissions_.add(permission);
}
}
if (!permissions_.isEmpty()) {
requestPermissions(this, permissions_.toArray(new String[permissions_.size()]), requestCode);
return false;
} else {
return true;
}
} else {
if (ActivityCompat.checkSelfPermission(this, permissions[0]) !=
PackageManager.PERMISSION_GRANTED) {
requestPermissions(this, permissions, requestCode);
return false;
} else {
return true;
}
}
}
private void requestPermissions(Activity activity, String permissions[], int resultCode) {
showRequestPermissionsDialog(activity, permissions, resultCode);
}
public void showRationaleDialog(Activity activity, String permission, String message,
int resultCode) {
new AlertDialog.Builder(activity)
.setMessage(message)
.setPositiveButton("ok", (dialog, which) ->
showRequestPermissionDialog(activity, permission, resultCode))
.setNegativeButton("not now", (dialog, which) -> { })
.show();
}
private void showRequestPermissionDialog(Activity activity, String permission, int resultCode) {
ActivityCompat.requestPermissions(activity, new String[]{permission}, resultCode);
}
private void showRequestPermissionsDialog(Activity activity, String[] permissions,
int resultCode) {
ActivityCompat.requestPermissions(activity, permissions, resultCode);
}
public String messageForRationale(String permission) {
String s;
switch (permission) {
case Manifest.permission.READ_PHONE_STATE:
s = "access this device's state";
break;
case Manifest.permission.ACCESS_FINE_LOCATION:
s = "access the location of this device";
break;
case Manifest.permission.SEND_SMS:
s = "send text messages";
break;
default:
throw new IllegalArgumentException("Permission not handled: " + permission);
}
return String.format("MyApp needs permission to %s.", s);
}
public int requestCodeForPermission(String permission) {
int code;
switch (permission) {
case Manifest.permission.READ_PHONE_STATE:
code = RequestCode.PERMISSION_READ_PHONE_STATE;
break;
case Manifest.permission.ACCESS_FINE_LOCATION:
code = RequestCode.PERMISSION_FINE_LOCATION;
break;
case Manifest.permission.SEND_SMS:
code = RequestCode.PERMISSION_SEND_SMS;
break;
default:
throw new IllegalArgumentException("Permission not handled: " + permission);
}
return code;
}
protected void onAllPermissionsGranted(String[] permissions) {
}
protected void onPermissionGranted(String permission) {
}
protected void onPermissionDenied(String permission) {
String message = messageForRationale(permission);
showRationaleDialog(this, permission, message, requestCodeForPermission(permission));
}
protected abstract void onPermissionBlocked(String permission);
}
->
符号是 Lambda 表达式。
RequestCode 是一个接口,专门用于抽象化数字。
public interface RequestCode {
int PERMISSION_READ_PHONE_STATE = 0;
int PERMISSION_FINE_LOCATION = 1;
int PERMISSION_SEND_SMS = 2;
int PERMISSION_MULTIPLE = 3;
}
您可以根据需要进行更改。不要使用超过256的数字,否则会抛出异常,提示:
请求代码只能使用低8位。
在需要权限的活动中,您可以像这样使用它(仅作为示例)。确保活动扩展PermissionActivity
。
private void callThisSomewhere() {
if (checkHasPermission(RequestCode.PERMISSION_READ_PHONE_STATE,
Manifest.permission.READ_PHONE_STATE)) {
tryDoStuffWithPhoneState();
}
}
@RequiresPermission(Manifest.permission.READ_PHONE_STATE)
private void doStuffWithPhoneState() {
}
@Override
public void onPermissionGranted(String permission) {
tryDoStuffWithPhoneState();
}
@Override
public void onPermissionBlocked(String permission) {
}
如果您一次请求多个权限,应使用RequestCode.PERMISSION_MULTIPLE
。否则,只会请求第一个权限。
未在AndroidManifest.xml中列出的权限将自动被阻止,而不显示给用户对话框,因此请确保在清单中添加您需要请求的任何权限。
限制
此解决方案不与片段或服务兼容。