使用 EXTRA_ADDRESS_BOOK_INDEX 支持 CursorLoader

Posted

技术标签:

【中文标题】使用 EXTRA_ADDRESS_BOOK_INDEX 支持 CursorLoader【英文标题】:Support CursorLoader with EXTRA_ADDRESS_BOOK_INDEX 【发布时间】:2018-06-24 00:31:57 【问题描述】:

我正在使用支持 CursorLoader 来加载联系人。

当使用大于 21 的 API 时,我调用

loader.setUri(ContactsContract.Data.CONTENT_URI.buildUpon().appendQueryParameter(ContactsContract.Data.EXTRA_ADDRESS_BOOK_INDEX, "true").build());

意思是我会得到联系人首字母的索引。

加载后,我收到此崩溃:

Writing exception to parcel
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String[] android.os.BaseBundle.getStringArray(java.lang.String)' on a null object reference
at com.android.providers.contacts.FastScrollingIndexCache.put(FastScrollingIndexCache.java:237)
at com.android.providers.contacts.ContactsProvider2.bundleFastScrollingIndexExtras(ContactsProvider2.java:8320)
at com.android.providers.contacts.ContactsProvider2.queryLocal(ContactsProvider2.java:7803)
at com.android.providers.contacts.ContactsProvider2.queryDirectoryIfNecessary(ContactsProvider2.java:6083)
at com.android.providers.contacts.ContactsProvider2.query(ContactsProvider2.java:6065)
at com.android.providers.contacts.SemcContactsProvider2.query(SemcContactsProvider2.java:550)
at android.content.ContentProvider$Transport.query(ContentProvider.java:247)
at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:112)
at android.os.Binder.execTransact(Binder.java:570)

还有

java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.support.v4.content.ModernAsyncTask$3.done(ModernAsyncTask.java:161)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String[] android.os.BaseBundle.getStringArray(java.lang.String)' on a null object reference
at android.os.Parcel.readException(Parcel.java:1689)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:188)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:140)
at android.content.ContentProviderProxy.query(ContentProviderNative.java:421)
at android.content.ContentResolver.query(ContentResolver.java:537)
at android.support.v4.content.ContentResolverCompat.query(ContentResolverCompat.java:80)
at android.support.v4.content.CursorLoader.loadInBackground(CursorLoader.java:61)
at android.support.v4.content.CursorLoader.loadInBackground(CursorLoader.java:39)
at android.support.v4.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:306)
at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:59)
at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:47)
at android.support.v4.content.ModernAsyncTask$2.call(ModernAsyncTask.java:138)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)

有人可以帮忙吗?

更新

使用 ContractsData.CommonDataKinds.Phone 视图时也会发生同样的情况,即使该列已公开

【问题讨论】:

【参考方案1】:

从文档示例代码看来,他们将此参数附加到 Contacts.CONTENT_URI 而不是像您一样的 Data.CONTENT_URI

Uri uri = Contacts.CONTENT_URI.buildUpon()
          .appendQueryParameter(Contacts.EXTRA_ADDRESS_BOOK_INDEX, "true")
          .build();

您说您正在使用CursorLoader 加载Contacts,那么您可能需要查询Contacts.CONTENT_URI 表,Data.CONTENT_URI 用于获取特定详细信息(电子邮件、电话等)。 ) 关于联系人,而不是姓名或照片等基本信息。

【讨论】:

感谢您的回答,不幸的是,这并不是我想要的,因为我希望使用 Data.CONTENT_URI 和 Phone.CONTENT_URI,它们有自己的 EXTRA_ADDRESS_BOOK_INDEX。我的问题是如果不使用,为什么要公开这个额外的内容。 在 ContactsContract.Data 文档中,他们确实提到了这一点,但是,如果您单击它查看代码示例,它使用 Contacts.CONTENT_URI 而不是 Data.CONTENT_URI。这也很有意义,因为EXTRA_ADDRESS_BOOK_INDEX 仅在联系人上下文中有意义,而不是在数据中,您永远不会在显示手机上所有电子邮件和电话的列表中看到 A-Z 滚动条。您只会看到那些用于联系人的滚动条 我想这确实有道理。对我来说很奇怪的是,如果不使用,他们会公开参考。感谢您的帮助!

以上是关于使用 EXTRA_ADDRESS_BOOK_INDEX 支持 CursorLoader的主要内容,如果未能解决你的问题,请参考以下文章

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

今目标使用教程 今目标任务使用篇

Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)

MySQL db 在按日期排序时使用“使用位置;使用临时;使用文件排序”

使用“使用严格”作为“使用强”的备份

Kettle java脚本组件的使用说明(简单使用升级使用)