如何使用Cursor获取全部联系人并存储为字符串至Firebase实时数据库
使用Cursor获取设备联系人并存储到Firebase实时数据库
嘿,我来帮你搞定用Cursor读取设备联系人并同步到Firebase实时数据库的事儿,下面是完整的实现方案,包括前置准备、步骤和完善后的代码:
前置准备
- 添加权限:首先得在
AndroidManifest.xml里加上读取联系人的权限:
<uses-permission android:name="android.permission.READ_CONTACTS" />
- Firebase配置:确保你的项目已经集成了Firebase实时数据库,并且完成了初始化(比如添加
google-services.json、配置依赖这些基础操作)。
核心实现步骤
- 动态请求权限:因为
READ_CONTACTS属于危险权限,必须在运行时向用户请求授权,只有授权通过后才能读取联系人。 - 读取联系人数据:通过
ContentResolver获取联系人游标,遍历每个联系人,先拿到姓名和ID,再用ID查询对应的电话号码。 - 写入Firebase数据库:把每个联系人的姓名作为节点的键,电话号码作为对应的值,写入Firebase实时数据库。
完整代码示例
import android.Manifest; import android.content.pm.PackageManager; import android.database.Cursor; import android.os.Bundle; import android.provider.ContactsContract; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import com.google.firebase.database.DatabaseReference; import com.google.firebase.database.FirebaseDatabase; public class ContactSyncActivity extends AppCompatActivity { private static final int REQUEST_READ_CONTACTS = 100; private DatabaseReference mRef; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_contact_sync); // 初始化Firebase数据库引用 mRef = FirebaseDatabase.getInstance().getReference("contacts"); // 检查权限,没有的话请求 if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, REQUEST_READ_CONTACTS); } else { // 权限已授权,开始读取联系人 fetchContactsAndSyncToFirebase(); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_READ_CONTACTS) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 用户同意权限,开始读取联系人 fetchContactsAndSyncToFirebase(); } } } private void fetchContactsAndSyncToFirebase() { Cursor cursor = getContentResolver().query( ContactsContract.Contacts.CONTENT_URI, null, null, null, null); if (cursor != null && cursor.getCount() > 0) { while (cursor.moveToNext()) { try { String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID)); String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); String hasPhone = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)); // 检查该联系人是否有电话号码 if (Integer.parseInt(hasPhone) > 0) { // 查询该联系人的所有电话号码 Cursor phones = getContentResolver().query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{contactId}, null); if (phones != null) { while (phones.moveToNext()) { String phoneNumber = phones.getString(phones.getColumnIndex( ContactsContract.CommonDataKinds.Phone.NUMBER)); // 去除电话号码中的特殊字符(可选,根据需求调整) phoneNumber = phoneNumber.replaceAll("[^0-9]", ""); // 将联系人数据写入Firebase mRef.child(name).setValue(phoneNumber); } phones.close(); } } } catch (Exception e) { e.printStackTrace(); } } cursor.close(); } } }
注意事项
- 重复姓名处理:如果有多个联系人姓名相同,后面的会覆盖前面的,你可以考虑用
contactId作为节点键,或者把电话号码存为数组来避免覆盖。 - 性能优化:如果设备联系人很多,建议在异步线程中执行读取和写入操作,避免阻塞主线程导致ANR。
- 异常处理:代码中加入了基本的异常捕获,实际项目中可以根据需求做更细致的错误处理。
内容的提问来源于stack exchange,提问作者Kunal Manocha
相关产品推荐
相关产品推荐

