Flutter中与硬件相关的部分,一直都挺蛋疼的。方案基本上有两种,自己写,或者等出相关的库。

最近做的一个项目中,需要对相机做定制。有过相关模块开发经验的,就知道这种需求并不简单,况且是这种跨平台解决方案的初期。

需求来了,怎么办呢?那就只能硬着头皮上了。先去pub上找找,有没有可以使用的库。初步挑到两个库,一个camera,另一个是image_picker。

image_picker试了下,基本上就pass了,只能调用系统相机或者选择相册,相机相关部分,肯定是没法使用。相册部分倒是可以拿来使用。

camera试着运行了下demo,感觉这个库可以使用,直接将相机预览封装成一个flutter widget。我们可以很方便的在上面进行各种定制。

设计图上需要相机全屏显示,试着在demo上修改成全屏,悲剧出现了,风一般的拉伸效果。添加一个调取相机的页面,在退出相机页面后,demo置后台,切换到前台的时候,Android这边crash了,试了N多次,100%的crash,我勒个擦,谷歌官方的插件写的这么随意~

然后,重点来了,本文主要是解决这两个问题,一个是全屏显示的问题,另一个则是crash问题

先上一张Android端的拍照效果图:

Android端全屏拉伸问题

对于这种相机拉伸问题,做过相机定制相关的,都会知道是预览的分辨率选择错误导致的,知道这一点过后,修改起来就简单的多了。直接拉camer plugin的源码,Android的实现,相对还是比较简单,一个文件700来行代码。找到计算预览尺寸的方法。

    private void computeBestPreviewAndRecordingSize(
StreamConfigurationMap streamConfigurationMap, Size minPreviewSize, Size captureSize) {
....
}

考虑到以后camera插件升级的问题,直接单独新建一个文件进行最佳预览尺寸的计算,然后在调用处进行替换即可。

Android端前后台切换必现crash问题

Android端前后台切换的问题,查看log发现是resume过后崩溃的,直接撸源代码,发现插件监听了Activity的生命周期,在resume的时候进行了open操作。

  @Override
public void onActivityResumed(Activity activity) {
if (requestingPermission) {
requestingPermission = false;
return;
}
if (activity == CameraPlugin.this.activity) {
if (camera != null) {
camera.open(null);
}
}
}

问题来了,关键是,插件没有进行unregister操作,在退出相机页面过后,调用dispose方法,会将camera关闭,并且将cameraDevice置为null,其他生命周期回调中调用cameraDevice的都会crash。onActivityResumed调用camer.open也会crash。这些crash的根本原因是因为没有将回调unregister掉。了解这些过后,修改起来就简单了,在dispose的时候,将插件的生命周期回调给unregister掉。修改完成后,试下效果,果然都没有crash。

后话

相关代码段我就不贴出来了,关于全屏预览尺寸的计算,网上太多的资料了,将previewSize计算正确即可。第二个crash的问题,添加一个unregisterActivityLifecycleCallbacks即可。对于修改的地方,做好注释,后续升级插件合入的时候不错乱即可。

目前来看Flutter第三方真的很差,如果只是自己个人项目,或者一些偏向于数据展示的项目,可以试一下。但是对于商业项目,尤其是硬件依赖性比较强的,还是建议一段时间过后再看看。

大后话

谷歌官方的camera插件,如果只是自己使用的话,可以按照上面的方法去修改,如果想要用在商业项目上,还是劝三思。

谷歌官方camera插件Android部分,用的是camera2 API,这个API有什么问题呢?

  1. 从21开始支持,也就是说需要放弃百分之十几的份额;
  2. 上面版本不是最坑的,最坑的是什么呢?硬件厂商对camera2的支持程度,遇到几台机子,对camera2支持非常差,这些机子还是近一年比较新的机子(vivo x20a),获取到的最大预览分辨率非常低,拍出来的图片尺寸也对不上。

最后,重写了Android部分,直接采用camera API,支持版本从16开始,完全没啥问题,对硬件支持也都非常完美。谷歌这个坑埋的有点深,最开始考虑时间因素,结果花在插件上修改分辨率、修改crash、排查特殊机型问题的时间不少。

参考

  1. Android设备对新Camera2 API的支持问题:以华为M2为例

Flutter 相机定制的更多相关文章

  1. 用 Flutter 和 Firebase 轻松构建 Web 应用

    作者 / Very Good Ventures Team 我们 (Very Good Ventures 团队) 与 Google 合作,在今年的 Google I/O 大会上推出了 照相亭互动体验 ( ...

  2. 【温故知新】——BABYLON.js学习之路·前辈经验(一)

    前言:公司用BABYLON作为主要的前端引擎,同事们在长时间的项目实践中摸索到有关BABYLON的学习路径和问题解决方法,这里只作为温故知新. 一.快速学习BABYLON 1. 阅读Babylon[基 ...

  3. iOS写在定制相机之前

    问题 不是所有的拍照UIImagePickerController都能搞定,理由如下: 1.产品不整点幺蛾子,哪来体验创新 2.设计不整点幺蛾子,怎能体现用心 3.运营:这体验跟某宝某信咋不一样??? ...

  4. Flutter: 使用相机拍照

    文档 camera import 'dart:io'; import 'package:camera/camera.dart'; import 'package:flutter/material.da ...

  5. html 通过input video canvas 打开摄像头 定制相机

    在机缘巧合之下,了解到用HTML5和javascript调用摄像头来实现拍照功能,今天就把大致原理写下来.页面布局很简单,就是一个input标签,两个HTML5元素video.canvas和一个but ...

  6. Flutter与Dart 入门

    Flutter简介 Flutter是google推出的,一个使用Dart语言开发的跨平台移动UI框架,通过自建绘制引擎,能高性能.高保真地进行Android和IOS开发. Flutter是什么 Flu ...

  7. 【Flutter】Flutter 一些常用库

    Flutter社区和资源传送门 新: 慕课网<Flutter入门与案例实战>   |   中文网<Flutter实战>电子书 字体图标生成 http://fluttericon ...

  8. Flutter的需要与原生交互的一些常用库

    [说明]由于这些库一直在更新,请自己选择合适的稳定版本下载. 另外如果发现有问题或者你有更好的库,欢迎留言告诉我. 谷歌官方的针对Dart语言的一些实用性的功能以及扩展的库 -- Quiver Qui ...

  9. Flutter 一些常用第三方库、插件

    网络请求 http ^0.12.0+2 https://pub.dev/packages/http https://github.com/dart-lang/http 该软件包包含一组高级函数和类,可 ...

随机推荐

  1. css font-family属性设置中文字体乱码

    一般设置字体,个人都喜欢用中文,比如:font-family:"微软雅黑":但是偶尔会出现设置以后字体显示乱码的问题 解决方法[1]: 看看你的CSS文件的第一行有没有:@char ...

  2. Linux下解压.tar.xz格式文件的方法

    前言 对于xz这个压缩相信很多人陌生,但xz是绝大数linux默认就带的一个压缩工具,xz格式比7z还要小. 今天在下载Node.js源码包的时候遇到的这种压缩格式.查了一下资料,这里进行一下记录,分 ...

  3. python中的数字取整(ceil,floor,round)概念和用法

    python中的数学运算函数(ceil,floor,round)的主要任务是截掉小数以后的位数.总体来说 就是取整用的.只是三者之间有微妙的区别:   floor() :把数字变小 ceil() : ...

  4. HoloLens开发手记 - HoloLens真机上手简评

    千呼万唤始出来,终于今天拿到了HoloLens真机. 使用体验 使用自带的应用录制了一段使用视频,如下 设备概览 包装盒 本体 试戴 实际效果 GalaxyExplorer试玩 全息图像贴到现实场景表 ...

  5. android开发学习——day8

    关于UI学习的总结 EditText的练习 MainActivity.java代码 package test.example.com.ch02_button; import android.suppo ...

  6. LearnOpenGL学习笔记(三)——VBO,VAO,EBO理解

    在opengl中所有的数据都要放在显存中,我们通过一定的手段去管理它,既要提供地方存放它,还要提供方法去正确地提取它们,去使用它们,opengl通过VAO,VBO,EBO这些手段来解决这些问题. (一 ...

  7. 史上最详细nodejs版本管理器nvm的安装与使用(附注意事项和优化方案)

    使用场景 在Node版本快速更新迭代的今天,新老项目使用的node版本号可能已经不相同了,node版本更新越来越快,项目越做越多,node切换版本号的需求越来越迫切,传统卸载一个版本在安装另一个版本的 ...

  8. 来自于一个问题的回答对自己的反思 php怎么发送邮件?发送邮件插件PHPMailer

    前言: 昨天用手机无意点了一下博问,看见了一个朋友问了一个关于php发邮件不能添加发件人名称的问题,试着看了一下代码,觉得自己发现了问题所在,谁知道只是一知半解没有真正发现问题所在,看来有一段时间没有 ...

  9. Linux的进程线程及调度

    本文为宋宝华<Linux的进程.线程以及调度>学习笔记. 1 进程概念 1.1 进程与线程的定义 操作系统中的经典定义: 进程:资源分配单位. 线程:调度单位. 操作系统中用PCB(Pro ...

  10. OpenCV3三种超像素分割算法源码以及效果

    OpenCV3中超像素分割算法SEEDS,SLIC, LSC算法在Contrib包里,需要使用Cmake编译使用.为了方便起见,我将三种算法的源码文件从contrib包里拎了出来,可以直接使用,顺便比 ...