Android webview 关于拍照上传图片的解决方法
2017-03-19 12:46
686 查看
本文地址:https://my.oschina.net/zengliubao/blog/862161
演示Demo中assets 目录内置了index.html 和JSbridge.js 来演示, this.goWebView("http://my.oschina.net/zengliubao/blog/file:/android_asset/index.html") 来启动吧!Demo演示请点击这里
Android 开发实在要考虑太多的因素,webview 就像IE6时代的产物,甚至JS 注入的惊天漏洞也有过呢,而且这部分设备永远得不到更新,炸弹一直没法拆除。
看很多朋友在实际的项目开发中遇到webview 拍照上传图片遇到的坑,最多的是webview 无法处理 type =file标签导致无法上传图片(重写onOpenFile 不会回调);当然我们项目由于业务的关系遇到一个更加麻烦的事情,低内存状态从拍照返回来页面被销毁重置了。
最终我们的解决方案是iOS 的仍然处理type=file 标签,Android 全部通过Jsbridge 调用Native 把照片bitmap 通过Base64编码回传给JS,param.content = "data:image/jpg;base64," + Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT),忙完这阵,我会把Demo上传到Github。
#低内存状态从拍照返回来页面被销毁重置了
上面的图使我们的业务相关的web 页面,如果前面几个步骤都做好了,最后去拍照的正准备去按下快门来了个电话,接着回复了一下微信,这个过程在一些低端的红米和魅族等手机(没有批判,国产的很多低端机都这样)返回来拍照返回数据的时候,发起拍照的那个含有webview 的页面一闪---onCreate了,全面填写的内容没有了,这又要让用户去操作填写一遍数据!尝试过onSavewInstance ,webview.storeInstance等方法看能不能恢复(对webkie内核不是非常的熟悉,去stackoverflow 看的),然而我没有恢复内容,多么的悲伤!
原生的控件的一些编辑的数据能在onSaveInstance 中保存起来,webview 中的页面也可以缓存,但是编辑中的那些数据能吗?我没有找到方法。我的做法简单粗暴,提高app 进程的优先级,启动前台Servie 以及 不要让我们的app变成后台进程,自定义相机不要用系统相机(新的App会让调用app 变为后台进程)
最重要的,Webview 所在的Activity配置成在一个新的独立进程中会很好的解决很多的问题-OOM 内存泄露等!
#拍的照片被旋转了?
这个经常出现在三星的手机中,拍好的照片导入电脑查看也是旋转度数的!我们读取的时候需要旋转处理一下
#没有系统相机可以使用?
前几天因为推送的问题设置天池优化,然而360 手机竟然竟然发送intent 请求电池优化的时候闪退了;系统相机会不会也被切除了,修改了,Android 奇葩事情无所不有。
虽然很极端,但作为客户端人员还是要进行处理,方式有二:
调用相机时,简单粗暴的 try-catch
调用相机前,检测系统有没有相机 app 可用
try-catch 这种粗暴的方式大家肯定很熟悉了,那么要如何检测系统有没有相机 app 可用呢?系统在 PackageManager 里为我们提供这样一个 API:queryIntentActivities通过这样一个 API ,可以知道系统是否存在 action 为 MediaStore.ACTION_IMAGE_CAPTURE 的 intent 可以唤起的拍照界面,具体实现代码如下:
演示Demo中assets 目录内置了index.html 和JSbridge.js 来演示, this.goWebView("http://my.oschina.net/zengliubao/blog/file:/android_asset/index.html") 来启动吧!Demo演示请点击这里
Android 开发实在要考虑太多的因素,webview 就像IE6时代的产物,甚至JS 注入的惊天漏洞也有过呢,而且这部分设备永远得不到更新,炸弹一直没法拆除。
看很多朋友在实际的项目开发中遇到webview 拍照上传图片遇到的坑,最多的是webview 无法处理 type =file标签导致无法上传图片(重写onOpenFile 不会回调);当然我们项目由于业务的关系遇到一个更加麻烦的事情,低内存状态从拍照返回来页面被销毁重置了。
Android 4.X 无法处理Type=file 的标记.
这个问题在很多的Android 4.X 都是必现的,那年项目上有人因为无法拍照没法接单,直接买了一部新手机把问题手机给我们了,感动ING;这也导致你针对不同的版本Webview重写了onOpenFile 仍然无法达到完美的解决方案的时候你会很难过。最终我们的解决方案是iOS 的仍然处理type=file 标签,Android 全部通过Jsbridge 调用Native 把照片bitmap 通过Base64编码回传给JS,param.content = "data:image/jpg;base64," + Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT),忙完这阵,我会把Demo上传到Github。
#低内存状态从拍照返回来页面被销毁重置了
上面的图使我们的业务相关的web 页面,如果前面几个步骤都做好了,最后去拍照的正准备去按下快门来了个电话,接着回复了一下微信,这个过程在一些低端的红米和魅族等手机(没有批判,国产的很多低端机都这样)返回来拍照返回数据的时候,发起拍照的那个含有webview 的页面一闪---onCreate了,全面填写的内容没有了,这又要让用户去操作填写一遍数据!尝试过onSavewInstance ,webview.storeInstance等方法看能不能恢复(对webkie内核不是非常的熟悉,去stackoverflow 看的),然而我没有恢复内容,多么的悲伤!
那么为什么会出现这种情况呢?
当某个 app 通过 intent 调用进入相机拍照界面时,系统会把这个 app 当做是后台进程,后台进程优先级是比较低的,当内存不足的时候就被销毁了,等重新回来拍完照回到这个app 的时候会恢复这个app 的进程页面数据等。原生的控件的一些编辑的数据能在onSaveInstance 中保存起来,webview 中的页面也可以缓存,但是编辑中的那些数据能吗?我没有找到方法。我的做法简单粗暴,提高app 进程的优先级,启动前台Servie 以及 不要让我们的app变成后台进程,自定义相机不要用系统相机(新的App会让调用app 变为后台进程)
最重要的,Webview 所在的Activity配置成在一个新的独立进程中会很好的解决很多的问题-OOM 内存泄露等!
#拍的照片被旋转了?
这个经常出现在三星的手机中,拍好的照片导入电脑查看也是旋转度数的!我们读取的时候需要旋转处理一下
/** * 获取图片的旋转角度 * * @param path 图片绝对路径 * @return 图片的旋转角度 */ public static int getBitmapDegree(String path) { int degree = 0; try { // 从指定路径下读取图片,并获取其EXIF信息 ExifInterface exifInterface = new ExifInterface(path); // 获取图片的旋转信息 int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_90: degree = 90; break; case ExifInterface.ORIENTATION_ROTATE_180: degree = 180; break; case ExifInterface.ORIENTATION_ROTATE_270: degree = 270; break; } } catch (IOException e) { e.printStackTrace(); } return degree; } /** * 将图片按照指定的角度进行旋转 * * @param bitmap 需要旋转的图片 * @param degree 指定的旋转角度 * @return 旋转后的图片 */ public static Bitmap rotateBitmapByDegree(Bitmap bitmap, int degree) { // 根据旋转角度,生成旋转矩阵 Matrix matrix = new Matrix(); matrix.postRotate(degree); // 将原始图片按照旋转矩阵进行旋转,并得到新的图片 Bitmap newBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); if (bitmap != null & !bitmap.isRecycled()) { bitmap.recycle(); } return newBitmap; }
Bitmap 过大?
这个网上很多的解决方法。#没有系统相机可以使用?
前几天因为推送的问题设置天池优化,然而360 手机竟然竟然发送intent 请求电池优化的时候闪退了;系统相机会不会也被切除了,修改了,Android 奇葩事情无所不有。
虽然很极端,但作为客户端人员还是要进行处理,方式有二:
调用相机时,简单粗暴的 try-catch
调用相机前,检测系统有没有相机 app 可用
try-catch 这种粗暴的方式大家肯定很熟悉了,那么要如何检测系统有没有相机 app 可用呢?系统在 PackageManager 里为我们提供这样一个 API:queryIntentActivities通过这样一个 API ,可以知道系统是否存在 action 为 MediaStore.ACTION_IMAGE_CAPTURE 的 intent 可以唤起的拍照界面,具体实现代码如下:
public boolean hasCamera() { PackageManager packageManager = mActivity.getPackageManager(); Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); List list = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); return list.size() > 0; }
准备整理一下写一个关于Jsbridge 总结的文章和Demo放到github
http://blog.csdn.net/sk719887916/article/details/52402470
相关文章推荐
- [置顶] 【Android开发技巧】 关于Webview拍照或从相册上传图片处理总结
- 关于Android原生集成5+webview,监听webview返回时,执行两次onkey方法问题的解决
- Android WebView关于图片/文件上传
- 【Android进阶】Android里webview不支持input file的解决方法(上传按钮点击失效的原因)
- Android WebView 上传各种文件(包括拍照 录像 录音 文件 音乐 等,用到图片或拍照的,可以参考下)
- Android WebView 选择图片并上传(调用相机拍照/相册/选择文件)
- android通过webView加载第三方h5应用,部分手机加载部分图片失败和播放部分视频失败的解决方法
- android通过webView加载第三方h5应用,无法加载图片和播放视频的解决方法
- 关于android webview中访问web页面带有upload上传控件的解决办法
- android webview图片文件上传——上传控件点击无效的解决办法
- [Android] WebView中拍照或从相册上传图片
- 关于Android WebView不支持window.location.href的解决方法
- 关于Webview拍照或从相册上传图片处理总结
- android webview图片文件上传兼容性问题——上传控件点击无效的解决办法
- 解决 react native 的 webview 组件不支持android客户端上传图片文件问题
- 关于Android WebView不支持location.href打开的解决方法 小米部分机型
- Android WebView 上传各种文件(包括拍照 录像 录音 文件 音乐 等,用到图片或拍照的)
- Android 使用腾讯X5 Webview浏览器拍照或从相册上传图片
- Android 使用腾讯X5 Webview浏览器拍照或从相册上传图片
- Android webview h5 图片,拍照,视频上传