Flutter 相機定製

Flutter中與硬件相關的部分,一直都挺蛋疼的。方案基本上有兩種,本身寫,或者等出相關的庫。html

最近作的一個項目中,須要對相機作定製。有過相關模塊開發經驗的,就知道這種需求並不簡單,何況是這種跨平臺解決方案的初期。android

需求來了,怎麼辦呢?那就只能硬着頭皮上了。先去pub上找找,有沒有可使用的庫。初步挑到兩個庫,一個camera,另外一個是image_picker。ide

image_picker試了下,基本上就pass了,只能調用系統相機或者選擇相冊,相機相關部分,確定是無法使用。相冊部分卻是能夠拿來使用。this

camera試着運行了下demo,感受這個庫可使用,直接將相機預覽封裝成一個flutter widget。咱們能夠很方便的在上面進行各類定製。插件

設計圖上須要相機全屏顯示,試着在demo上修改爲全屏,悲劇出現了,風通常的拉伸效果。添加一個調取相機的頁面,在退出相機頁面後,demo置後臺,切換到前臺的時候,Android這邊crash了,試了N屢次,100%的crash,我勒個擦,谷歌官方的插件寫的這麼隨意~設計

而後,重點來了,本文主要是解決這兩個問題,一個是全屏顯示的問題,另外一個則是crash問題code

先上一張Android端的拍照效果圖:htm

Flutter 相機定製

Android端全屏拉伸問題

對於這種相機拉伸問題,作過相機定製相關的,都會知道是預覽的分辨率選擇錯誤致使的,知道這一點事後,修改起來就簡單的多了。直接拉camer plugin的源碼,Android的實現,相對仍是比較簡單,一個文件700來行代碼。找到計算預覽尺寸的方法。blog

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爲例
相關文章
相關標籤/搜索