質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

Q&A

解決済

1回答

2827閲覧

android端末のカメラを起動した状態でライトを点灯させたい

m-mega

総合スコア56

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

0グッド

0クリップ

投稿2021/09/16 05:04

編集2021/09/16 05:09

端末のカメラを起動し、カメラ映像をプレビューした状態で「カメラ横のライト」を点灯させたい。

やったこと

カメラを起動して、画面にプレビューするアプリを作成しました。コードを以下に記載します。

kotlin

1//MainActivity.kt 2 3package com.example.mycamera2application2 4 5//投稿文字数制限の関係で、import部分は割愛 6 7class MainActivity : AppCompatActivity() { 8 // 定数を定義 9 companion object { 10 private const val REQUEST_CODE_PERMISSIONS = 10 11 private val REQUIRED_PERMISSIONS = arrayOf(Manifest.permission.CAMERA) 12 } 13 // 変数を定義 14 lateinit var previewRequestBuilder : CaptureRequest.Builder 15 lateinit var button_torch: ImageButton 16 lateinit var cameraManager: CameraManager 17 val textureView: TextureView by lazy { 18 findViewById(R.id.textureView) 19 } 20 var cameraDevice: CameraDevice? = null 21 var captureSession: CameraCaptureSession? = null 22 var cameraId: String = "" // カメラのID取得用 23 var torchSw = false // LED点灯消灯制御用 24 //------------------------------------------------------------------- 25 26 @RequiresApi(Build.VERSION_CODES.M) 27 override fun onCreate(savedInstanceState: Bundle?) { 28 super.onCreate(savedInstanceState) 29 setContentView(R.layout.activity_main) 30 // LED制御ボタンのidを取得 31 torchCallback() 32 } 33 34 override fun onResume() { 35 super.onResume() 36 // ビューの準備ができている場合 37 if (textureView.isAvailable) { 38 // カメラ起動用関数を実行 39 openCamera() 40 } else { 41 // ビューにイベントリスナーを設定 42 textureView.surfaceTextureListener = object : TextureView.SurfaceTextureListener { 43 override fun onSurfaceTextureAvailable(p0: SurfaceTexture, p1: Int, p2: Int) { 44 openCamera() 45 } 46 // ビューのサイズが変更された際の処理 47 override fun onSurfaceTextureSizeChanged(p0: SurfaceTexture, p1: Int, p2: Int) {} 48 // ビューが更新された際の処理 49 override fun onSurfaceTextureUpdated(p0: SurfaceTexture) {} 50 // ビューが破棄された際の処理 51 override fun onSurfaceTextureDestroyed(p0: SurfaceTexture): Boolean = true 52 } 53 } 54 } 55 56 // 全てのパーミッションの使用許諾を取得 57 private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all { 58 ContextCompat.checkSelfPermission( 59 baseContext, it) == PackageManager.PERMISSION_GRANTED 60 } 61 62 private fun openCamera() { 63 // カメラの使用許可を取得する 64 if (allPermissionsGranted()) { 65 if (ActivityCompat.checkSelfPermission( 66 this, 67 Manifest.permission.CAMERA 68 ) != PackageManager.PERMISSION_GRANTED 69 ) { 70 return 71 } 72 // カメラマネージャー(カメラへのアクセス機能)の取得 73// cameraManager = getSystemService(Context.CAMERA_SERVICE) as CameraManager 74 cameraManager.openCamera("0", object: CameraDevice.StateCallback() { 75 // カメラが起動できた場合 76 @RequiresApi(Build.VERSION_CODES.M) 77 override fun onOpened(camera: CameraDevice) { 78 cameraDevice = camera 79 createCameraPreviewSession() 80 } 81 // カメラから切断された場合 82 override fun onDisconnected(camera: CameraDevice) { 83 cameraDevice?.close() 84 cameraDevice = null 85 } 86 // カメラの接続でエラーが発生した場合 87 override fun onError(camera: CameraDevice, p1: Int) { 88 cameraDevice?.close() 89 cameraDevice = null 90 } 91 }, null) 92 } else { 93 ActivityCompat.requestPermissions( 94 this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS 95 ) 96 } 97 } 98 99 // トーチモードのコールバックを登録する 100 @RequiresApi(Build.VERSION_CODES.M) 101 private fun torchCallback() { 102 cameraManager = getSystemService(Context.CAMERA_SERVICE) as CameraManager 103 cameraManager.registerTorchCallback(@RequiresApi(Build.VERSION_CODES.M) 104 object : CameraManager.TorchCallback() { 105 override fun onTorchModeChanged(id: String, enabled: Boolean) { 106 super.onTorchModeChanged(id, enabled) 107 // 状態を保存する 108 cameraId = id 109 torchSw = enabled 110 } 111 }, Handler()) 112 // LEDボタンのイベント登録 113 button_torch = findViewById(R.id.button_torch) 114 button_torch.setOnClickListener { 115 Log.i("cnfig_light","config_light") 116 switchLight() 117 } 118 } 119 120 // LEDの点灯消灯切り替え 121 @RequiresApi(Build.VERSION_CODES.M) 122 private fun switchLight() { 123 // 状態を反転させて、消灯なら点灯、点灯なら消灯させる 124 cameraManager.setTorchMode(cameraId, !torchSw) 125 Log.i("switchLight","torchSw : ${torchSw}") 126 } 127 128 // プレビュー用のセッションを作成 129 private fun createCameraPreviewSession() { 130 if (cameraDevice == null) { 131 return 132 } 133 val texture = textureView.surfaceTexture 134 // プレビューのサイズを指定 135 texture?.setDefaultBufferSize(640, 480) 136 // プレビューの表示先となるsurfaceを設定 137 val surface = Surface(texture) 138 139 previewRequestBuilder = cameraDevice!!.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW) 140 previewRequestBuilder.addTarget(surface) 141 142 cameraDevice?.createCaptureSession(listOf(surface), object : CameraCaptureSession.StateCallback() { 143 // セッションが取得できた場合 144 override fun onConfigured(session: CameraCaptureSession) { 145 captureSession = session 146 // プレビュー画像をTextureViewにセット 147 captureSession?.setRepeatingRequest(previewRequestBuilder.build(), null, null) 148 } 149 // セッションが取得できなかった場合 150 override fun onConfigureFailed(session: CameraCaptureSession) {} 151 }, null) 152 } 153}

kotlin

1//activity_main.xml 2 3<?xml version="1.0" encoding="utf-8"?> 4<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" 5 xmlns:app="http://schemas.android.com/apk/res-auto" 6 xmlns:tools="http://schemas.android.com/tools" 7 android:layout_width="match_parent" 8 android:layout_height="match_parent" 9 tools:context=".MainActivity"> 10 11 <TextureView 12 android:id="@+id/textureView" 13 android:layout_width="0dp" 14 android:layout_height="0dp" 15 app:layout_constraintBottom_toBottomOf="parent" 16 app:layout_constraintEnd_toEndOf="parent" 17 app:layout_constraintHorizontal_bias="0.0" 18 app:layout_constraintStart_toStartOf="parent" 19 app:layout_constraintTop_toTopOf="parent" 20 app:layout_constraintVertical_bias="0.0" /> 21 22 <View 23 android:id="@+id/container_bar" 24 android:layout_width="0dp" 25 android:layout_height="200dp" 26 android:background="#99D1D1D1" 27 app:layout_constraintBottom_toTopOf="@+id/container_button" 28 app:layout_constraintEnd_toEndOf="parent" 29 app:layout_constraintHorizontal_bias="0.0" 30 app:layout_constraintStart_toStartOf="parent" /> 31 32 //<SeekBar 33 // 投稿文字数制限の関係で割愛... 34 // /> 35 36 <TextView 37 android:id="@+id/textView_frame" 38 android:layout_width="wrap_content" 39 android:layout_height="wrap_content" 40 android:layout_marginLeft="10dp" 41 android:layout_marginBottom="5dp" 42 android:text="フレームレート" 43 app:layout_constraintBottom_toTopOf="@+id/seekBar_frame" 44 app:layout_constraintStart_toStartOf="parent" /> 45 46 <TextView 47 android:id="@+id/textView_speed" 48 android:layout_width="wrap_content" 49 android:layout_height="wrap_content" 50 android:layout_marginLeft="10dp" 51 android:layout_marginBottom="5dp" 52 android:text="シャッタースピード" 53 app:layout_constraintBottom_toTopOf="@+id/seekBar_speed" 54 app:layout_constraintStart_toStartOf="parent" /> 55 56 <TextView 57 android:id="@+id/textView_iso" 58 android:layout_width="wrap_content" 59 android:layout_height="wrap_content" 60 android:layout_marginLeft="10dp" 61 android:layout_marginBottom="5dp" 62 android:text="ISO" 63 app:layout_constraintBottom_toTopOf="@+id/seekBar_iso" 64 app:layout_constraintStart_toStartOf="parent" /> 65 66 <View 67 android:id="@+id/container_button" 68 android:layout_width="0dp" 69 android:layout_height="100dp" 70 android:background="#818181" 71 app:layout_constraintBottom_toBottomOf="@+id/textureView" 72 app:layout_constraintEnd_toEndOf="parent" 73 app:layout_constraintStart_toStartOf="parent" /> 74 75 <ImageButton 76 android:id="@+id/button_torch" 77 android:layout_width="40dp" 78 android:layout_height="40dp" 79 android:layout_marginRight="40dp" 80 app:layout_constraintBottom_toBottomOf="parent" 81 app:layout_constraintEnd_toEndOf="@+id/container_button" 82 app:layout_constraintTop_toBottomOf="@+id/container_bar" 83 app:srcCompat="?android:attr/textCursorDrawable" /> 84 85</androidx.constraintlayout.widget.ConstraintLayout> 86

エラー内容

ボタンを配置し、ライトの点灯消灯制御を行えるようにしたいのですが、ボタンを押した瞬間に以下のようなエラーが発生してアプリが強制終了してしまいます。

Caused by: android.os.ServiceSpecificException: setTorchMode:1485: Torch for camera "0" is not available due to an existing camera user (code 7)

直訳すると、カメラ「0」のトーチは、既存のカメラユーザーのため利用できませんとあります。

これは、カメラの起動(openCamera())でid"0"をすでに使用しているから、ライト点灯の際に同じidでの処理ができないということなのでしょうか。

その場合、異なるidの指定の仕方が分からず困っています。
カメラを起動した状態でライトを点灯させる例がネット上に見当たりませんでしたが、実装することは機能的に可能なのでしょうか。
解決方法がお分かりになる方がいらっしゃいましたら、教えていただけますと幸いです。よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m-mega

2021/09/17 00:40

情報共有ありがとうございます!参考にさせていただきます。 また、海外のStackOverflowに投稿した方がサイトの共有だけでなく実際に投稿したコードへの指摘をいただけそうなので、そちらにも投稿してみます。ありがとうございます!
m-mega

2021/09/17 01:28

いただいた情報を試してみましたが、現在では非推奨となっておりまして、正常に動作致しませんでした。 せっかく情報共有をいただいたにも関わらず解決に至れず申し訳ございません。
hoshi-takanori

2021/09/17 02:09

こちらこそ失礼しました、最近は CameraX を使うことが推奨されているので、その方がいいのかもしれませんね。
m-mega

2021/09/17 02:18 編集

ちなみにですが、現在のプログラムはカメラのIDとライトのIDをそれぞれ同じ"0(背面カメラ)"に設定していますが、カメラのIDを"1(正面カメラ)"に変更し、ライトのIDを"0(背面カメラ)"にするとカメラの映像は正面カメラの映像になりますが、無事にボタンでライトを点灯させることができました。 ですが、背面カメラをプレビューした状態でライトを点灯させようとする(同じIDを指定する)と点灯させようとした瞬間にエラーでアプリが終了してしまいます。 やはり、IDの指定方法に加えて、ライトを使用する上で何か"許可"を取得する必要があるのかもしれません。 公式リファレンスにもっと詳しく書いておいて欲しいものですが(公式には「カメラが起動している場合はライトの制御ができない場合があります」とだけ記載があります)、引き続き調査してみます。 https://developer.android.com/reference/android/hardware/camera2/CameraManager.TorchCallback#onTorchModeChanged(java.lang.String,%20boolean)
m-mega

2021/09/21 08:50

返答が遅くなってしまい申し訳ありません。 情報共有ありがとうございます!いただいた情報を実装してみます。
guest

回答1

0

自己解決

hoshi-takanoriさんからいただいた情報をもとに修正したところ、無事に問題を解決することができました!本当にありがとうございました。

以下に修正点と、修正後のコードの一部を掲載します(コード全文は本文を参照)。

修正点

kotlin

1cameraManager.setTorchMode(cameraId, !torchSw)

点灯、消灯の処理に使用していたこちらの処理を以下の処理に変更。

kotlin

1captureSession?.setRepeatingRequest(captureRequestBuilder.build(), null, null)

その上で、LEDの状態を制御するコードとして、以下を追加。

kotlin

1 if(!torchSw) { // false(消灯中)の場合 2 captureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON) 3 captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH) 4 } else { // true(点灯中)の場合 5 captureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON) 6 captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF) 7 }

つまり、改めてIDを指定して制御しようとするとエラーが出るので、IDの指定はせずに状態のみを変更すると良いことがわかりました。修正箇所を含むコードの一部を以下に記します。

kotlin

1 // LEDの点灯消灯切り替え 2 @RequiresApi(Build.VERSION_CODES.M) 3 private fun switchLight() { 4 if(!torchSw) { // false(消灯中)の場合 5 captureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON) 6 captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH) 7 } 8 else { // true(点灯中)の場合 9 captureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON) 10 captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF) 11 } 12 // 状態の継続 13 captureSession?.setRepeatingRequest(captureRequestBuilder.build(), null, null) 14 // 状態を反転させて、消灯なら点灯、点灯なら消灯させる 15 torchSw = !torchSw 16 // cameraManager.setTorchMode(cameraId, !torchSw) <- 削除した部分 17 Log.i("switchLight","torchSw : ${torchSw}") 18 }

投稿2021/09/21 09:52

編集2021/09/21 09:54
m-mega

総合スコア56

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問