能否绕过ArrayMap.containsKey()校验更新RawContacts的contact_id字段
解决方案
前提说明
系统原生updateRawContacts方法的第一层校验逻辑与调用方身份无关,只要ContentValues中包含RawContacts.CONTACT_ID键就会直接抛出异常,没有办法在不修改系统源码、不获取root权限的前提下直接传入该键绕过校验。
合法实现方案
如果确实需要调整RawContact关联的contact_id,可选择以下两种适配系统设计的方案实现:
- 方案1:使用系统官方提供的关联接口(无需特殊权限,第三方普通应用可直接使用)
安卓联系人框架专门提供了affiliate接口用于调整RawContact绑定的ContactID,不需要直接调用原始的update接口,构造请求的代码如下:
// 单次请求写法 ContentValues values = new ContentValues(); values.put(RawContacts._ID, 待修改的rawContactId); values.put(RawContacts.CONTACT_ID, 目标contactId); getContentResolver().update( RawContacts.CONTENT_URI.buildUpon().appendPath("affiliate").build(), values, null, null ); // 适配你当前的ContentProviderOperation批量操作写法 ContentProviderOperation.newUpdate( RawContacts.CONTENT_URI.buildUpon().appendPath("affiliate").build() ) .withValue(RawContacts._ID, 待修改的rawContactId) .withValue(RawContacts.CONTACT_ID, 目标contactId) .build();
- 方案2:Root后直接操作底层数据库(仅适合ROM开发、调试场景使用)
如果有设备的root权限,可以直接绕过ContentProvider校验,操作联系人数据库contacts2.db的raw_contacts表直接更新:
UPDATE raw_contacts SET contact_id = 目标contactId WHERE _id = 待修改的rawContactId;
注意事项
不要尝试用反射、恶意参数注入等方式绕过ContentProvider的原生校验,这类方案在安卓7.0及以上版本系统权限收紧后完全不可用,还会触发系统安全检测导致应用闪退、被系统标记为恶意应用。
内容的提问来源于stack exchange,提问作者124697
相关产品推荐
相关产品推荐

