uni-app targetSdkVersion高于28时 华为webview内拍照无法保存图片 一直提示正在保存照片
uni-app targetSdkVersion高于28时 华为webview内拍照无法保存图片 一直提示正在保存照片
项目属性 | 详细信息 |
---|---|
产品分类 | uniapp/App |
PC开发环境 | Windows |
PC开发环境版本 | win11 23h2 |
HBuilderX类型 | 正式 |
HBuilderX版本 | 4.29 |
手机系统 | 全部 |
手机厂商 | 华为 |
页面类型 | vue |
vue版本 | vue2 |
打包方式 | 云端 |
项目创建方式 | HBuilderX |
测试过的手机:
nova 5 pro 系统HarmonyOS 4.0.0
操作步骤:
自定义基座设置targetSdkVersion为30,webview中打开任意网站触发选择图片,选择拍照时拍完照一直正在保存,只有targetSdkVersion低于28才可以正常使用
预期结果:
拍照正常使用
实际结果:
拍照一直提示正在保存
bug描述:
打包app targetSdkVersion高于28,华为webview内拍照无法保存图片,一直提示正在保存照片,低于等于28可以正常使用,但是华为应用市场最低要求为30!
针对您提到的uni-app在targetSdkVersion高于28时,华为设备上WebView内拍照无法保存图片的问题,这通常与Android系统的权限管理和文件存储机制变化有关。从Android 9(Pie, API级别28)开始,Google引入了Scoped Storage机制,对应用访问外部存储进行了更严格的限制。以下是一些可能的解决方案,通过代码示例来展示如何处理这个问题。
1. 动态请求存储权限
首先,确保你的应用有适当的权限来写入存储。尽管在Scoped Storage下,直接访问外部存储的路径受限,但存储权限仍然是必要的,特别是在处理拍照功能时。
// 在uni-app的manifest.json中配置必要权限
{
"mp-weixin": {},
"app-plus": {
"distribute": {
"android": {
"permissions": [
"android.permission.WRITE_EXTERNAL_STORAGE",
"android.permission.READ_EXTERNAL_STORAGE"
]
}
}
}
}
// 在页面加载或拍照功能触发前动态请求权限(需使用uni-app的API封装权限请求逻辑)
uni.authorize({
scope: 'scope.writePhotosAlbum',
success() {
console.log('存储权限授权成功');
// 触发拍照逻辑
},
fail() {
console.log('存储权限授权失败');
}
});
2. 使用MediaStore API保存照片
由于Scoped Storage的限制,建议使用MediaStore API来保存照片,这样可以避免直接访问外部存储路径的问题。以下是一个简化的示例,展示如何在Android原生代码中通过MediaStore保存照片(注意,这部分代码需要在原生插件或原生模块中实现,uni-app本身不直接支持Java/Kotlin代码,但可以通过扩展实现)。
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "image.jpg");
values.put(MediaStore.Images.Media.DISPLAY_NAME, "image.jpg");
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + "/MyApp");
Uri uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
if (uri != null) {
try (OutputStream outputStream = getContentResolver().openOutputStream(uri)) {
// 将图片数据写入outputStream
} catch (IOException e) {
e.printStackTrace();
}
}
结论
由于uni-app的限制,直接在JavaScript/TypeScript中处理这些原生级别的存储问题是不可能的。你需要创建一个原生插件或使用现有的原生模块来处理MediaStore API的调用和权限请求。这通常涉及到Android原生开发知识,并可能需要与uni-app社区或专业开发者合作来完成。