如何从联系人目录加载地址?

Posted

技术标签:

【中文标题】如何从联系人目录加载地址?【英文标题】:How to load an address from a contacts directory? 【发布时间】:2018-05-12 05:27:48 【问题描述】:

我正在尝试从 android 下的 G Suite 联系人目录(或 Exchange 全局地址列表)加载地址。该目录没有实现完整的 ContactsContract,而只是例如CONTENT_FILTER_URI 可能还有其他一些。我可以加载联系方式、电话号码和电子邮件地址。但我无法加载邮政地址。要获取联系人 ID,我使用以下代码:

// The directory I use in this example has the number 3:
String directoryId = "3";     

// A contact with the name "Test" is searched in directory "3":
Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_FILTER_URI, Uri.encode("Test")).buildUpon()
             .appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY, directoryId)
             .build();

// The id of the first result is loaded:
Cursor c = cr.query(uri, new String[]ContactsContract.Contacts._ID, null, null, null);
c.moveToNext();
String id = c.getString(0);

之后,我在“id”中获得了第一个联系人的 ID。现在我想加载该联系人的所有邮政地址。但是,此代码返回 null 而不是光标,但仅当我使用 directoryId "3" 时:

Uri uri = ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI.buildUpon()
          .appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY, directoryId)
          .build();
Cursor c = cr.query(uri, new String[]ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS, ContactsContract.CommonDataKinds.StructuredPostal.CONTACT_ID+"=?", new String[]id, null);
c.moveToNext();
c.getString(0);

对于 directoryId "0" 来说效果很好。因此,G Suite 联系人目录似乎没有实现 ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI。但是,Android 联系人应用程序能够加载该联系人的地址。

联系人目录中获取联系人的“StructuredPostal”对象的正确方法是什么?

【问题讨论】:

获得联系人 ID 后,您是否尝试在标准 ContactsContacts 数据库中查询它?即Uri uri = StructuredPostal.CONTENT_URI; 是的,我试过了。但是默认目录中不存在 content-id。当我省略“DIRECTORY_PARAM_KEY”并仅访问 StructuredPostal.CONTENT_URI 时,我得到一个游标,但“c.moveToNext()”返回 false,即该内容 ID 没有一行。这可能是因为省略“DIRECTORY_PARAM_KEY”时会查询默认目录,并且该目录不包含有关该联系人的任何信息。只有目录“3”(G Suite)知道联系人。 【参考方案1】:

更新

除了从下表中获取任何东西之外似乎没有其他方法:ContactsContract.ContactsCommonDataKinds.PhoneCommonDataKinds.Email,因为所有其他表都缺少 CONTENT_FILTER_URI 来运行查询。

【讨论】:

不,不幸的是“cr.query”返回一个空指针。它适用于 directoryId 0(当在 "StructuredPostal.CONTENT_ITEM_TYPE" 周围添加缺少的引号以获得有效的 SQL 时)但是当将它与 directoryId 3 一起使用时,会返回一个空指针。因此,G Suite 似乎也没有实现 ContactsContract.Data.CONTENT_URI 。根据developer.android.com/reference/android/provider/…,他们只需要实现 Contacts.CONTENT_FILTER_URI。但我无法弄清楚联系人应用程序如何从 G Suite 目录中获取地址。 :-( 如何查询ContactsContract.Contacts.Entity?它没有 Uri。你的意思是“RawContacts”,它似乎有 三元组?不,如果我在没有 directoryId 的情况下访问 RawContacts.CONTENT_URI,我会得到一个空游标(因为找不到联系人 ID),如果我使用 directoryId,我会得到一个空指针而不是游标(再次,似乎 G Suite 没有实现该 Uri)。我认为 RawContacts 仅包含本地联系人,而不包含 GAL/GSuite 联系人。 你提到的源代码从其他地方获取它的 Uri,我已经跟随它到 QuickContactsActivity,它似乎从 onActivityResult 函数中的另一个活动中获取它。您是否能够编译并运行“联系人”应用程序?这样就可以检查使用了哪个 Uri?关于 RawContacts 表,我发现这篇文章可能很有趣,但在这种情况下无济于事:***.com/questions/8788053/… 很遗憾,似乎在任何地方都没有关于这个问题的文档。 不,我的意思是ContactsContract.Contacts.Entity,你不是通过CONTENT_URI查询它,而是通过将Entity.CONTENT_DIRECTORY添加到contactUri,对于contactUri部分,请参阅我在上面添加的代码 我已经尝试了您的新代码,但得到了相同的结果。如果我不使用 directoryId,系统将找不到具有该联系人 ID 的任何内容并返回 Cursor 但没有内容。如果我添加 .appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY, directoryId) 那么我得到一个空指针而不是光标。 :-(

以上是关于如何从联系人目录加载地址?的主要内容,如果未能解决你的问题,请参考以下文章

如何从联系人列表中获取电子邮件地址?

Flutter:如何从联系人获取用户地址

如何从地址簿获取联系人到我们的本机应用程序

加载联系人以检索电子邮件地址并发送电子邮件

从 android 中的联系人加载器获取电话号码:投影崩溃

如何从android中的联系人读取电子邮件字段?