You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

部分Android设备中添加联系人Intent未在onActivityResult返回数据

问题分析与解决方案

你遇到的是厂商定制ROM的行为差异——索尼Xperia的系统联系人应用在完成联系人插入后,没有遵循标准Android规范返回包含新联系人Uri的Intent data,虽然返回了RESULT_OK(即-1),但data为null。这是定制ROM里很常见的兼容性问题,下面给你几个可行的解决思路:

1. 调整Intent的构造方式

你当前的Intent同时设置了ACTION_INSERT和setType(ContactsContract.Contacts.CONTENT_TYPE),部分厂商的应用对这种组合的处理不符合标准。可以尝试简化Intent的构造逻辑:

private void addContactUsingIntent() {
    Intent intent = new Intent(ContactsContract.Intents.Insert.ACTION);
    intent.setType(ContactsContract.RawContacts.CONTENT_TYPE);
    // 如果需要提前填充联系人信息,可以在这里添加extra参数
    // intent.putExtra(ContactsContract.Intents.Insert.NAME, "预设姓名");
    // intent.putExtra(ContactsContract.Intents.Insert.PHONE, "预设电话");
    intent.putExtra(Intent.EXTRA_FINISH_ON_COMPLETION, true);
    startActivityForResult(intent, INSERT_CONTACT_REQUEST);
}

使用ContactsContract.Intents.Insert.ACTION是官方推荐的插入联系人的Intent构造方式,兼容性会更好。

2. 当data为null时,查询最新添加的联系人

既然resultCode == RESULT_OK,说明联系人已经成功保存,我们可以直接通过Contacts Provider查询最近创建的联系人来获取数据:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == INSERT_CONTACT_REQUEST) {
        if (resultCode == RESULT_OK) {
            Uri contactData = data.getData();
            long newId = -1;
            String name = "";

            // 处理data为null的情况
            if (contactData == null) {
                // 按创建时间倒序查询,取最新的一条联系人
                String[] projection = {
                    ContactsContract.Contacts._ID,
                    ContactsContract.Contacts.DISPLAY_NAME
                };
                String sortOrder = ContactsContract.Contacts.CREATED_TIMESTAMP + " DESC LIMIT 1";
                Cursor cursor = getContentResolver().query(
                    ContactsContract.Contacts.CONTENT_URI,
                    projection,
                    null,
                    null,
                    sortOrder
                );
                if (cursor != null && cursor.moveToFirst()) {
                    newId = cursor.getLong(cursor.getColumnIndexOrThrow(ContactsContract.Contacts._ID));
                    name = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME));
                    cursor.close();
                }
            } else {
                // 原有处理data不为null的逻辑
                Cursor cursor = getContentResolver().query(contactData, null, null, null, null);
                if (cursor.moveToFirst()) {
                    newId = cursor.getLong(cursor.getColumnIndexOrThrow(ContactsContract.Contacts._ID));
                    name = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME));
                    cursor.close();
                }
            }

            // 如果成功获取到联系人ID,继续获取电话、邮箱等信息
            if (newId != -1) {
                String email = getEmail(String.valueOf(newId));
                ArrayList<String> phones = new ArrayList<>();
                Cursor cPhones = getContentResolver().query(
                    ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                    null,
                    ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
                    new String[]{String.valueOf(newId)},
                    null
                );
                while (cPhones.moveToNext()) {
                    phones.add(cPhones.getString(cPhones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
                }
                cPhones.close();
                Uri photoUri = getPhotoUri(newId);
                Log.i("Photo URI", photoUri.toString());
                updateViews(newId, name, phones, email, photoUri);
            }
        }
    }
}

注意:这个方法依赖CREATED_TIMESTAMP字段,Android 3.0(API 11)及以上支持,你的设备都是Android 6.0,完全没问题。另外要确保已经申请了READ_CONTACTS的动态权限(Android 6.0及以上需要)。

3. 直接使用Contacts Provider插入联系人(最可控)

如果依赖系统Intent的兼容性问题始终无法解决,可以跳过系统联系人应用,直接通过ContentResolver插入联系人,这样完全不受厂商ROM的影响:

private void addContactDirectly(String name, String phone, String email) {
    // 1. 插入RawContact
    ContentValues values = new ContentValues();
    Uri rawContactUri = getContentResolver().insert(ContactsContract.RawContacts.CONTENT_URI, values);
    long rawContactId = ContentUris.parseId(rawContactUri);

    // 2. 插入姓名
    values.clear();
    values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
    values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
    values.put(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name);
    getContentResolver().insert(ContactsContract.Data.CONTENT_URI, values);

    // 3. 插入电话(如果有)
    if (!TextUtils.isEmpty(phone)) {
        values.clear();
        values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
        values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
        values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone);
        values.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
        getContentResolver().insert(ContactsContract.Data.CONTENT_URI, values);
    }

    // 4. 插入邮箱(如果有)
    if (!TextUtils.isEmpty(email)) {
        values.clear();
        values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
        values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE);
        values.put(ContactsContract.CommonDataKinds.Email.ADDRESS, email);
        values.put(ContactsContract.CommonDataKinds.Email.TYPE, ContactsContract.CommonDataKinds.Email.TYPE_WORK);
        getContentResolver().insert(ContactsContract.Data.CONTENT_URI, values);
    }

    // 5. 获取对应的Contact ID并更新界面
    Cursor cursor = getContentResolver().query(
        ContactsContract.RawContacts.CONTENT_URI,
        new String[]{ContactsContract.RawContacts.CONTACT_ID},
        ContactsContract.RawContacts._ID + " = ?",
        new String[]{String.valueOf(rawContactId)},
        null
    );
    if (cursor != null && cursor.moveToFirst()) {
        long contactId = cursor.getLong(0);
        cursor.close();
        ArrayList<String> phonesList = new ArrayList<>();
        phonesList.add(phone);
        Uri photoUri = getPhotoUri(contactId);
        updateViews(contactId, name, phonesList, email, photoUri);
    }
}

这种方法需要申请WRITE_CONTACTS动态权限,但好处是完全可控,不会受到任何厂商ROM的限制。

额外注意事项

  • 务必在AndroidManifest.xml中声明必要权限:
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
  • Android 6.0及以上需要动态申请这些权限,在调用相关代码前一定要检查权限是否已授予。

内容的提问来源于stack exchange,提问作者Travolta John

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:48:14