运行时权限 - 为已授予的权限请求权限
Runtime Permission - Requesting permission for already granted permission
我编写了以下脚本来获取联系人和位置的多个运行时权限。我在布局中分别为联系人和位置使用了两个开关。如果我单击联系人开关,它会按预期请求对联系人和位置的许可。然后我从 "App Permissions" 设置 activity 中手动删除了位置权限。现在,如果我单击位置开关,它会再次询问联系人和位置。
我的问题是,既然我第一次授予了联系人权限,我可以在"App Permissions"设置中看到权限被授予activity,为什么又要请求联系人权限?即使我正在 hasPermissions 方法中检查它。
public static final int REQUEST_ID_MULTIPLE_PERMISSIONS = 1001;
String[] PERMISSIONS = {Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS,
Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.basic_permissions);
CONTACTS_ACCESS_SWITCH = (Switch) findViewById(R.id.contactsPermissionSwitch);
LOCATION_ACCESS_SWITCH = (Switch) findViewById(R.id.locationPermissionSwitch);
CONTACTS_ACCESS_SWITCH.setOnClickListener(requestPermissionMethod);
LOCATION_ACCESS_SWITCH.setOnClickListener(requestPermissionMethod);
}
private void requestPermissionMethod() {
if (!hasPermissions(BasicPermissions.this, PERMISSIONS)) {
ActivityCompat.requestPermissions(BasicPermissions.this, PERMISSIONS, REQUEST_ID_MULTIPLE_PERMISSIONS);
}
}
private boolean hasPermissions(Context context, String... permissions) {
if (context != null && permissions != null) {
for (String permission : permissions) {
if (ContextCompat.checkSelfPermission(BasicPermissions.this, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
清单文件:
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
配置:
在 Android 6.0 android 工作室模拟器设备中进行测试。
compileSdkVersion 27.
minSdkVersion 18
targetSdkVersion 27
如果您请求多个权限,它会请求多个权限。
如果您只希望它请求您当前没有的权限,您必须自己检查,然后从 "PERMISSIONS" 数组中删除您已经拥有的权限。
由于代码是使用 Array 编写的,因此它请求对数组中所有值的权限,即使它已经被授予。所以我重写了代码以使用 ArrayList
而不是 Array
。现在它按预期完美运行。
private boolean requestPermissionMethod() {
int permissionContacts = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS);
int locationPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
List<String> listPermissionsNeeded = new ArrayList<>();
if (locationPermission != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
}
if (permissionContacts != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.READ_CONTACTS);
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]),REQUEST_ID_MULTIPLE_PERMISSIONS);
return false;
}
return true;
}
我编写了以下脚本来获取联系人和位置的多个运行时权限。我在布局中分别为联系人和位置使用了两个开关。如果我单击联系人开关,它会按预期请求对联系人和位置的许可。然后我从 "App Permissions" 设置 activity 中手动删除了位置权限。现在,如果我单击位置开关,它会再次询问联系人和位置。
我的问题是,既然我第一次授予了联系人权限,我可以在"App Permissions"设置中看到权限被授予activity,为什么又要请求联系人权限?即使我正在 hasPermissions 方法中检查它。
public static final int REQUEST_ID_MULTIPLE_PERMISSIONS = 1001;
String[] PERMISSIONS = {Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS,
Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.basic_permissions);
CONTACTS_ACCESS_SWITCH = (Switch) findViewById(R.id.contactsPermissionSwitch);
LOCATION_ACCESS_SWITCH = (Switch) findViewById(R.id.locationPermissionSwitch);
CONTACTS_ACCESS_SWITCH.setOnClickListener(requestPermissionMethod);
LOCATION_ACCESS_SWITCH.setOnClickListener(requestPermissionMethod);
}
private void requestPermissionMethod() {
if (!hasPermissions(BasicPermissions.this, PERMISSIONS)) {
ActivityCompat.requestPermissions(BasicPermissions.this, PERMISSIONS, REQUEST_ID_MULTIPLE_PERMISSIONS);
}
}
private boolean hasPermissions(Context context, String... permissions) {
if (context != null && permissions != null) {
for (String permission : permissions) {
if (ContextCompat.checkSelfPermission(BasicPermissions.this, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
清单文件:
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
配置:
在 Android 6.0 android 工作室模拟器设备中进行测试。
compileSdkVersion 27.
minSdkVersion 18
targetSdkVersion 27
如果您请求多个权限,它会请求多个权限。
如果您只希望它请求您当前没有的权限,您必须自己检查,然后从 "PERMISSIONS" 数组中删除您已经拥有的权限。
由于代码是使用 Array 编写的,因此它请求对数组中所有值的权限,即使它已经被授予。所以我重写了代码以使用 ArrayList
而不是 Array
。现在它按预期完美运行。
private boolean requestPermissionMethod() {
int permissionContacts = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS);
int locationPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
List<String> listPermissionsNeeded = new ArrayList<>();
if (locationPermission != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
}
if (permissionContacts != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.READ_CONTACTS);
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]),REQUEST_ID_MULTIPLE_PERMISSIONS);
return false;
}
return true;
}