为什么PhoneLookup和ContactsContract.Contacts选择器之间的联系人ID不匹配?

时间:2018-06-24 16:44:07

标签: android kotlin android-contacts contactscontract

我的应用程序正在扫描SMS消息并计算指标,然后将其存储在数据库中,该数据库由与SMS上的电话号码相关联的联系人ID键控。使用PhoneLookup机制查找该第一个联系人ID。稍后,我还让用户使用联系人选择器的意图选择联系人。但是,即使选择了同一个人,从选择器返回的联系人ID也不同于通过PhoneLookup获得的联系人ID。为什么会这样?

这是显示此效果的活动。设置PHONE_NUMBER等于手机上已知联系人的电话号码。然后点击“选择联系人”按钮并选择相同的联系人。对我来说,这两种方法的联系人ID不同。

import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.provider.ContactsContract
import android.support.v7.app.AppCompatActivity
import android.util.Log
import com.example.R
import kotlinx.android.synthetic.main.activity_contact_idtest.*

class ContactIDTest : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_contact_idtest)
    }

    companion object {
        const val TAG = "ContactIDTest"
        const val RQST_PICK_CONTACT = 1
        const val PHONE_NUMBER = "5551234567"
    }

    override fun onResume() {
        super.onResume()

        cmdPickContact.setOnClickListener {
            val pickContactIntent = Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI)
            pickContactIntent.type = ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE // Show user only contacts w/ phone numbers
            startActivityForResult(pickContactIntent, RQST_PICK_CONTACT)
        }

        contactForPhoneNumber(PHONE_NUMBER, { contactID, displayName, photoThumbnailUri ->
            txtContactID.text = contactID.toString()
            txtContactName.text = displayName
        }, {
            Log.e(TAG, "Error getting contact for phone number")
        })
    }

    private fun contactForPhoneNumber(phoneNumber: String, callback: (contactID: Long, displayName: String?, photoThumbnailUri: String?) -> Unit, error: () -> Unit) {
        val contactURI = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber))

        try {
            val cursor = contentResolver.query(contactURI,
                    arrayOf(ContactsContract.PhoneLookup.CONTACT_ID, ContactsContract.PhoneLookup.DISPLAY_NAME, ContactsContract.PhoneLookup.PHOTO_THUMBNAIL_URI),
                    null,
                    null,
                    null
            )

            if(cursor == null || cursor.count <= 0) {
                error()
            } else {

                cursor.moveToFirst()

                val contactID = cursor.getLong(cursor.getColumnIndexOrThrow(ContactsContract.PhoneLookup.CONTACT_ID))
                val displayName = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.PhoneLookup.DISPLAY_NAME))
                val photoThumbnailUri = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.PhoneLookup.PHOTO_THUMBNAIL_URI))

                cursor.close()

                callback(contactID, displayName, photoThumbnailUri)

            }

        } catch(e: Exception) {
            Log.e(TAG, "Error loading contact for phone number: $phoneNumber", e)
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if(requestCode == RQST_PICK_CONTACT) {
            if(resultCode == Activity.RESULT_OK) {

                val contactData = data!!.data
                val c = contentResolver.query(contactData, null, null, null, null)
                if(c.moveToFirst()) {
                    val contactID = c.getLong(c.getColumnIndex(ContactsContract.Contacts._ID))
                    val displayName = c.getString(c.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME))

                    txtPickedContactID.text = contactID.toString()
                    txtPickedContactName.text = displayName.toString()
                }
                c.close()
            }
        }
    }
}

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/layoutContactIDTest"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".activities.ContactIDTest"
    tools:layout_editor_absoluteY="81dp">

    <TextView
        android:id="@+id/txtContactName"
        android:layout_width="wrap_content"
        android:layout_height="21dp"
        android:text="$CONTACT_NAME"
        app:layout_constraintBottom_toTopOf="@+id/cmdPickContact"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/txtContactID" />

    <TextView
        android:id="@+id/txtContactID"
        android:layout_width="wrap_content"
        android:layout_height="18dp"
        android:text="$CONTACT_ID"
        app:layout_constraintBottom_toTopOf="@+id/txtContactName"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/cmdPickContact"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Pick Contact"
        app:layout_constraintBottom_toTopOf="@+id/txtPickedContactID"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/txtContactName" />

    <TextView
        android:id="@+id/txtPickedContactID"
        android:layout_width="wrap_content"
        android:layout_height="17dp"
        android:text="$PICKED_CONTACT_ID"
        app:layout_constraintBottom_toTopOf="@+id/txtPickedContactName"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/cmdPickContact" />

    <TextView
        android:id="@+id/txtPickedContactName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="$PICKED_CONTACT_NAME"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/txtPickedContactID" />
</android.support.constraint.ConstraintLayout>

1 个答案:

答案 0 :(得分:1)

此代码:

val pickContactIntent = Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI)
pickContactIntent.type = ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE

将返回CommonDataKinds.Phone._ID而不是Contacts._ID