ContentResolver query方法无法使用,API版本适配问题求助
解决ContentResolver#query API级别兼容问题
嘿,我来帮你搞定这个问题!你遇到的报错是因为你调用的ContentResolver#query方法是Android 8.0(API 26)才新增的重载版本,但你的项目最低兼容API 16,所以编译器会阻止你使用它。虽然你参考的教程API版本更低,但大概率是教程里用的是旧版的query重载,而你不小心用了新的。
两种解决方法:
1. 直接使用兼容所有旧版本的query重载
最省事的方式是改用从API 1就存在的经典query签名,完全适配你的minSdk 16:
// 在onCreate里的示例代码 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 确保已经申请了READ_CONTACTS权限(API23+需要动态申请) if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) { // 兼容API1+的query调用 Cursor cursor = getContentResolver().query( ContactsContract.Contacts.CONTENT_URI, // 你需要查询的字段 new String[]{ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME}, // 查询条件(比如筛选特定联系人),不需要就传null null, // 条件参数,不需要就传null null, // 排序规则 ContactsContract.Contacts.DISPLAY_NAME + " ASC" ); // 处理cursor数据... if (cursor != null) { while (cursor.moveToNext()) { String contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); // 做你需要的操作 } cursor.close(); } } else { // 请求动态权限 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, 1001); } }
2. 版本适配(如果一定要用API26+的新方法)
如果你想使用API26新增的带Bundle或CancellationSignal的query重载,可以通过版本判断来兼容:
Cursor cursor; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // API26及以上使用新的query方法 Bundle queryArgs = new Bundle(); // 设置排序参数 queryArgs.putString(ContentResolver.QUERY_ARG_SORT_COLUMNS, ContactsContract.Contacts.DISPLAY_NAME); queryArgs.putInt(ContentResolver.QUERY_ARG_SORT_DIRECTION, ContentResolver.QUERY_SORT_DIRECTION_ASCENDING); cursor = getContentResolver().query( ContactsContract.Contacts.CONTENT_URI, new String[]{ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME}, queryArgs, null // CancellationSignal,不需要就传null ); } else { // API26以下回退到旧方法 cursor = getContentResolver().query( ContactsContract.Contacts.CONTENT_URI, new String[]{ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME}, null, null, ContactsContract.Contacts.DISPLAY_NAME + " ASC" ); } // 后续处理cursor...
额外提醒:权限问题
别忘了读取联系人需要READ_CONTACTS权限,在Android 6.0(API23)及以上必须动态申请权限,不然即使代码编译通过,运行时也会崩溃或者拿不到数据。
内容的提问来源于stack exchange,提问作者Erika
相关产品推荐
相关产品推荐

