Android 为什么我的联系人查询提供了一个具有不同id的联系人?

Android 为什么我的联系人查询提供了一个具有不同id的联系人?,android,contacts,Android,Contacts,我有一个允许用户选择联系人的活动。完成后,所选联系人的id将在回复意图中传递。在处理结果的地方,将读取所选联系人的详细信息。 问题是,在处理结果时,读取的详细信息是针对与所选联系人不同的联系人的。 我不知道为什么。在我的例子中,用户只选择了一个联系人 我已经阅读了很多关于阅读联系人的文档和其他问题,但没有看到任何有助于我的案例的东西 从活动中获取联系人的用户选择: @Override protected void onCreate (Bundle savedInstanceState) {

我有一个允许用户选择联系人的活动。完成后,所选联系人的id将在回复意图中传递。在处理结果的地方,将读取所选联系人的详细信息。 问题是,在处理结果时,读取的详细信息是针对与所选联系人不同的联系人的。 我不知道为什么。在我的例子中,用户只选择了一个联系人

我已经阅读了很多关于阅读联系人的文档和其他问题,但没有看到任何有助于我的案例的东西

从活动中获取联系人的用户选择:

@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();
    }
}