新闻详情

新闻详情

首页 / 资讯中心 / 详情

Android 内容提供器入门:用 ContentResolver 查询数据与权限配置实战

发布时间:2026/9/26 18:05:40来源:尧图网络
Android 内容提供器入门:用 ContentResolver 查询数据与权限配置实战
1. 为什么你查联系人总是返回空 Cursor很多人第一次写 Android 内容提供器相关代码时都会遇到一个很迷惑的现象代码没报错ContentResolver.query()也正常返回了一个 Cursor 对象但getCount()就是 0界面上什么都显示不出来。我试过在模拟器上反复检查 URI、列名、排序参数最后发现真正的问题出在权限上——清单里少了一行uses-permission或者运行时权限没申请系统直接把查询结果过滤成了空集。内容提供器ContentProvider是 Android 四大组件之一它把数据封装成类似数据库表的接口让不同应用之间可以安全地共享数据。而 ContentResolver 就是你作为客户端去访问这些数据的入口。它适合谁适合所有需要在应用之间读写共享数据联系人、媒体库、日历、用户字典等的 Android 开发者尤其是刚接触跨进程数据访问、对 URI 和 Cursor 还不熟的同学。这篇内容我会带你跑通一个最小闭环从清单权限声明到 URI 构造到 ContentResolver 查询再到 Cursor 读取和运行时权限申请最后用一个读取联系人的完整例子验证结果。每一步都给可复制的代码骨架你照着改包名就能用。2. 前置准备权限、URI 和查询四要素在动手写查询之前先把三件事理清楚否则后面报错你会不知道从哪查。第一是权限。内容提供器的读权限分两种一种是普通权限在清单里声明后安装时系统自动授予另一种是危险权限比如读取联系人READ_CONTACTS除了清单声明还必须在运行时动态申请。你查的是哪个提供器就要去它的官方文档里找确切的权限名不能猜。第二是 URI。每个提供器都暴露一个或多个 Content URI格式通常是content://authority/path。比如联系人提供器的ContactsContract.Contacts.CONTENT_URI用户字典的UserDictionary.Words.CONTENT_URI。URI 决定了你访问哪张表。第三是查询四要素对应query()的五个参数URI 之外projection要返回哪些列、selection筛选条件、selectionArgs条件里的占位参数、sortOrder排序。这四样和 SQL 的 SELECT 子句一一对应理解了 SQL 就理解了它。注意查询一定要放在子线程或异步任务里执行主线程查询大数据量会触发 ANR。本文为了演示清晰用同步写法实际项目请用 CursorLoader 或协程。3. 可复制配置清单权限与查询代码骨架3.1 清单文件声明权限以读取联系人为例在AndroidManifest.xml的manifest下、application外添加uses-permission android:nameandroid.permission.READ_CONTACTS /如果你还要写数据再加WRITE_CONTACTS。声明之后普通权限安装即授予危险权限还需要下一步的运行时申请。3.2 构造查询并读取 Cursor下面是一个查询联系人姓名和 ID 的骨架注意 projection 里必须包含_ID列否则后面配合 SimpleCursorAdapter 会直接崩// 1. 定义要返回的列 String[] projection { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME }; // 2. 筛选条件只取有电话号码的联系人 String selection ContactsContract.Contacts.HAS_PHONE_NUMBER ?; String[] selectionArgs { 1 }; // 3. 排序 String sortOrder ContactsContract.Contacts.DISPLAY_NAME ASC; // 4. 执行查询 Cursor cursor getContentResolver().query( ContactsContract.Contacts.CONTENT_URI, projection, selection, selectionArgs, sortOrder ); // 5. 读取结果 if (cursor ! null) { int idIndex cursor.getColumnIndex(ContactsContract.Contacts._ID); int nameIndex cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME); while (cursor.moveToNext()) { String id cursor.getString(idIndex); String name cursor.getString(nameIndex); Log.d(ContactQuery, id id , name name); } cursor.close(); // 必须关闭否则泄漏 } else { Log.e(ContactQuery, cursor is null, 查询失败); }这里 selection 用了?占位符加 selectionArgs而不是把用户输入拼进字符串。这是防 SQL 注入的关键用户输入被当作参数绑定不会被解释成 SQL 语句。如果你写成name userInput恶意输入就可能拼出破坏性语句。3.3 运行时权限申请Android 6.0 起危险权限必须动态申请。在查询前检查并请求if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) ! PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions( this, new String[]{ Manifest.permission.READ_CONTACTS }, REQUEST_CODE_READ_CONTACTS); } else { queryContacts(); // 已授权直接查 }然后在onRequestPermissionsResult里根据授权结果决定是否继续查询。授权通过再调用查询方法否则提示用户。4. 验证请求跑通一次完整的联系人读取把上面的代码串起来完整流程是这样的先在 Activity 的onCreate里调用权限检查逻辑。用户点允许后onRequestPermissionsResult收到PERMISSION_GRANTED触发queryContacts()。查询返回 Cursor 后遍历打印日志。实测下来在模拟器里预置几个联系人运行后 Logcat 会输出类似D/ContactQuery: id1, nameAlice D/ContactQuery: id2, nameBob D/ContactQuery: id3, nameCarol如果你想把结果直接显示到列表可以用 SimpleCursorAdapter 绑定 ListView但记得 Cursor 必须含_ID列String[] fromColumns { ContactsContract.Contacts.DISPLAY_NAME }; int[] toViews { android.R.id.text1 }; SimpleCursorAdapter adapter new SimpleCursorAdapter( this, android.R.layout.simple_list_item_1, cursor, fromColumns, toViews, 0); listView.setAdapter(adapter);看到列表里出现联系人名字就说明从提供器获取数据的最小闭环跑通了。整个过程的核心就是权限到位、URI 正确、projection 含_ID、Cursor 及时关闭。5. 本篇常见错排查查询返回 null部分提供器内部出错时返回 null另一些直接抛异常。先判空再使用别直接cursor.getCount()。getCount() 为 0 但数据明明存在九成是权限问题。检查清单权限名是否拼错、运行时权限是否真的授予。可以在设置里手动看应用权限状态。列名找不到getColumnIndex 返回 -1projection 里没写这一列或者列名拼错。用getColumnIndexOrThrow()能在开发期直接暴露问题。配合 ListView 崩溃Cursor 缺少_ID列。SimpleCursorAdapter 强制要求结果集里有_ID查询时务必带上。主线程查询卡顿或 ANR把查询放到子线程、CursorLoader 或协程里别在主线程做大数据量遍历。SQL 注入风险永远用?加 selectionArgs不要字符串拼接用户输入。6. 接入与调试把查询能力接到实际工程如果你在本地调试时想快速验证某个提供器的返回结构或者需要对比不同模型给出的查询代码是否正确可以借助在线工具做交叉验证。我平时会把查询逻辑和报错信息整理好用模型对话快速定位是 URI 写错还是权限漏了省去反复翻文档的时间。对于需要长期写 Android 代码、频繁调试 ContentResolver 和权限逻辑的场景可以考虑用 Coding Plan 把这类重复性的代码骨架生成和排错固化下来减少手动试错。具体入口想直接对话验证查询代码和报错模型对话 https://taotoken.net/api?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite长期编码与 Agent 工作流Coding Plan https://taotoken.net/api?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite生成和管理接入密钥API Keys https://taotoken.net/api?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite接入文档与参数说明接入文档 https://taotoken.net/api?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite官网入口https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content最后留一个实用习惯每次写完查询先在 Logcat 里打印cursor.getColumnNames()确认返回的列和你 projection 里写的一致。这一步能帮你提前发现大部分列名不匹配的问题比等到界面空白再回头查要快得多。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Web of Science高被引论文快速验证:URL结构化检索实战指南 2026/9/26 19:43:40

Web of Science高被引论文快速验证:URL结构化检索实战指南

1. 这不是“查论文”,而是一场高被引身份的快速验证你刚收到一封邮件,说你的某篇论文被Web of Science标记为“ESI高被引论文”;或者你在学术社交平台看到别人晒出“Top 1% Highly Cited”的徽章,心里一动:我那篇2021年…

阅读更多 →
treg:多CLI Agent时代的配置注册表管理工具 2026/9/26 19:43:40

treg:多CLI Agent时代的配置注册表管理工具

1. 从“treg”这个标题说起:一个被低估的CLI工具入口第一次看到“treg”这个词,很多人会愣一下——它不像codex cli、claude cli那样一眼能看出用途,也不像mcp那样有明确的协议含义。我最初接触到它,是在折腾 OpenRouter 的 API K…

阅读更多 →
莆仙话语音翻译应用的网页与微信小程序双端设计实践 2026/9/26 19:43:28

莆仙话语音翻译应用的网页与微信小程序双端设计实践

莆仙话属于低资源方言。与普通话相比,可直接用于语音识别、文本归一化和语音合成的数据更少,莆田、仙游等地区的口音差异也会影响识别结果。因此,把方言语音翻译做成可日常使用的产品,难点不只在模型,还包括录音交互、…

阅读更多 →
本地部署与API场景下如何下载旧版本:版本回退完整指南 2026/9/26 19:43:28

本地部署与API场景下如何下载旧版本:版本回退完整指南

1. 为什么会有“下载旧版本”这个需求先把话说在前头:绝大多数普通用户其实不需要旧版本。新版本通常修了bug、补了安全漏洞、优化了推理速度,除非你遇到了明确的兼容性问题或者功能回退,否则没必要折腾。但现实里确实有几类人会被迫去找旧版…

阅读更多 →
video-use:用ffmpeg和Claude Code搭建自动化视频处理流水线 2026/9/26 19:42:49

video-use:用ffmpeg和Claude Code搭建自动化视频处理流水线

1. 从“video-use”这个标题说起:它到底想解决什么问题第一次看到“video-use”这个标题,我脑子里蹦出来的不是某个具体工具,而是一类需求:用代码和命令行把视频处理这件事自动化起来。结合热搜词里高频出现的 Claude Code、ffmpe…

阅读更多 →
Substrate区块链开发框架入门:从核心概念到本地链实操 2026/9/26 19:42:43

Substrate区块链开发框架入门:从核心概念到本地链实操

1. 从零认识 Substrate:它到底是什么,能解决什么问题第一次听到 Substrate 这个词,很多人会以为是某个前端框架或者构建工具。其实不是。Substrate 是一个用于构建区块链的开发框架,由 Parity Technologies 团队打造,最…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉