Android中cursor.getColumnIndex(Phone.NUMBER)返回-1问题求助
为什么Android 12真机上获取联系人号码时
getColumnIndex返回-1,模拟器却正常? 问题原因
ROM定制差异
模拟器运行的是原生Android系统,而用户的真机大概率是搭载了定制ROM(如小米、华为、OPPO等厂商的系统)。这类定制ROM对联系人ContentProvider的实现可能与原生系统存在差异:当你用query(contactData, null, null, null, null)请求所有列时,定制ROM可能不会返回ContactsContract.CommonDataKinds.Phone.NUMBER列,直接导致getColumnIndex返回-1。未明确指定查询列
使用null作为投影参数(即请求所有列)属于不规范写法,Android系统并不保证会返回所有可用列,不同设备、ROM的返回结果可能存在不一致,模拟器的原生环境刚好返回了所需列,但真机的定制环境没有。代码潜在bug
你代码中关闭Cursor的语句写的是c.close(),但Cursor对象的变量名是cursor,这会导致编译或运行时异常,虽不是当前崩溃的直接原因,但也是需要修复的问题。
修复后的代码
private void onClick(){ Intent pickContact = new Intent(Intent.ACTION_PICK); pickContact.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE); startActivityForResult(pickContact, CONTACT_PICK_CODE); } protected void onActivityResult (int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == Activity.RESULT_OK && requestCode == CONTACT_PICK_CODE) { Uri contactData = data.getData(); // 明确指定需要查询的列,避免系统返回列不全 String[] projection = new String[]{ ContactsContract.CommonDataKinds.Phone.NUMBER }; Cursor cursor = getContentResolver().query(contactData, projection, null, null, null); if (cursor != null && cursor.moveToFirst()) { int phoneIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER); // 增加索引有效性判断,防止崩溃 if (phoneIndex != -1) { String number = cursor.getString(phoneIndex); // 这里处理获取到的号码逻辑 } cursor.close(); } } }
额外注意事项
- 权限检查:确保已申请并获取
READ_CONTACTS权限,Android 6.0及以上需要动态申请,虽然这不是当前崩溃的直接原因,但缺失权限会导致后续操作异常。 - 空值防御:增加
cursor是否为null的判断,避免空指针异常;同时对phoneIndex的有效性做校验,从根源上避免因索引无效导致的崩溃。
内容的提问来源于stack exchange,提问作者Alessandro
相关产品推荐
相关产品推荐

