读取全部收藏联系人号码失败问题咨询
读取Android收藏联系人的所有号码解决方案
我明白你要读取3个收藏联系人的全部6个号码,你的代码开头已经有了基础的导入,我来帮你补全并优化完整的实现逻辑,确保能正确获取到所有收藏联系人的所有号码。
第一步:添加必要权限
首先要在AndroidManifest.xml里声明读取联系人的权限:
<uses-permission android:name="android.permission.READ_CONTACTS" />
注意Android 6.0(API 23)及以上版本,还需要在代码中动态申请权限,否则会直接拒绝访问。
第二步:完整实现代码
下面是补全后的完整代码,包含了查询收藏联系人、获取对应所有号码的逻辑:
import android.annotation.SuppressLint import android.content.Context import android.provider.ContactsContract import android.provider.ContactsContract.Contacts import android.provider.ContactsContract.CommonDataKinds.Phone import android.util.Log class ContactUtils { private val TAG = "ContactUtils" @SuppressLint("Range") fun getStarredContactsWithAllNumbers(context: Context): List<String> { val allStarredNumbers = mutableListOf<String>() // 1. 查询所有收藏的联系人(STARRED=1),且确保该联系人有电话号码(HAS_PHONE_NUMBER=1) val starredContactsCursor = context.contentResolver.query( Contacts.CONTENT_URI, arrayOf(Contacts._ID, Contacts.DISPLAY_NAME), "${Contacts.STARRED} = ? AND ${Contacts.HAS_PHONE_NUMBER} = ?", arrayOf("1", "1"), null ) starredContactsCursor?.let { cursor -> while (cursor.moveToNext()) { val contactId = cursor.getString(cursor.getColumnIndex(Contacts._ID)) val contactName = cursor.getString(cursor.getColumnIndex(Contacts.DISPLAY_NAME)) Log.d(TAG, "收藏联系人:$contactName") // 2. 根据contactId查询该联系人的所有电话号码 val phoneCursor = context.contentResolver.query( Phone.CONTENT_URI, arrayOf(Phone.NUMBER), "${Phone.CONTACT_ID} = ?", arrayOf(contactId), null ) phoneCursor?.let { phone -> while (phone.moveToNext()) { val phoneNumber = phone.getString(phone.getColumnIndex(Phone.NUMBER)) // 可以对号码做格式化处理,比如去掉空格、特殊符号 val formattedNumber = phoneNumber.replace(Regex("[^0-9+]"), "") allStarredNumbers.add(formattedNumber) Log.d(TAG, "号码:$formattedNumber") } phone.close() } } cursor.close() } return allStarredNumbers } }
第三步:调用方法并处理权限
在你的Activity里,需要先申请权限,再调用这个方法:
import android.Manifest import android.content.pm.PackageManager import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat class MainActivity : AppCompatActivity() { private val REQUEST_READ_CONTACTS = 1001 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 检查权限 if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED ) { ActivityCompat.requestPermissions( this, arrayOf(Manifest.permission.READ_CONTACTS), REQUEST_READ_CONTACTS ) } else { // 权限已获取,读取收藏联系人号码 val contactUtils = ContactUtils() val starredNumbers = contactUtils.getStarredContactsWithAllNumbers(this) Log.d("MainActivity", "所有收藏号码:$starredNumbers") // 这里可以处理获取到的6个号码 } } override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<out String>, grantResults: IntArray ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == REQUEST_READ_CONTACTS) { if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 用户同意权限,读取号码 val contactUtils = ContactUtils() val starredNumbers = contactUtils.getStarredContactsWithAllNumbers(this) Log.d("MainActivity", "所有收藏号码:$starredNumbers") } else { // 用户拒绝权限,提示需要权限才能读取联系人 Log.d("MainActivity", "需要读取联系人权限才能获取收藏号码") } } } }
关键逻辑说明
- 第一次查询
Contacts.CONTENT_URI是为了筛选出所有已收藏(STARRED=1)且有电话号码的联系人,拿到每个联系人的contactId。 - 第二次查询
Phone.CONTENT_URI是通过contactId关联,获取该联系人下的所有电话号码,这样就能拿到每个收藏联系人的全部号码(比如你说的每个2个,总共6个)。 - 代码里对号码做了格式化处理,去掉了非数字和加号的字符,避免不同格式的号码干扰。
内容的提问来源于stack exchange,提问作者Hasan A Yousef
相关产品推荐
相关产品推荐

