Flutter Android embedding V2插件中Android Cursor运行失效问题
问题根因
你遇到的游标返回空的核心原因是 Context类型使用错误:
- V1版本
Registrar.context()返回的是当前挂载的FlutterActivity实例作为上下文,有权限访问媒体库查询结果 - V2版本你用了
applicationContext,Android 10+对应用上下文访问共享媒体做了权限限制,同时_data字段本身属于系统私有字段,用应用上下文查询会直接返回空游标
解决方案
1. 替换Context来源
不要使用全局应用上下文,通过ActivityAware接口获取当前Activity实例作为上下文使用,示例代码:
// 插件类实现ActivityAware接口后,添加以下逻辑 private var currentActivity: Activity? = null override fun onAttachedToActivity(binding: ActivityPluginBinding) { currentActivity = binding.activity } override fun onDetachedFromActivityForConfigChanges() { currentActivity = null } override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) { currentActivity = binding.activity } override fun onDetachedFromActivity() { currentActivity = null }
调用工具类时传入Activity实例:
currentActivity?.let { val path = FileDirectory.getAbsolutePath(it, Uri.parse("content://media/external/images/media/41")) }
2. 补充权限校验
调用工具类前先检查存储权限:
- Android 12及以下:申请
READ_EXTERNAL_STORAGE权限 - Android 13及以上:根据文件类型申请
READ_MEDIA_IMAGES/READ_MEDIA_VIDEO/READ_MEDIA_AUDIO权限
没有权限时先发起权限申请,用户授权后再执行查询逻辑。
3. 分区存储适配
如果你的应用targetSdkVersion >= 29,需要在AndroidManifest.xml的application节点添加以下配置,临时兼容旧的_data字段查询逻辑:
<application android:requestLegacyExternalStorage="true" ...> ... </application>
长期来看建议替换废弃的_data字段查询逻辑:拿到Uri后先把对应文件复制到应用私有沙盒目录,再返回沙盒内的绝对路径,适配分区存储规则。
V1插件报错说明
新版本Flutter默认启用V2嵌入,已经移除了V1Registrar的默认实现,因此旧的V1插件会报registrar.context() must not be null错误,直接使用适配完V2的插件版本即可,无需再兼容V1版本插件。
内容的提问来源于stack exchange,提问作者selan
相关产品推荐
相关产品推荐

