Flutter: APIレベル31以上のAndroidエミュレーターだと、Cameraの撮影がエラーになる

※当サイトは、アフィリエイト広告を利用しています

結論:(未解決)APIレベル31以上の端末については、実機でテストする

2022/11/6 Flutter エラー・バグ日記

 

「Camera」パッケージを使い、「takePicture」メソッドで撮影しようとすると、エラーになって撮影できない現象に直面した。

 

様々なケースで試したところ、

 

  • APIレベル31(Android12)のAndroidエミュレーター
  • APIレベル33(Android13)のAndroidエミュレーター

 

だとエラーになる。

 

本記事はライトな日記思考で書いているので、詳細説明はしておらず、基本、テキストのみで画像とかはあまり載せておりません。。m(_ _)m

解説記事ではないため、解決していない内容や、その時々の間違った解釈を述べてしまっている可能性が大いにありますので、何卒、ご了承ください。

 

一方、

 

  • APIレベル30(Android11)以下のAndroidエミュレーター
  • APIレベル31(Android12)のAndroid実機
  • iOSシミュレーター(iOS16)
  • iOS実機(iOS16)

 

ではエラーにならず、問題なく写真撮影できた

 

実行環境は、以下のとおり。

 

  • macOS: Monterey 12.6
  • Flutter: stable 3.3.4
  • Dart: 2.18.2
  • Android Studio: version 2021.3

 

また、「Camera」パッケージのバージョンは、本日記時点で最新の「0.10.0+4」。

 

パッケージのReadmeに書かれているAndroid用の設定は実施済(minSdkVersion 21)。

 

以下2通りのコードで動作を試した。

 

 

いずれのコードでも、同じエラーが発生する状況。そのため、コード自体の問題ではなさそう。。

 

エラーメッセージは複数パターンある

「CameraPreview」ウィジェットによるプレビュー画像は問題なく表示される(下図は、Android 12のエミュレーターで実行した場合)。

 

プレビューは機能する(Exampleのコード)

 

撮影ボタンを押し、「takePicture」メソッドを発動すると、アプリは落ちないが、何の反応も無く、コンソールにエラーログが表示される。

 

エラーログの内容は、状況によって若干異なり、主に下記3パターンあった。

 

■エラーパターン①

 

一番多く出るエラーが以下。

 

I/Camera  (11669): runPrecaptureSequence
I/Camera  (11669): refreshPreviewCaptureSession
D/CameraCaptureCallback(11669): CameraCaptureCallback | state: STATE_WAITING_PRECAPTURE_START | afState: 0 | aeState: 2
D/CameraCaptureCallback(11669): CameraCaptureCallback | state: STATE_WAITING_PRECAPTURE_DONE | afState: 0 | aeState: 2
I/Camera  (11669): captureStillPicture
D/Camera  (11669): Updating builder with feature: ExposureLockFeature
D/Camera  (11669): Updating builder with feature: ExposurePointFeature
D/Camera  (11669): Updating builder with feature: ZoomLevelFeature
D/Camera  (11669): Updating builder with feature: AutoFocusFeature
D/Camera  (11669): Updating builder with feature: NoiseReductionFeature
I/Camera  (11669): updateNoiseReduction | currentSetting: fast
D/Camera  (11669): Updating builder with feature: FocusPointFeature
D/Camera  (11669): Updating builder with feature: ResolutionFeature
D/Camera  (11669): Updating builder with feature: SensorOrientationFeature
D/Camera  (11669): Updating builder with feature: FlashFeature
D/Camera  (11669): Updating builder with feature: ExposureOffsetFeature
D/Camera  (11669): Updating builder with feature: FpsRangeFeature
I/Camera  (11669): sending capture request
D/CameraCaptureCallback(11669): CameraCaptureCallback | state: STATE_CAPTURING | afState: 0 | aeState: 2
D/CameraCaptureCallback(11669): CameraCaptureCallback | state: STATE_CAPTURING | afState: 0 | aeState: 2
D/CameraCaptureCallback(11669): CameraCaptureCallback | state: STATE_CAPTURING | afState: 0 | aeState: 5
D/CameraCaptureCallback(11669): CameraCaptureCallback | state: STATE_CAPTURING | afState: 0 | aeState: 5
D/EGL_emulation(11669): app_time_stats: avg=135.85ms min=30.15ms max=597.02ms count=11
I/Camera  (11669): unlockAutoFocus
I/Camera  (11669): refreshPreviewCaptureSession
D/CameraCaptureCallback(11669): CameraCaptureCallback | state: STATE_CAPTURING | afState: 0 | aeState: 5
D/CameraCaptureCallback(11669): CameraCaptureCallback | state: STATE_CAPTURING | afState: 0 | aeState: 5
D/CameraCaptureCallback(11669): CameraCaptureCallback | state: STATE_CAPTURING | afState: 0 | aeState: 5
D/CameraCaptureCallback(11669): CameraCaptureCallback | state: STATE_CAPTURING | afState: 0 | aeState: 5
D/CameraCaptureCallback(11669): CameraCaptureCallback | state: STATE_CAPTURING | afState: 0 | aeState: 5
D/CameraCaptureCallback(11669): CameraCaptureCallback | state: STATE_CAPTURING | afState: 0 | aeState: 5
D/CameraCaptureCallback(11669): CameraCaptureCallback | state: STATE_CAPTURING | afState: 0 | aeState: 2
D/CameraCaptureCallback(11669): CameraCaptureCallback | state: STATE_CAPTURING | afState: 0 | aeState: 5
I/Camera  (11669): open | onError
I/Camera  (11669): close
I/Camera  (11669): open | onClosed

 

「E/」から始まるログはないものの、最後から3行目に「onError」と出ている。

 

APIレベル30以下のエミュレーターでは問題なく撮影され、このようなログは出ない。

 

■エラーパターン

 

「compileSdkVersion」と「targetSdkVersion」を31から33に上げたら、以下のエラーになった。

 

I/Camera  (11977): runPrecaptureSequence
I/Camera  (11977): refreshPreviewCaptureSession
D/CameraCaptureCallback(11977): CameraCaptureCallback | state: STATE_WAITING_PRECAPTURE_START | afState: 0 | aeState: 2
D/CameraCaptureCallback(11977): CameraCaptureCallback | state: STATE_WAITING_PRECAPTURE_DONE | afState: 0 | aeState: 2
I/Camera  (11977): captureStillPicture
D/Camera  (11977): Updating builder with feature: ExposureLockFeature
D/Camera  (11977): Updating builder with feature: ExposurePointFeature
D/Camera  (11977): Updating builder with feature: ZoomLevelFeature
D/Camera  (11977): Updating builder with feature: AutoFocusFeature
D/Camera  (11977): Updating builder with feature: NoiseReductionFeature
I/Camera  (11977): updateNoiseReduction | currentSetting: fast
D/Camera  (11977): Updating builder with feature: FocusPointFeature
D/Camera  (11977): Updating builder with feature: ResolutionFeature
D/Camera  (11977): Updating builder with feature: SensorOrientationFeature
D/Camera  (11977): Updating builder with feature: FlashFeature
D/Camera  (11977): Updating builder with feature: ExposureOffsetFeature
D/Camera  (11977): Updating builder with feature: FpsRangeFeature
D/EGL_emulation(11977): app_time_stats: avg=92.99ms min=17.37ms max=464.67ms count=14
I/Camera  (11977): sending capture request
D/CameraCaptureCallback(11977): CameraCaptureCallback | state: STATE_CAPTURING | afState: 0 | aeState: 2
D/CameraCaptureCallback(11977): CameraCaptureCallback | state: STATE_CAPTURING | afState: 0 | aeState: 2
D/CameraCaptureCallback(11977): CameraCaptureCallback | state: STATE_CAPTURING | afState: 0 | aeState: 5
D/CameraCaptureCallback(11977): CameraCaptureCallback | state: STATE_CAPTURING | afState: 0 | aeState: 5
I/Camera  (11977): unlockAutoFocus
I/Camera  (11977): refreshPreviewCaptureSession
D/CameraCaptureCallback(11977): CameraCaptureCallback | state: STATE_CAPTURING | afState: 0 | aeState: 5
D/CameraCaptureCallback(11977): CameraCaptureCallback | state: STATE_CAPTURING | afState: 0 | aeState: 5
D/CameraCaptureCallback(11977): CameraCaptureCallback | state: STATE_CAPTURING | afState: 0 | aeState: 5
D/CameraCaptureCallback(11977): CameraCaptureCallback | state: STATE_CAPTURING | afState: 0 | aeState: 5
D/CameraCaptureCallback(11977): CameraCaptureCallback | state: STATE_CAPTURING | afState: 0 | aeState: 5
D/CameraCaptureCallback(11977): CameraCaptureCallback | state: STATE_CAPTURING | afState: 0 | aeState: 5
D/CameraCaptureCallback(11977): CameraCaptureCallback | state: STATE_CAPTURING | afState: 0 | aeState: 2
D/CameraCaptureCallback(11977): CameraCaptureCallback | state: STATE_CAPTURING | afState: 0 | aeState: 5
D/CameraCaptureCallback(11977): CameraCaptureCallback | state: STATE_CAPTURING | afState: 0 | aeState: 5
E/CameraCaptureSession(11977): Session 0: Exception while stopping repeating: 
E/CameraCaptureSession(11977): android.hardware.camera2.CameraAccessException: CAMERA_ERROR (3): cancelRequest:507: Camera 0: Error clearing streaming request: Function not implemented (-38)
E/CameraCaptureSession(11977):     at android.hardware.camera2.CameraManager.throwAsPublicException(CameraManager.java:1179)
E/CameraCaptureSession(11977):     at android.hardware.camera2.impl.ICameraDeviceUserWrapper.cancelRequest(ICameraDeviceUserWrapper.java:99)
E/CameraCaptureSession(11977):     at android.hardware.camera2.impl.CameraDeviceImpl.stopRepeating(CameraDeviceImpl.java:1287)
E/CameraCaptureSession(11977):     at android.hardware.camera2.impl.CameraCaptureSessionImpl.close(CameraCaptureSessionImpl.java:579)
E/CameraCaptureSession(11977):     at android.hardware.camera2.impl.CameraCaptureSessionImpl$2.onDisconnected(CameraCaptureSessionImpl.java:790)
E/CameraCaptureSession(11977):     at android.hardware.camera2.impl.CameraDeviceImpl$7.run(CameraDeviceImpl.java:259)
E/CameraCaptureSession(11977):     at android.os.Handler.handleCallback(Handler.java:938)
E/CameraCaptureSession(11977):     at android.os.Handler.dispatchMessage(Handler.java:99)
E/CameraCaptureSession(11977):     at android.os.Looper.loopOnce(Looper.java:201)
E/CameraCaptureSession(11977):     at android.os.Looper.loop(Looper.java:288)
E/CameraCaptureSession(11977):     at android.os.HandlerThread.run(HandlerThread.java:67)
E/CameraCaptureSession(11977): Caused by: android.os.ServiceSpecificException: cancelRequest:507: Camera 0: Error clearing streaming request: Function not implemented (-38) (code 10)
E/CameraCaptureSession(11977):     at android.os.Parcel.createExceptionOrNull(Parcel.java:2439)
E/CameraCaptureSession(11977):     at android.os.Parcel.createException(Parcel.java:2409)
E/CameraCaptureSession(11977):     at android.os.Parcel.readException(Parcel.java:2392)
E/CameraCaptureSession(11977):     at android.os.Parcel.readException(Parcel.java:2334)
E/CameraCaptureSession(11977):     at android.hardware.camera2.ICameraDeviceUser$Stub$Proxy.cancelRequest(ICameraDeviceUser.java:749)
E/CameraCaptureSession(11977):     at android.hardware.camera2.impl.ICameraDeviceUserWrapper.cancelRequest(ICameraDeviceUserWrapper.java:97)
E/CameraCaptureSession(11977):     ... 9 more
I/Camera  (11977): open | onDisconnected
I/Camera  (11977): close
I/Camera  (11977): open | onClosed

 

今度は「E/」のログが表示され、「CAMERA_ERROR (3)」という表示も出ている。

 

また、最後から3行目は「onDisconnected」に変わった。

 

■エラーパターン

 

「Camera」パッケージのバージョンを思い切って下げたら(0.9.0より下)、以下のようなエラーになった。

 

D/EGL_emulation(12214): app_time_stats: avg=372.55ms min=79.65ms max=683.29ms count=3
E/CameraCaptureSession(12214): Session 0: Exception while stopping repeating: 
E/CameraCaptureSession(12214): android.hardware.camera2.CameraAccessException: CAMERA_ERROR (3): The camera device has encountered a serious error
E/CameraCaptureSession(12214):     at android.hardware.camera2.impl.CameraDeviceImpl.checkIfCameraClosedOrInError(CameraDeviceImpl.java:2350)
E/CameraCaptureSession(12214):     at android.hardware.camera2.impl.CameraDeviceImpl.stopRepeating(CameraDeviceImpl.java:1277)
E/CameraCaptureSession(12214):     at android.hardware.camera2.impl.CameraCaptureSessionImpl.close(CameraCaptureSessionImpl.java:579)
E/CameraCaptureSession(12214):     at io.flutter.plugins.camera.Camera.closeCaptureSession(Camera.java:1171)
E/CameraCaptureSession(12214):     at io.flutter.plugins.camera.Camera.close(Camera.java:1177)
E/CameraCaptureSession(12214):     at io.flutter.plugins.camera.Camera$1.onError(Camera.java:252)
E/CameraCaptureSession(12214):     at android.hardware.camera2.impl.CameraDeviceImpl.notifyError(CameraDeviceImpl.java:1748)
E/CameraCaptureSession(12214):     at android.hardware.camera2.impl.CameraDeviceImpl.$r8$lambda$KBQCqQRdhVVn7uHI9Xdha6OqnsU(Unknown Source:0)
E/CameraCaptureSession(12214):     at android.hardware.camera2.impl.CameraDeviceImpl$$ExternalSyntheticLambda0.accept(Unknown Source:8)
E/CameraCaptureSession(12214):     at com.android.internal.util.function.pooled.PooledLambdaImpl.doInvoke(PooledLambdaImpl.java:281)
E/CameraCaptureSession(12214):     at com.android.internal.util.function.pooled.PooledLambdaImpl.invoke(PooledLambdaImpl.java:204)
E/CameraCaptureSession(12214):     at com.android.internal.util.function.pooled.OmniFunction.run(OmniFunction.java:97)
E/CameraCaptureSession(12214):     at android.os.Handler.handleCallback(Handler.java:938)
E/CameraCaptureSession(12214):     at android.os.Handler.dispatchMessage(Handler.java:99)
E/CameraCaptureSession(12214):     at android.os.Looper.loopOnce(Looper.java:201)
E/CameraCaptureSession(12214):     at android.os.Looper.loop(Looper.java:288)
E/CameraCaptureSession(12214):     at android.app.ActivityThread.main(ActivityThread.java:7839)
E/CameraCaptureSession(12214):     at java.lang.reflect.Method.invoke(Native Method)
E/CameraCaptureSession(12214):     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
E/CameraCaptureSession(12214):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)

 

「E/」のログや「CAMERA_ERROR (3)」の他に、「The camera device has encountered a serious error」というメッセージも表示されている。

 

GitHubに複数のオープン中のイシューあり

「Androidで動かない」(適当に英単語化して検索)、「CAMERA_ERROR (3)」などのキーワードで検索すると、以下2つのイシューが見つかった。

 

 

 

いずれもまだオープン中。

 

1つ目のイシューは、iOSだと機能するが、Androidのエミュレーターだと機能しないとのことで、自分と似た状況。

 

2つのイシューを見ると、色々な報告があるようだが、やはりAPIレベル31以上のPixelのエミュレーターで発生する模様。

 

しかし、解決策は提示されていない。

 

2つ目のイシューでは、イシュー報告に多くの賛成票(グッドボタン)が投じられている。

 

「Camera」パッケージは、Flutter公式が開発していることも踏まえると、そのうち改善される可能性がありそう。

 

試しに、「targetSdkVersion」を上げたり、パッケージのバージョンを下げたりしてみたが、状況は変わらず(前述のとおり、若干エラーメッセージの表示が変わる程度)。。

  

APIレベル31(Android12)の実機では問題なく動いているので、エミュレーターで動かないうちは、仕方なく実機でテストすることにして、いったん本件は様子見。

 

(補足)「Camera.java」の内容

「onDisconnected」や「onError」の出力箇所を確認したいと思い、プロジェクト内を検索したところ、Javaで書かれた「Camera.java」というファイル内に書かれていた。

 

読んでみたが、エラーの発生条件は理解できず。。

 

ただし、ファイル内に、以下のようにAPIレベル31を境にした判定箇所がいくつかあった。

 

    if (Build.VERSION.SDK_INT >= 31) {
      mediaRecorderBuilder = new MediaRecorderBuilder(getRecordingProfile(), outputFilePath);
    } else {
      mediaRecorderBuilder = new MediaRecorderBuilder(getRecordingProfileLegacy(), outputFilePath);
    }

 

どうやら録画関連の機能を使用する場合に、影響がある模様。

 

もしかすると、録画機能をOFFにすれば、エラーが解消されるかもしれない、と思い、「CameraController」の「enableAudio」プロパティをfalseにしてみた(デフォルトはtrue)が、残念ながら、結果は変わらず。。

 

いったん諦めて、引き続き、イシューをウォッチしていこう。

 

\一般的なエラー対処法をまとめた記事はこちら/

 

リリースしたアプリ(全てFlutterで開発)

 

個人アプリ開発で役立ったもの

おすすめの学習教材

超初心者向けでオススメな元Udemyの講座/

 

 \キャンペーン時を狙えば安価で網羅的な内容が学べる(日本語訳あり)/

 

\Gitの基礎について無料で学べる/

 

おすすめの学習書籍

実用的image_pickerに関してかなり助けられた/

 

Dartの基礎文法を素早くインプットできる/


Dart入門 - Dartの要点をつかむためのクイックツアー