我已经遵循android准则,要求运行VERSION.M及更高版本的Android设备(运行时权限)要求许可,但是未显示许可请求对话框,而是自动拒绝了许可。
我要求用户提供“读/写联系人”权限以及下面清单中指示的其他权限。
该应用程序请求其他权限,例如访问文件,电话,短信,但不请求读取联系人权限。
这是我的清单文件
<uses-permission
android:name="android.permission.AUTHENTICATE_ACCOUNTS"
tools:remove="android:maxSdkVersion"/>
<uses-permission
android:name="android.permission.GET_ACCOUNTS"
tools:remove="android:maxSdkVersion"/>
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.RECEIVE_MMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="Manifest.permission.READ_CONTACTS"
tools:remove="android:maxSdkVersion"/>
<uses-permission android:name="Manifest.permission.WRITE_CONTACTS"
tools:remove="android:maxSdkVersion"/>
<uses-permission android:name="Manifest.permission.CONTACTS"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.READ_CALL_STATE" />
<!-- For sending/receiving events -->
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.RAISED_THREAD_PRIORITY" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<!-- Normal -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<!-- So we can add a TextSecure 'Account' -->
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<!-- For conversation 'shortcuts' on the desktop -->
<uses-permission android:name="android.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<!-- For fixing MMS -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-feature
android:name="android.hardware.microphone"
android:required="false" />
<uses-feature
android:name="android.hardware.wifi"
android:required="false" />
<uses-feature
android:name="android.hardware.portrait"
android:required="false" />
<uses-feature
android:name="android.hardware.touchscreen"
android:required="false" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<uses-permission android:name="com.google.android.providers.gsf.permmission.READ_GSERVICES" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission
android:name="android.permission.BROADCAST_WAP_PUSH"
tools:ignore="ProtectedPermissions" />
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
这是我的显式读取联系人权限请求块
private void loadDeviceContactsOnAndroid_M() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission_group.CONTACTS) == PackageManager.PERMISSION_GRANTED) {
Log.e(getClass().getSimpleName(), "Read contacts permission granted");
loadAndDisplayConfiguredRecipients();
} else {
Log.e(getClass().getSimpleName(), "Read contacts permission Not granted");
if (shouldShowRequestPermissionRationale(Manifest.permission_group.CONTACTS)) {
Toast.makeText(getApplicationContext(), "mPHR messaging feature requires your contacts", Toast.LENGTH_LONG).show();
}
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission_group.CONTACTS}, 101);
}
} else
Toast.makeText(getApplicationContext(), "Android Version is " + Build.VERSION.SDK_INT, Toast.LENGTH_LONG).show();
}
这是我的onRequestPermissionResult回调方法
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == 101) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Hurray permission granted ", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Until you grant the permission, we cannot display the names", Toast.LENGTH_SHORT).show();
}
}
}
这是我的联系人加载器方法块
Cursor cursor = contactController.querySystemContacts("");
if (cursor.moveToFirst()) {
do {
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
messageRecipients.add(name);
} while (cursor.moveToNext());
}
cursor.close();
该应用程序不向用户请求联系人权限,当我绕过此权限并尝试继续访问设备上的联系人时,我收到权限被拒绝的安全错误;
java.lang.SecurityException: Permission Denial: opening provider com.android.providers.contacts.ContactsProvider2 from ProcessRecord{13c53b7 14017:my/app/package/name/u0a183}
(pid=159017, uid=10183)
requires android.permission.READ_CONTACTS or android.permission.WRITE_CONTACTS
我正在Android 8物理设备上运行测试。
当我使用相同的代码ACCESS_COARSE_LOCATION_PERMISSION时,它可以正常工作,但是当我使用READ_CONTACT或WRITE_CONTACTS时失败
答案 0 :(得分:1)
我尚未尝试您的代码,但请不要直接使用checkSelfPermission
。按照Google的建议使用ContextCompat.checkSelfPermission
方法。
if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.WRITE_CALENDAR)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
}
https://developer.android.com/training/permissions/requesting#java
当我添加用于权限检查的代码时,我正在单独进行权限检查,这意味着我是在逐一检查权限,而不是检查权限组。因此,我稍后将尝试。但是现在,请尝试使用ContextCompat方法。
编辑:
请勿按权限组要求。 Android M中的权限请求模型仅适用于个人权限。 所以这就是你可以做的。
private void checkPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.READ_CONTACTS) || ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_CONTACTS)) {
Toast.makeText(this, "Necessary permissions are not granted",
Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS},
MY_PERMISSIONS_REQUEST_CODE);
}
} else {
// Permission has already been granted
}
}
编辑:
请不要在清单中使用以下内容。
<uses-permission android:name="Manifest.permission.READ_CONTACTS"
tools:remove="android:maxSdkVersion"/>
<uses-permission android:name="Manifest.permission.WRITE_CONTACTS"
tools:remove="android:maxSdkVersion"/>
<uses-permission android:name="Manifest.permission.CONTACTS"/>
您可以将它们替换为以下内容。
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
答案 1 :(得分:1)
您可以在需要使用应用程序或运行时时请求其启动权限。 试试这个库(https://github.com/nabinbhandari/Android-Permissions)。它提供了许多选项,例如当用户拒绝或授予权限时,您还可以请求多个权限。
示例
单一权限
Permissions.check(this/*context*/, Manifest.permission.READ_CONTACTS, null, new PermissionHandler() {
@Override
public void onGranted() {
// do your task.
}});
多个权限
String[] permissions = {Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_EXTERNAL_STORAGE};Permissions.check(this/*context*/, permissions, null/*rationale*/, null/*options*/, new PermissionHandler() {
@Override
public void onGranted() {
// do your task.
}});
注意 除非维护良好,否则使用库不是一个好习惯