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

Android通过ContactsContract用联系人ID查手机号报参数空错误如何解决?

错误原因
  • 核心错误是你传入getSuspectPhoneNumber方法的contactId参数为null,导致执行SQL查询时占位符?对应的绑定值为空,抛出IllegalArgumentException: the bind value at index 1 is null异常。
  • 具体触发逻辑:你在onActivityResult中仅存储了选中联系人的姓名,没有将对应的联系人ID持久化存储到mCrime对象或Fragment成员变量中。当你异步申请通讯录权限、用户点击同意后触发onRequestPermissionsResult回调时,onActivityResult返回的Intent数据已经不在当前上下文里,无法再获取到之前选中的联系人ID,调用updateSuspectNumber时传入了空的contactId。
修复方案
  1. 扩展Crime类存储联系人ID
    给Crime实体类新增suspectContactId字段及对应的get、set方法,用于持久化存储选中的联系人ID:
public class Crime {
    // 保留原有字段
    private String mSuspectContactId;

    public String getSuspectContactId() {
        return mSuspectContactId;
    }

    public void setSuspectContactId(String suspectContactId) {
        mSuspectContactId = suspectContactId;
    }
}
  1. 修改onActivityResult逻辑,同时保存姓名和联系人ID
    在选择联系人返回后,同时取出联系人姓名和ID存入mCrime:
} else if (requestCode == REQUEST_CONTACT && data != null){
    Uri contactUri = data.getData();
    String[] queryFields = new String[] {
        ContactsContract.Contacts.DISPLAY_NAME,
        ContactsContract.Contacts._ID
    };
    Cursor c = getActivity().getContentResolver().query(contactUri, queryFields, null, null, null);
    try {
        if (c == null || c.getCount() == 0) {
            return;
        }
        c.moveToFirst();
        String suspectName = c.getString(0);
        String contactId = c.getString(1);
        mCrime.setSuspect(suspectName);
        mCrime.setSuspectContactId(contactId);
        mSuspectButton.setText(suspectName);

        if (hasContactsPermission()){
            updateSuspectNumber(); 
        } else{
            requestPermissions(CONTACTS_PERMISSIONS,REQUEST_CONTACTS_PERMISSIONS);
        }
    } finally {
        if (c != null) {
            c.close();
        }
    }
}
  1. 给查询逻辑增加空判断,优化Cursor遍历
    首先在updateSuspectNumber中先判断contactId是否为空,同时优化getSuspectPhoneNumber方法的边界处理:
private void updateSuspectNumber() {
    String contactId = mCrime.getSuspectContactId();
    // 空值直接返回,避免触发查询异常
    if (TextUtils.isEmpty(contactId) || getActivity() == null) {
        return;
    }
    String phoneNumber = getSuspectPhoneNumber(contactId);
    // 后续自有业务逻辑
}

private String getSuspectPhoneNumber(String contactId){
    String suspectPhoneNumber=null;
    Uri phoneContactUri= ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
    String[] queryFields= new String[] {
            ContactsContract.CommonDataKinds.Phone.NUMBER,
            ContactsContract.CommonDataKinds.Phone.TYPE};
    String mSelectionClause= ContactsContract.Data.CONTACT_ID + "=?";
    String mSelectionArgs[] ={ contactId };

    Cursor c= getActivity().getContentResolver().
            query(phoneContactUri,queryFields,mSelectionClause,mSelectionArgs,null);

    try {
        if (c == null || c.getCount() == 0) {
            return null;
        }
        // 遍历所有号码,找到手机号类型再返回
        while (c.moveToNext()) {
            int phoneType=c.getInt(c.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.TYPE));
            if (phoneType==ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE) {
                suspectPhoneNumber=c.getString(c.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
                break;
            }
        }
    }finally {
        if (c != null) {
            c.close(); 
        }
    }
    return suspectPhoneNumber;
}

内容的提问来源于stack exchange,提问作者Ganeshvaran Letchumanan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 14:48:04