联系人选择器在Android 11上无法工作。

4

我遇到了一个问题,联系人选择器代码在 Android 11 以下的任何版本上都能正常工作,但是当我在 Android 11 上测试时,出现了以下错误:

2021-08-05 10:15:47.617 9338-9338/com.tortohub W/System.err:     at android.database.AbstractCursor.checkPosition(AbstractCursor.java:514)
2021-08-05 10:15:47.617 9338-9338/com.tortohub W/System.err:     at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:138)
2021-08-05 10:15:47.617 9338-9338/com.tortohub W/System.err:     at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:52)
2021-08-05 10:15:47.617 9338-9338/com.tortohub W/System.err:     at android.database.CursorWrapper.getString(CursorWrapper.java:141)
2021-08-05 10:15:47.617 9338-9338/com.tortohub W/System.err:     at com.tortohub.client.add.AddClientActivity.onActivityResult(AddClientActivity.java:159)
2021-08-05 10:15:47.617 9338-9338/com.tortohub W/System.err:     at android.app.Activity.dispatchActivityResult(Activity.java:8310)
2021-08-05 10:15:47.617 9338-9338/com.tortohub W/System.err:     at android.app.ActivityThread.deliverResults(ActivityThread.java:5008)
2021-08-05 10:15:47.617 9338-9338/com.tortohub W/System.err:     at android.app.ActivityThread.handleSendResult(ActivityThread.java:5056)
2021-08-05 10:15:47.617 9338-9338/com.tortohub W/System.err:     at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
2021-08-05 10:15:47.617 9338-9338/com.tortohub W/System.err:     at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
2021-08-05 10:15:47.617 9338-9338/com.tortohub W/System.err:     at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
2021-08-05 10:15:47.617 9338-9338/com.tortohub W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
2021-08-05 10:15:47.617 9338-9338/com.tortohub W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:106)
2021-08-05 10:15:47.617 9338-9338/com.tortohub W/System.err:     at android.os.Looper.loop(Looper.java:223)
2021-08-05 10:15:47.617 9338-9338/com.tortohub W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:7656)
2021-08-05 10:15:47.617 9338-9338/com.tortohub W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
2021-08-05 10:15:47.617 9338-9338/com.tortohub W/System.err:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
2021-08-05 10:15:47.617 9338-9338/com.tortohub W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

我从另一个stackoverflow问题中使用联系人选择器代码:

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            if (requestCode == RESULT_PICK_CONTACT) {
                Cursor cursor;
                try {
                    String phoneNo = "";
                    String name = "";
                    Log.i("intent",data.getData().toString());
                    Uri uri = data.getData();
                    cursor = this.getContentResolver().query(uri, null, null, null, null);
                    cursor.moveToFirst();

                    int phoneIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
                    phoneNo = cursor.getString(phoneIndex);

                    int nameColumnIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
                    name = cursor.getString(nameColumnIndex);

                    cursor.close();
                    Log.i("phone", phoneNo);
                    Log.i("name", name);
                    contactPicked(name,phoneNo);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } else {
            Log.e("MainActivity", "Failed to pick contact");
        }
    }
    private void pickContact(){
        Intent contactPickerIntent = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
        startActivityForResult(contactPickerIntent, RESULT_PICK_CONTACT);
    }

我注意到在安卓11上内容URI略有变化:

安卓11: intent: content://com.android.contacts/data/3
安卓10: intent: content://com.android.contacts/data/1


你找到解决方法了吗? 如果您启用了联系人权限,它就可以工作。但是为什么我们需要用户选择的联系人的权限呢? - Manikandan Selvanathan
3个回答

1

这些权限是用于从TelephonyManager读取自己的手机,而不是用于从电话簿中读取联系人的。 - Дмитрий Пупкинг
有时候一些插件也需要这个权限,所以如果我们不提供所有的权限,它就完全无法工作。 - Rahman Rezaee

1

我解决了这个问题:原因是在安卓11中,我必须手动请求读取联系人权限,而在安卓10中,那段代码可以正常工作。
解决方案:手动请求读取联系人权限。


0

不仅需要在AndroidManifest.xml中添加联系人读取权限,还需要添加查询意图。

<manifest>
    <!-- For overall Android support -->
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <application>
        ...
    </application>
    <!-- For Android 11+ support -->
    <queries>
        <intent>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="vnd.android.cursor.dir/contact" />
        </intent>
    </queries>
</manifest>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接