Flutter发布版sqflite与image_picker功能异常,debug模式运行正常
正式版sqflite、image_picker存储功能异常排查指南
核心根因排查清单
- Android 13+(API 33)权限适配错位
android:requestLegacyExternalStorage="true"仅对Android 10-12版本生效,在targetSdk 33及以上的版本中该属性会被系统完全忽略。传统的WRITE_EXTERNAL_STORAGE、READ_EXTERNAL_STORAGE全量存储权限在该版本上无法获得有效授权,需要按媒体类型拆分配置:<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> - Release构建混淆裁剪逻辑
Debug版本默认关闭R8/ProGuard混淆,功能运行正常;正式版开启混淆后如果漏配keep规则,会导致sqflite的数据库读写逻辑、image_picker的权限申请流程被静默裁剪,出现无报错的功能失效。需要在proguard-rules.pro中补充规则:-keep class com.tekartik.sqflite.** { *; } -keep class io.flutter.plugins.imagepicker.** { *; } - Google Play权限政策拦截
如果应用声明了MANAGE_EXTERNAL_STORAGE这类高危权限,Google Play在正式版分发时会直接拦截该权限的授予流程,无论代码中如何发起申请,用户端都会直接返回权限拒绝结果,不会唤起系统授权弹窗。 - 硬编码公共存储路径
sqflite如果硬编码/storage/emulated/0/xxx这类公共目录绝对路径做数据库存储,image_picker如果硬写公共目录做缓存路径,在Android 11+分区存储规则下,正式版没有Debug版本的临时权限豁免,会直接抛出IO读写异常,表现和权限不足完全一致。
分步验证操作
- 核对项目配置的
targetSdkVersion,不再依赖requestLegacyExternalStorage做长期适配,该属性在targetSdk 34及以上版本中已被Google完全废弃,无实际作用。 - 临时关闭Release构建的混淆开关,打测试包验证功能是否恢复:如果功能正常,说明问题出在混淆规则漏配,补全规则后再正式发布,不要直接关闭混淆全量上线。
- 通过
adb shell dumpsys package 你的应用包名拉取线上版本的实际权限授予状态,确认是否为安装阶段就被系统/Play商店默认拒绝,而非用户手动操作拒绝。 - 替换所有硬编码的存储路径,统一通过
path_provider插件的getApplicationDocumentsDirectory()获取应用专属目录路径,不要跨目录读写非应用专属的公共存储位置。
内容的提问来源于stack exchange,提问作者Ahmed Elshazly
相关产品推荐
相关产品推荐

