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

跨应用通过ContentProvider共享数据失败,查询返回Cursor为null求助

跨应用通过ContentProvider共享数据失败,查询返回Cursor为null求助

兄弟,我仔细看了你的代码和描述,发现几个很可能导致cursor为null的问题,咱们一个个来排查:

  • 最显眼的拼写错误!这大概率是核心问题
    你在第二个App里构建的URI是content://com.example.storge,但第一个App的Manifest里声明的ContentProvider authorities是com.example.storage——注意看,storge少了一个字母a!正确的应该是storage。这个拼写错误会让系统找不到对应的ContentProvider,自然返回null的cursor。先把这个改了试试!

  • Android 11+的跨应用访问限制
    如果你的测试设备是Android 11(API 30)及以上版本,第二个App需要在Manifest中添加<queries>标签,明确声明要访问的第一个App的ContentProvider权限,否则系统会默认阻止跨应用的访问请求:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="你的第二个App包名">
    
        <queries>
            <provider android:authorities="com.example.storage" />
        </queries>
    
        <!-- 其他Manifest内容 -->
    </manifest>
    
  • ContentProvider缺少URI匹配逻辑(规范优化)
    你的Provider类没有使用UriMatcher来校验传入的URI,虽然当前只处理一张表,但没有匹配逻辑的话,后续扩展或者URI写错时更容易出问题。可以按下面的方式优化你的Provider:

    class Provider : ContentProvider() {
        private lateinit var db: LoginSqliteHelper
        private val uriMatcher = UriMatcher(UriMatcher.NO_MATCH)
        
        companion object {
            private const val TABLE_QUERY_CODE = 1
            // 定义标准的CONTENT_URI
            const val CONTENT_URI = "content://com.example.storage/${ConstantValue.Table_Name}"
        }
    
        override fun onCreate(): Boolean {
            db = LoginSqliteHelper(context!!)
            // 添加URI匹配规则,指定匹配我们的表
            uriMatcher.addURI("com.example.storage", ConstantValue.Table_Name, TABLE_QUERY_CODE)
            return true
        }
    
        override fun query(
            uri: Uri,
            projection: Array<out String>?,
            selection: String?,
            selectionArgs: Array<out String>?,
            sortOrder: String?
        ): Cursor? {
            // 先匹配URI,只有合法的URI才处理
            return when (uriMatcher.match(uri)) {
                TABLE_QUERY_CODE -> {
                    db.readableDatabase.query(
                        ConstantValue.Table_Name,
                        projection,
                        selection,
                        selectionArgs,
                        null,
                        null,
                        sortOrder
                    )
                }
                else -> null // 不匹配的URI直接返回null
            }
        }
    
        // 其他方法保持不变...
    }
    

    之后第二个App里的URI就可以直接用Uri.parse(Provider.CONTENT_URI)(如果能引用到第一个App的常量的话),或者写content://com.example.storage/你的表名,这样更规范,也不容易出错。

  • 确认第一个App的数据库中确实存在数据
    虽然你说第一个App一切正常,但还是建议在第一个App里直接查询自己的数据库,确认目标表中确实有数据。如果数据库本身是空的,查询返回的cursor会是空的(但不是null),不过先排除这个可能性。

先从第一个拼写错误入手修改,应该能解决大部分问题,要是还有问题再依次排查后面的点!

备注:内容来源于stack exchange,提问作者ANAS AHMED

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.17 11:50:29