Android:从电话号码中检索联系人姓名
我想检索与传入电话号码关联的联系人的姓名。当我在broascastreceiver中处理传入号码时,拥有一个带有传入调用方名称的字符串将极大地帮助我的项目Android:从电话号码中检索联系人姓名,android,android-contacts,phone-number,contactscontract,Android,Android Contacts,Phone Number,Contactscontract,我想检索与传入电话号码关联的联系人的姓名。当我在broascastreceiver中处理传入号码时,拥有一个带有传入调用方名称的字符串将极大地帮助我的项目 我认为这涉及到使用SQLWHERE子句作为过滤器的查询,但是我需要对联系人进行排序吗?一个示例或提示将非常有帮助。为此,您需要使用优化的PhoneLookup提供程序,如前所述 将权限添加到AndroidManifest.xml: <uses-permission android:name="android.permission.REA
我认为这涉及到使用SQLWHERE子句作为过滤器的查询,但是我需要对联系人进行排序吗?一个示例或提示将非常有帮助。为此,您需要使用优化的PhoneLookup提供程序,如前所述 将权限添加到
AndroidManifest.xml
:
<uses-permission android:name="android.permission.READ_CONTACTS"/>
这非常有帮助,以下是我检索来电者姓名、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);
}
。。。然后只需使用“输入”(他们的照片作为输入流)、“姓名”和“联系人ID”即可
下面是列出您可以访问的大约15列的文档,只需将它们添加到上面代码开头附近的投影中即可:
虽然已经回答了这个问题,但下面是从号码中获取联系人姓名的完整功能。希望它能帮助其他人:
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;
}
[根据马库斯的评论进行更新]
您必须申请此许可:
此版本与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();
}
通过以下方法传递您接到呼叫的联系人号码。此方法将检查联系人是否保存在手机中。如果联系人已保存,则将返回联系人姓名,否则将返回字符串未知号码 在广播接收器类中添加此代码
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;
}
要获取源代码,请立即访问开发页面,感谢您的快速响应。Uri中的toString()方法应该将此查询转换为联系人名称?不,不会。您必须自己解析光标。要获得一些帮助,请检查以下问题:我将使用URI使用managedQuery初始化游标,然后将游标移动到第一个位置并获取数据?一旦光标位于第一个位置,我就使用getString?我假设第一个位置是正确的,因为查询是针对一个数字的,因此查询将只提取该数字的名称?该查询的其余部分具体是什么?这个答案并不比已经存在的文档更有帮助。你应该用完整的代码来回答。查询后如何迭代并获取名称。初学者不能理解这两行。您应该使返回基于numberrit的名称的函数在恢复活动时使应用程序“不负责”。我应该怎么做呢?我每次在Android 5.1上运行时都会得到ANR,很可能你需要在UI线程以外的线程上运行ANR。值得一提的是,这需要
权限您好,我尝试了类似的方法,但没有成功。这是我的问题,我非常感谢你的帮助!:)为了方便他人,我写了一篇文章,其中包含了查询姓名、照片、联系人ID等的完整代码,并给出了合理的解释。代码包含不同答案上的代码片段,但更具组织性和测试性。链接:
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;
}