Android 不显示 READ_CONTACT WRITE_CONTACTS 的权限请求对话框

Android Does not show permission request dialog for READ_CONTACT WRITE_CONTACTS

我遵循了 android 指南来请求 Android 设备 运行 VERSION.M 及更高版本的权限,即(运行时权限),但是权限请求对话框不显示,而是自动拒绝权限。

我请求用户获得 READ/WRITE CONTACTS 权限以及下面我的清单中指示的其他权限。

该应用请求其他权限,例如访问文件、phone、短信但不请求读取联系人权限。

这是我的清单文件

<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

时失败

我没有试过你的代码,但请不要直接使用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 方法。

编辑:

请不要按权限组请求。 AndroidM中的权限请求模型仅针对个人权限。 所以这就是您可以做的。

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.
}});

注意 使用库不是一个好习惯,除非它们得到很好的维护