如何在 Android 6 中请求用户权限
How to ask for user permissions in Android 6
我对 Android 6 (Marshmallow) 中的新权限系统感到非常困惑。
我正在使用两个所谓的 'dangeorus permissions' -
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
而且我在很多地方都使用了这些权限。
我需要访问用户帐户以注册应用程序、发送反馈 etc.And我还需要访问设备 ID 以注册应用程序。
我在 Java Class 命名的 util 中编写了两个函数来获取邮件帐户列表和设备 ID,并在 AsyncTask 和片段中使用这些函数。
现在,我完全不知所措,如何申请这些权限!我应该在功能中询问还是每次调用这些功能时询问?在 AsyncTask 中,我怎样才能得到响应?
请帮忙。
首先,您必须在 activity/fragment 中实现以下方法:
@Override
public void onRequestPermissionsResult(int requestCode,@NonNull String permissions[], @NonNull int[] grantResults) {
switch (requestCode) {
case Permissions.READ_CONTACTS: { //Permissions.READ_CONTACTS is an int constant
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
getContactsFromPhone();
}
}
}
}
然后在您单击以获取此联系人时,您应该询问您是否拥有此权限:
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(activity,
new String[]{Manifest.permission.READ_CONTACTS}, Permissions.READ_CONTACTS); //Permissions.READ_CONTACTS is an int constant
return false;
} else {
getContactsFromPhone();
}
1) 是的,您应该在每次调用这些函数时检查是否授予了权限。
2)您可以从主线程检查和请求权限。我认为从 AsyncTask 检查和请求权限不是一个好方法,因为权限请求是一个对话框,你将不得不等待异步任务线程直到你得到用户响应。尝试从主线程检查权限,获取用户响应,然后,如果权限被授予,则启动您的异步任务。
您不应该在 AsyncTask 中请求权限。事实上,您甚至不应该检索 deviceId 或其中的某些信息 - 将其作为参数传递。
每个应用程序的设置都有 'dangerous' 权限列表及其状态。如果您的应用程序以 sdk 23 为目标,则默认情况下它们都被禁用。因此,当您使用需要此类许可的代码时,您需要检查它是否被授予,如果没有 - 请求它。
最简单的方法是为这样的权限创建实用程序 class:
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);
}
}
}
然后像这样使用它:
(在你的片段中/Activity)
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);
}
在您的 AppCompat 中覆盖权限结果处理程序Activity 或实施 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);
}
}
如您所见,我们还有一个问题 - 如果用户拒绝许可怎么办?作为变体,我们可以显示解释对话框。或者(可能更好)仅在登录屏幕后请求权限。
Dexter 是一个 Android 库,它简化了运行时请求权限的过程。
我对 Android 6 (Marshmallow) 中的新权限系统感到非常困惑。
我正在使用两个所谓的 'dangeorus permissions' -
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
而且我在很多地方都使用了这些权限。
我需要访问用户帐户以注册应用程序、发送反馈 etc.And我还需要访问设备 ID 以注册应用程序。
我在 Java Class 命名的 util 中编写了两个函数来获取邮件帐户列表和设备 ID,并在 AsyncTask 和片段中使用这些函数。
现在,我完全不知所措,如何申请这些权限!我应该在功能中询问还是每次调用这些功能时询问?在 AsyncTask 中,我怎样才能得到响应?
请帮忙。
首先,您必须在 activity/fragment 中实现以下方法:
@Override
public void onRequestPermissionsResult(int requestCode,@NonNull String permissions[], @NonNull int[] grantResults) {
switch (requestCode) {
case Permissions.READ_CONTACTS: { //Permissions.READ_CONTACTS is an int constant
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
getContactsFromPhone();
}
}
}
}
然后在您单击以获取此联系人时,您应该询问您是否拥有此权限:
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(activity,
new String[]{Manifest.permission.READ_CONTACTS}, Permissions.READ_CONTACTS); //Permissions.READ_CONTACTS is an int constant
return false;
} else {
getContactsFromPhone();
}
1) 是的,您应该在每次调用这些函数时检查是否授予了权限。
2)您可以从主线程检查和请求权限。我认为从 AsyncTask 检查和请求权限不是一个好方法,因为权限请求是一个对话框,你将不得不等待异步任务线程直到你得到用户响应。尝试从主线程检查权限,获取用户响应,然后,如果权限被授予,则启动您的异步任务。
您不应该在 AsyncTask 中请求权限。事实上,您甚至不应该检索 deviceId 或其中的某些信息 - 将其作为参数传递。
每个应用程序的设置都有 'dangerous' 权限列表及其状态。如果您的应用程序以 sdk 23 为目标,则默认情况下它们都被禁用。因此,当您使用需要此类许可的代码时,您需要检查它是否被授予,如果没有 - 请求它。
最简单的方法是为这样的权限创建实用程序 class:
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);
}
}
}
然后像这样使用它: (在你的片段中/Activity)
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);
}
在您的 AppCompat 中覆盖权限结果处理程序Activity 或实施 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);
}
}
如您所见,我们还有一个问题 - 如果用户拒绝许可怎么办?作为变体,我们可以显示解释对话框。或者(可能更好)仅在登录屏幕后请求权限。
Dexter 是一个 Android 库,它简化了运行时请求权限的过程。