您不应该在 AsyncTask 中请求权限。事实上,您甚至不应该检索 deviceId 或其中的某些信息 - 将其作为参数传递。
每个应用程序的设置都有“危险”权限列表及其状态。如果您的应用程序以 sdk 23 为目标,则默认情况下它们都被禁用。因此,当您使用需要此类权限的代码时,您需要检查它是否被授予,如果没有 - 请求它。
最简单的方法是为这样的权限创建实用程序类:
public final class PermissionUtils {
private PermissionUtils() {
}
public static boolean checkPermissions(Context context, String... permissions) {
for (String permission : permissions) {
if (!checkPermission(context, permission)) {
return false;
}
}
return true;
}
public static boolean checkPermission(Context context, String permission) {
return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED;
}
public static boolean isDeviceInfoGranted(Context context) {
return checkPermission(context, Manifest.permission.READ_PHONE_STATE);
}
public static void requestPermissions(Object o, int permissionId, String... permissions) {
if (o instanceof Fragment) {
FragmentCompat.requestPermissions((Fragment) o, permissions, permissionId);
} else if (o instanceof Activity) {
ActivityCompat.requestPermissions((AppCompatActivity) o, permissions, permissionId);
}
}
}
然后像这样使用它:
(在您的片段/活动中)
if (PermissionUtils.isDeviceInfoGranted(this)) {
//get deviceId and proccess your code
} else {
String[] permissions = new String[]{READ_PHONE_STATE};
PermissionUtils.requestPermissions(this, PHONE_STATE_PERMISSION_ID, permissions);
}
在您的 AppCompatActivity 中覆盖权限结果的处理程序或实现 OnRequestPermissionsResultCallback 接口:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case PHONE_STATE_PERMISSION_ID:
boolean granted = grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED;
if (granted) {
//get deviceId and proccess your code
} else {
//nobody knows what to do
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
如您所见,我们还有一个问题 - 如果用户拒绝许可,该怎么办?作为一个变体,我们可以显示解释对话框。或者(可能更好)仅在入职屏幕后请求权限。