我遵循了安卓指南,为运行VERSION的安卓设备请求权限。M及以上即(运行时权限(,但没有显示权限请求对话框,而是自动拒绝权限。
我请求用户获得"读/写联系人"权限以及我下面的清单所示的其他权限。
该应用程序请求其他权限,如访问文件、电话、短信,但不请求读取联系人权限。
这是我的清单文件
<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
我正在安卓8物理设备上运行测试。
当我使用相同的代码时,例如,ACCESS_COARSE_LOCATION_PERMISSION,它工作得很好,但当我使用READ_CONTACT或WRITE_CONTACTS 时失败
我没有尝试过你的代码,但请不要直接使用checkSelfPermission
。按照谷歌的建议,使用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方法。
编辑:
请不要按权限组进行请求。安卓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" />
您可以在需要使用应用程序或运行时请求权限。试试这个库(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.
}});
注意使用库不是一个好的做法,除非它们得到了良好的维护