我有一个活动允许用户选择联系人。完成后,所选联系人的ID将在回复Intent中传递。处理结果的地方,将读取所选联系人的详细信息。问题是,在处理结果时,读取的详细信息是针对与选择的不同的联系人。我不知道为什么。在我的情况下,用户只选择一个联系人。
我已经阅读了很多关于阅读联系人的文档和其他问题,但没有看到任何有助于我的案例。
从“活动”中获取用户从联系人中选择的内容:
@Override
protected void onCreate (Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_select_from_contacts);
m_view = findViewById(R.id.lv_contactsSelect);
m_view.setVisibility(View.VISIBLE);
getListView().setItemsCanFocus(false);
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,
new String[]{ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME},
null, null, "UPPER(" + ContactsContract.Contacts.DISPLAY_NAME + ") ASC");
setListAdapter(new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_multiple_choice,
cursor,
new String[]{ContactsContract.Contacts.DISPLAY_NAME},
new int[]{android.R.id.text1},
0));
Button btn = findViewById(R.id.btn_get_contacts);
btn.setOnClickListener((View view) -> {
Intent replyIntent = new Intent();
ArrayList<Long> ids = pickContacts();
replyIntent.putExtra(Activities.ARG_SELECTED, ids);
setResult(Activities.RESULT_CONTACTS_SELECTED, replyIntent);
finish();
});
}
/** Viewer for list of contacts */
private ListView m_view;
private ListView getListView ()
{ return m_view; }
private CursorAdapter mAdapter;
private void setListAdapter (@NonNull CursorAdapter adapter)
{
mAdapter = adapter;
m_view.setAdapter(adapter);
}
// return id for each selected contact
private ArrayList<Long> pickContacts ()
{
SparseBooleanArray a = getListView().getCheckedItemPositions();
ArrayList<Long> contacts = new ArrayList<>();
for (int i = 0; i < a.size(); i++)
{
if (a.valueAt(i))
{
Cursor c = (Cursor)mAdapter.getItem(a.keyAt(i));
// TODO use RawContacts or Contacts? Currently the result is the same.
//Long idContact = c.getLong(c.getColumnIndex(ContactsContract.Contacts._ID));
Long idRaw = c.getLong(c.getColumnIndex(ContactsContract.RawContacts._ID));
contacts.add(idRaw);
}
}
return contacts;
}
处理结果:
@Override
protected void onActivityResult (int requestCode, int resultCode, Intent data)
{
if (resultCode == Activities.RESULT_CONTACTS_SELECTED)
{
ArrayList<Long> ids = (ArrayList<Long>)data.getSerializableExtra(Activities.ARG_SELECTED);
for (long id : ids)
{
getContactDetails(id);
}
}
}
/**
* As mentioned in https://developer.android.com/reference/android/provider/ContactsContract.RawContacts
* the best way to read a raw contact along with associated data is by using the Entity directory.
*/
// FIXME: The id from the received result matches what was selected,
// but this function reads details for a different contact.
private void getContactDetails (long rawContactId)
{
System.out.println("Get contact with id " + rawContactId);
Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
Uri entityUri = Uri.withAppendedPath(rawContactUri, Entity.CONTENT_DIRECTORY);
// For example, this output can be "Get contact from entity uri content://com.android.contacts/raw_contacts/615/entity"
// (Where 615 is the id for the selected contact.)
System.out.println("Get contact from entity uri " + entityUri);
Cursor c = getContentResolver().query(entityUri,
new String[]{RawContacts.SOURCE_ID, Entity.DATA_ID, Entity.MIMETYPE, Entity.DATA1}, // projection
null, null, null);
if (c == null)
return;
try
{
while (c.moveToNext())
{
// In this example I'm just dumping data to the console.
if (!c.isNull(1))
{
String mimeType = c.getString(2);
String data = c.getString(3);
System.out.println("mimeType = " + mimeType);
System.out.println("data = " + data);
}
}
}
finally
{
c.close();
}
}
例如,处理程序的控制台输出包括:
mimeType = vnd.android.cursor.item/name
data = A name
名称与联系人选择活动中选择的名称不同。
在方法pickContacts
中,改变它以获得Contacts._ID
,它偶然发现一个ID,因为RawContacts._ID
和Contacts._ID
都是字符串“_id”,但它只是完全错误。
接下来,因为你实际上正在抓取一个联系人ID,你需要修改你的getContactDetails
接受ContactId
而不是RawContactId
。
不确定为什么你需要像这样涉及Entity
API,如果你只需要查询该联系人的数据,请执行以下操作:
private void getContactDetails (long contactId) {
Log.i("Contacts", "Get contact with id " + contactId);
String[] projection = new String[]{Data.DISPLAY_NAME, Data.MIMETYPE, Data.DATA1};
String selection = Data.CONTACT_ID + "=" + contactId;
Cursor c = getContentResolver().query(Data.CONTENT_URI, projection, selection, null, null);
if (c == null) {
return;
}
try {
while (c.moveToNext()) {
String name = c.getString(0);
String mimeType = c.getString(1);
String data = c.getString(2);
Log.i("Contacts", contactId + ", " + name + ", " + mimetype + ", " + data);
}
} finally {
c.close();
}
}