【问题标题】:Android: Retrieve contact name from phone numberAndroid:从电话号码中检索联系人姓名
【发布时间】:2011-03-05 23:52:49
【问题描述】:

我想检索与传入电话号码关联的联系人姓名。当我处理 broascastreceiver 中的传入号码时,有一个带有传入呼叫者姓名的字符串将对我的项目有很大帮助。

我认为这涉及使用 sql WHERE 子句作为过滤器的查询,但我需要对联系人进行排序吗?一个例子或提示会很有帮助。

【问题讨论】:

  • 为了方便他人,我写了一篇文章,其中包含查询姓名,照片,联系人ID等的完整代码,并附有适当的解释。该代码包含在不同答案中找到的 sn-ps,但更有条理和经过测试。链接:hellafun.weebly.com/home/…

标签: android android-contacts phone-number contactscontract


【解决方案1】:

虽然这已经回答了,但这里是从号码中获取联系人姓名的完整功能。希望对其他人有所帮助:

public static String getContactName(Context context, String phoneNumber) {
    ContentResolver cr = context.getContentResolver();
    Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
    Cursor cursor = cr.query(uri, new String[]{PhoneLookup.DISPLAY_NAME}, null, null, null);
    if (cursor == null) {
        return null;
    }
    String contactName = null;
    if(cursor.moveToFirst()) {
        contactName = cursor.getString(cursor.getColumnIndex(PhoneLookup.DISPLAY_NAME));
    }

    if(cursor != null && !cursor.isClosed()) {
        cursor.close();
    }

    return contactName;
}

[更新基于 Marcus 的评论]

您必须申请此权限:

<uses-permission android:name="android.permission.READ_CONTACTS"/>

【讨论】:

  • 它使应用程序在恢复活动时“不负责任”。我该怎么做
  • 我每次在 Android 5.1 上运行时都会遇到 ANR
  • 可能对于 ANR,您需要在 UI 线程以外的线程上运行它。
  • 值得一提的是,这需要<uses-permission android:name="android.permission.READ_CONTACTS"/>权限
  • 您好,我尝试了类似的方法,但没有成功。这是我的问题,非常感谢您的帮助! :) stackoverflow.com/questions/35097844/get-contact-name/…
【解决方案2】:

为此,您需要按照所述使用优化的 PhoneLookup 提供程序。

添加AndroidManifest.xml的权限:

<uses-permission android:name="android.permission.READ_CONTACTS"/>

然后:

public String getContactName(final String phoneNumber, Context context)
{
    Uri uri=Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI,Uri.encode(phoneNumber));

    String[] projection = new String[]{ContactsContract.PhoneLookup.DISPLAY_NAME};

    String contactName="";
    Cursor cursor=context.getContentResolver().query(uri,projection,null,null,null);

    if (cursor != null) {
        if(cursor.moveToFirst()) {
            contactName=cursor.getString(0);
        }
        cursor.close();
    }

    return contactName;
}

【讨论】:

  • 立即关闭开发页面,感谢您的快速响应。 Uri 中的 toString() 方法应该将此查询转换为联系人姓名吗?
  • 不,您不必自己解决光标。如需帮助,请查看以下问题:stackoverflow.com/questions/903343/…
  • 我会使用 URI 使用 managedQuery 初始化一个游标,然后将游标移动到第一个位置并获取数据?一旦我将光标放在第一个位置,我就使用 getString?我认为第一个位置是正确的,因为查询是针对数字的,因此查询只会提取该数字的名称?
  • 该查询的其余部分具体包含哪些内容?这个答案并不比现有的文档更有帮助。
  • 你应该用完整的代码来回答。在查询如何迭代和获取名称之后。初学者无法理解这 2 行。您应该制作基于数字返回名称的函数
【解决方案3】:

这很有帮助,这是我检索调用者姓名、ID 和照片的最终代码:

private void uploadContactPhoto(Context context, String number) {

Log.v("ffnet", "Started uploadcontactphoto...");

String name = null;
String contactId = null;
InputStream input = null;

// define the columns I want the query to return
String[] projection = new String[] {
        ContactsContract.PhoneLookup.DISPLAY_NAME,
        ContactsContract.PhoneLookup._ID};

// encode the phone number and build the filter URI
Uri contactUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));

// query time
Cursor cursor = context.getContentResolver().query(contactUri, projection, null, null, null);

if (cursor.moveToFirst()) {

    // Get values from contacts database:
    contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.PhoneLookup._ID));
    name =      cursor.getString(cursor.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME));

    // Get photo of contactId as input stream:
    Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(contactId));
    input = ContactsContract.Contacts.openContactPhotoInputStream(context.getContentResolver(), uri);

    Log.v("ffnet", "Started uploadcontactphoto: Contact Found @ " + number);            
    Log.v("ffnet", "Started uploadcontactphoto: Contact name  = " + name);
    Log.v("ffnet", "Started uploadcontactphoto: Contact id    = " + contactId);

} else {

    Log.v("ffnet", "Started uploadcontactphoto: Contact Not Found @ " + number);
    return; // contact not found

}

// Only continue if we found a valid contact photo:
if (input == null) {
    Log.v("ffnet", "Started uploadcontactphoto: No photo found, id = " + contactId + " name = " + name);
    return; // no photo
} else {
    this.type = contactId;
    Log.v("ffnet", "Started uploadcontactphoto: Photo found, id = " + contactId + " name = " + name);
}

...然后用“input”(他们的照片作为 InputStream)、“name”和“contactId”做任何你想做的事情。

以下是列出您可以访问的大约 15 列的文档,只需将它们添加到上面代码开头附近的投影中即可: http://developer.android.com/reference/android/provider/ContactsContract.PhoneLookup.html

【讨论】:

    【解决方案4】:

    此版本与 Vikram.exe 的答案相同,带有避免 ANR 的代码

    interface GetContactNameListener {
        void contactName(String name);
    }
    
    public void getContactName(final String phoneNumber,final GetContactNameListener listener) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                ContentResolver cr = getContentResolver();
                Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
                Cursor cursor = cr.query(uri, new String[]{ContactsContract.PhoneLookup.DISPLAY_NAME}, null, null, null);
                if (cursor == null) {
                    return;
                }
                String contactName = null;
                if(cursor.moveToFirst()) {
                    contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME));
                }
    
                if(cursor != null && !cursor.isClosed()) {
                    cursor.close();
                }
    
                listener.contactName(contactName);
            }
        }).start();
    
    }
    

    【讨论】:

      【解决方案5】:

      通过以下方法传递您从中接听电话的联系号码。此方法将检查联系人是否保存在您的手机中。如果联系人已保存,则返回联系人姓名,否则返回字符串未知号码

      将此代码添加到您的广播接收器类中

          public String getContactDisplayNameByNumber(String number,Context context) {
          Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
          name = "Incoming call from";
      
          ContentResolver contentResolver = context.getContentResolver();
          Cursor contactLookup = contentResolver.query(uri, null, null, null, null);
      
          try {
              if (contactLookup != null && contactLookup.getCount() > 0) {
                  contactLookup.moveToNext();
                  name = contactLookup.getString(contactLookup.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
                  // this.id =
                  // contactLookup.getString(contactLookup.getColumnIndex(ContactsContract.Data.CONTACT_ID));
                  // String contactId =
                  // contactLookup.getString(contactLookup.getColumnIndex(BaseColumns._ID));
              }else{
                  name = "Unknown number";
              }
          } finally {
              if (contactLookup != null) {
                  contactLookup.close();
              }
          }
      
          return name;
      }
      

      获取源码访问this link

      【讨论】:

        【解决方案6】:

        为此,我们可以使用PhoneLookup 提供者通过手机号码获取姓名或联系方式。

        添加AndroidManifest.xml的权限:

        <uses-permission android:name="android.permission.READ_CONTACTS"/>
        

        在您的活动中添加以下自定义 kotlin 方法,并使用所需的手机号码调用该方法。

        fun getContactNameByPhoneNumber(context: Context, phoneNumber: String): String? {
                var phone = phoneNumber
                if(phoneNumber != null && phoneNumber.length > 0 && phoneNumber[0].equals('+'))
                    phone = phoneNumber.substring(3)
        
                val projection = arrayOf(
                    ContactsContract.PhoneLookup.DISPLAY_NAME,
                    ContactsContract.CommonDataKinds.Phone.NUMBER
                )
                val cursor = context.contentResolver.query(
                    ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                    projection,
                    ContactsContract.CommonDataKinds.Phone.NUMBER, null, null
                ) ?: return ""
                for (i in 0 until cursor.count) {
                    cursor.moveToPosition(i)
                    val nameFieldColumnIndex = cursor
                        .getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME)
                    val phoneFieldColumnIndex = cursor
                        .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)
        
                    if(phone.equals(cursor.getString(phoneFieldColumnIndex)))
                        return cursor.getString(nameFieldColumnIndex)
                }
                return "Unknown"
            }
        

        更多:https://developer.android.com/training/contacts-provider/retrieve-names

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-03-16
          • 1970-01-01
          • 1970-01-01
          • 2011-08-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多