Android Studio(Java)获取指定联系人手机号报错求助
问题根源与修复方案
核心问题
你传入getContentResolver().query()的contactUri指向的是联系人主数据表(ContactsContract.Contacts.CONTENT_URI),这个表仅存储联系人的基础信息(如姓名、唯一ID),并不包含电话号码字段——电话号码存在专门的ContactsContract.CommonDataKinds.Phone数据表中,所以cursor里找不到NUMBER列,导致phoneNumberIndex返回-1。
另外你代码里定义了projection数组但查询时传了null,虽然不影响功能,但会查询所有字段,建议传入定义好的projection来优化性能。
修复方案
方案1:直接选择联系人电话记录(推荐)
如果是通过Intent唤起联系人选择器,把Intent的目标Uri改成ContactsContract.CommonDataKinds.Phone.CONTENT_URI,这样返回的Uri直接指向电话记录,无需关联查询:
// 示例:唤起联系人选择器的代码 Intent pickContactIntent = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Phone.CONTENT_URI); // 用ActivityResultLauncher启动(替代已废弃的startActivityForResult) pickContactLauncher.launch(pickContactIntent);
对应的查询代码可以简化为:
ContactInfo contactInfo = null; String[] projection = { ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY, ContactsContract.CommonDataKinds.Phone.NUMBER }; try (Cursor cursor = getContentResolver().query(contactUri, projection, null, null, null)) { if (cursor != null && cursor.moveToFirst()) { String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY)); String phoneNumber = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); contactInfo = new ContactInfo(name, phoneNumber); } } catch (Exception e) { Log.d("Info SMS Error", Arrays.toString(e.getStackTrace())); } Log.d("Info SMS", String.valueOf(contactInfo)); return contactInfo;
方案2:通过联系人ID关联查询电话表
如果必须使用联系人主表的Uri,需要先从主表获取联系人ID,再用ID关联查询电话表:
ContactInfo contactInfo = null; // 1. 从联系人主表获取ID和姓名 String[] contactProjection = { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME_PRIMARY }; try (Cursor contactCursor = getContentResolver().query(contactUri, contactProjection, null, null, null)) { if (contactCursor != null && contactCursor.moveToFirst()) { String contactId = contactCursor.getString(contactCursor.getColumnIndex(ContactsContract.Contacts._ID)); String name = contactCursor.getString(contactCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME_PRIMARY)); // 2. 用联系人ID查询电话表获取号码 String[] phoneProjection = {ContactsContract.CommonDataKinds.Phone.NUMBER}; String selection = ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?"; String[] selectionArgs = {contactId}; try (Cursor phoneCursor = getContentResolver().query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, phoneProjection, selection, selectionArgs, null)) { if (phoneCursor != null && phoneCursor.moveToFirst()) { String phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); contactInfo = new ContactInfo(name, phoneNumber); } } } } catch (Exception e) { Log.d("Info SMS Error", Arrays.toString(e.getStackTrace())); } Log.d("Info SMS", String.valueOf(contactInfo)); return contactInfo;
额外注意事项
- 动态权限检查:Android 6.0(API 23)及以上系统,除了在
AndroidManifest.xml中声明READ_CONTACTS权限,还需要在代码中动态申请权限,确保用户授权后再执行查询操作。 - 多号码处理:部分联系人可能有多个电话号码,上述代码仅获取第一个号码,若需要全部号码,可循环遍历
phoneCursor。
内容的提问来源于stack exchange,提问作者e1k
相关产品推荐
相关产品推荐

