Android 为什么我的联系人查询提供了一个具有不同id的联系人?
我有一个允许用户选择联系人的活动。完成后,所选联系人的id将在回复意图中传递。在处理结果的地方,将读取所选联系人的详细信息。 问题是,在处理结果时,读取的详细信息是针对与所选联系人不同的联系人的。 我不知道为什么。在我的例子中,用户只选择了一个联系人 我已经阅读了很多关于阅读联系人的文档和其他问题,但没有看到任何有助于我的案例的东西 从活动中获取联系人的用户选择:Android 为什么我的联系人查询提供了一个具有不同id的联系人?,android,contacts,Android,Contacts,我有一个允许用户选择联系人的活动。完成后,所选联系人的id将在回复意图中传递。在处理结果的地方,将读取所选联系人的详细信息。 问题是,在处理结果时,读取的详细信息是针对与所选联系人不同的联系人的。 我不知道为什么。在我的例子中,用户只选择了一个联系人 我已经阅读了很多关于阅读联系人的文档和其他问题,但没有看到任何有助于我的案例的东西 从活动中获取联系人的用户选择: @Override protected void onCreate (Bundle savedInstanceState) {
@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;
}
如果姓名与在联系人选择活动中选择的姓名不同。在方法
中选择联系人
,将其更改为获取联系人。\u ID
,它会偶然找到一个ID,因为中的raw Contacts.\u ID
和Contacts.\u ID
都是字符串“\u ID”,但它完全错了
接下来,由于您实际上正在获取联系人id,因此需要修改getContactDetails
以接受ContactId
,而不是RawContactId
不确定您为什么需要像这样涉及实体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();
}
}
在方法pickContacts
中,将其更改为获取联系人。\u ID
,它会偶然找到一个ID,因为RawContacts.\u ID
和Contacts.\u ID
都是字符串“\u ID”,但它完全错了
接下来,由于您实际上正在获取联系人id,因此需要修改getContactDetails
以接受ContactId
,而不是RawContactId
不确定您为什么需要像这样涉及实体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();
}
}
是:导入android.provider.ContactsContract.RawContacts.Entity;未使用idContact变量。这是尝试不同id方法后留下的东西。我将删除它以避免混淆。我看不出原始联系人id是怎么错的。因为Contacts contract.raw Contacts.\u id
与Contacts contract.Contacts.\u id
完全相同-只需尝试Log.d
这两个,你是说这行是错的吗<代码>长idRaw=c.getLong(c.getColumnIndex(ContactsContract.RawContacts._ID))代码>是的,它会给你联系人id-而不是原始联系人id-我假设mAdapter
是上面的SimpleCursorAdapte
-但我可能错了,因为mAdapter
只显示在你代码中的一个地方,顺便说一句,如果您使用SimpleCursorAdapter
您需要迭代做什么?是:导入android.provider.contacts contract.RawContacts.Entity;未使用idContact变量。这是尝试不同id方法后留下的东西。我将删除它以避免混淆。我看不出原始联系人id是怎么错的。因为Contacts contract.raw Contacts.\u id
与Contacts contract.Contacts.\u id
完全相同-只需尝试Log.d
这两个,你是说这行是错的吗<代码>长idRaw=c.getLong(c.getColumnIndex(ContactsContract.RawContacts._ID))代码>是的,它会给你联系人id-而不是原始联系人id-我假设mAdapter
是上面的SimpleCursorAdapte
-但我可能错了,因为mAdapter
只在代码中的一个地方显示,顺便问一下,如果你使用SimpleCursorAdapter
你需要迭代做什么?谢谢。这是一个没有使用我认为最好的实体的解决方案,如中所述。不管怎样,我很高兴使用你提出的问题。谢谢。这是一个没有使用我认为最好的实体的解决方案,如中所述。不管怎样,我很高兴使用你给出的查询。
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();
}
}