为什么我的联系人查询是否给出了具有不同ID的联系人?

问题描述 投票:1回答:1

我有一个活动允许用户选择联系人。完成后,所选联系人的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

名称与联系人选择活动中选择的名称不同。

android contacts
1个回答
1
投票

在方法pickContacts中,改变它以获得Contacts._ID,它偶然发现一个ID,因为RawContacts._IDContacts._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();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.