【Android】混合开发 - 奇案 - 上传照片至 H5 失败

1,203 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 8 天,点击查看活动详情

前言

混合开发坑点千千万,今天讲讲其中一个比较离奇的情况。具体场景是在上传照片到 H5 时发生了不是必现的 BUG——上传不上去。

发现问题

在开发阶段,手上有的真机都验证过,当时都没有出现问题。

但,当准备上应用市场的前,扩大测试范围的时候,就出现了问题。具体问题就是:在 H5 调起原生相机相册,选择文件后,H5 页面无法获取到对应文件展示。如下图所示:

通过测试结果显示:红米note9(Android10) ,荣耀 30(Android10),OPPO R17(Android10),OPPO Reno5 (Android11),小米10(Android10),均出现了该问题,但又不是必现的问题。这就让我摸不着头脑了。

分析问题

于是开始了探索之路。

在没有思路的情况下,我打算先调试之前写的 Demo,担心实际项目中过多的因素不好排查问题。

经过比较, Demo 和 项目中最大的区别就是——待上传的图片是否经历了压缩操作。于是从结果出发,发现压缩后原本的图片路径发送了变化。

由日志,我们可以发现:

  1. 压缩后的是 file:// 协议

  2. 文件名也发生了变化。 temp.png -> 1623032141978588.jpeg 后者是个时间戳。

String cacheBuilder = mTargetDir + "/" +
    System.currentTimeMillis() +
    (int) (Math.random() * 1000) +
    (TextUtils.isEmpty(suffix) ? ".jpg" : suffix);

那这里就产生了一个问题,是压缩的问题?还是只是文件名的问题?

基于这样的想法,我发现把文件名直接改成压缩后的格式,但不经过压缩,传给 H5 。

mFilePathCallback?.onReceiveValue(arrayOf(Uri.parse("file://"+PhotoUtils.PATH_PHOTO)))

其中的 PATH_PHOTO 如下:

PATH_PHOTO = getSdCardDirectory(context) + "/"+System.currentTimeMillis()+".png"

发现确实成功上传了。

但是担心是机缘巧合,所以展开了多次的测试。

解决方案

实验得出,可正常使用的方案就是:

  1. 传给 H5 的路径,要符合 file 协议 file://

  2. 拍照后的照片存储的名字要唯一

再思考

到这样,问题应该算解决了吧?可以说解决了,但是没有完全解决。

如果解决的标准是——【能用】就行,那的确是解决了。

但是,在测试中出现了几个奇怪的现象。暂时没有找到结果。抛出来,希望跟大家一起谈论学习。

情况1:连续上传两次同名文件失败

在拍照的时候,拍照临时存的文件,如果是设定为同一个名字。即 PATH_PHOTO 设置为

PATH_PHOTO = getSdCardDirectory(context) + "/temp.png"

这个情况下,拍摄第二张照片上传时出现失败。

操作如下:

日志如下:

情况2:是否是同名文件引起的情况1

上面那种情况,刚开始,我以为是同一个文件名,可能系统缓存中认为是同一张照片,所以没办法上传的时候。但是,当我尝试在两次拍照的中间,加一次上传相册的图片,又可以了!

操作如下:

d497c5cd8hb370764e7538e2c854cdd0.gif

日志如下:

情况3:是否与 appCache, domStorage 有关?

测试是否与 websetting (appCache, domStorage) 有关

WebView类型enable AppCacheenable domStorageenableboth
X5(Tencent)XX
原生XXX

测试结果:在 X5WebView 中,将 appCache, domStorage 都使能的情况下。App 在第二次进入时,相机&相册功能均正常。

情况4:是否与 file 协议有关?

测试是否与 file 协议有关

WebView类型遵循file协议
X5(Tencent)
原生

测试结果:无论是 X5 还是原生在遵循 file 协议下,相机&相册均可成功。