LoginSignup
2

More than 3 years have passed since last update.

Androidアプリ&Kotlinでハマった点の技術的原因と対応方法(2.Android*のカメラ機能に関する処理)

Last updated at Posted at 2018-11-21

2.Androidのカメラ機能に関する処理

カメラ撮影後のイメージ保存場所は、サードベンダーが提供するカメラアプリ毎に相違があるようで、暗黙的Intentパラメータの挙動、内容に注意する必要があります。
また、Androidバージョン6.0以降になると権限チェック及び権限付与確認をアプリの初起動時にユーザへ求めることになります。

2.1 画像選択時のギャラリー又はカメラ機能を選択するChooser処理

<背景>

本アプリでは、Android端末内のギャラリーの画像もしくはカメラ撮影を実施した後、画面遷移後にイメージ画像を貼り付ける処理を行います。

<課題>

Android端末内のギャラリーの画像もしくはカメラ撮影の2つの機能(暗黙的Intent(ギャラリー機能)/暗黙的Intent(カメラ機能))のIntent登録において、画面選択ボタンをタッチすると暗黙的Intent(ギャラリー機能)のみで暗黙的Intent(カメラ機能)が表示されない。
一方で、直後にキャンセルして再度、画面選択ボタンをタッチすると暗黙的Intent(ギャラリー機能)が複数表示されます。

<原因>

Android端末内のギャラリーの画像もしくはカメラ撮影の2つの機能のIntent登録の順番に誤りがありました。

<対応>

2つの機能(暗黙的Intent(ギャラリー機能)/暗黙的Intent(カメラ機能))のIntent登録を下記の順とします。
①暗黙的Intent(カメラ機能)の作成
②暗黙的Intent(ギャラリー機能)の作成
Chooserの作成

暗黙的Intent(ギャラリー機能/カメラ機能)の登録順
// ..... 略
    private fun addPhoto(requestCode: Int) {
        getCameraIntent()
        createChooserIntent()
// ..... 略
    }
// ..... 略
暗黙的Intent(カメラ機能)の作成
// ..... 略
    private fun getCameraIntent() {
        Intent(MediaStore.ACTION_IMAGE_CAPTURE)
// ..... 略
    }
// ..... 略
暗黙的Intent(ギャラリー機能)&Chooserの作成
// ..... 略
    private fun createChooserIntent(): Intent {
        Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
            addCategory(Intent.CATEGORY_OPENABLE)
            type = "image/*"
        }
        return Intent.createChooser(引数).apply {
            putExtra(Intent.EXTRA_INITIAL_INTENTS, 引数)
        }
    }
// ..... 略

2.2 Chooserのカメラ機能に他カメラアプリを除外する処理

<背景>

本アプリでは、画面選択ボタンをタッチしてギャラリーの画像もしくはサードベンダーが提供するカメラアプリを除外してカメラ撮影を実施した後、画面遷移後にイメージ画像を貼り付ける処理を行います。

<課題>

サードベンダーが提供するカメラアプリが撮影画像の保存場所が不明のため、影響度を考慮してChooserから除外します。

<原因>

なし

<対応>

暗黙的Intent(カメラ機能)の作成後、内蔵カメラ機能のクラス名とマッチした場合に新たな暗黙的Intent(カメラ機能)を作成します。

他カメラアプリ除外
// ..... 略
    Intent(MediaStore.ACTION_IMAGE_CAPTURE).apply {
        val intentInfoList = context?.packageManager?.queryIntentActivities(this, 0) ?: return

        // 他カメラアプリの仕様が不明のため、内蔵カメラのみ対象
        for (intentInfo in intentInfoList) {
            val packageName = intentInfo.activityInfo.packageName
            val name = intentInfo.activityInfo.name
            if (name.contains(CAMERA_CLS_NAME)) { // CAMERA_CLS_NAME → "com.android.camera"
                Intent(MediaStore.ACTION_IMAGE_CAPTURE).apply {
// ..... 略
                }
            }
        }
    }
// ..... 略

2.3 カメラ撮影時のonActivityResult()Intentパラメータ処理

<背景>

本アプリでは、画面選択ボタンをタッチしてギャラリーの画像もしくはカメラ撮影を実施した後、画面遷移後にイメージ画像を貼り付ける処理を行います。

<課題>

画像選択ボタンをタッチしてギャラリーの画像もしくはカメラ撮影を実施した後、画面遷移先レイアウト上のImageViewにイメージ画像が表示されず、画面が真っ白になります。

<原因>

IntentChooser付きの暗黙的Intent(カメラ機能)を作成する場合、putExtra(MediaStore.EXTRA_OUTPUT, cameraUri) を除外しないとonActivityResult()Intentパラメータがnullになるため、Intent先でカメラ撮影のUriを取得できません。
(公式ドキュメントの暗黙的Intent例を使用)

<対応>

putExtra(MediaStore.EXTRA_OUTPUT, cameraUri) を除外して暗黙的Intent(カメラ機能)を作成します。

putExtra()除外
// ..... 略
    Intent(MediaStore.ACTION_IMAGE_CAPTURE).apply {
        val intentInfoList = context?.packageManager?.queryIntentActivities(this, 0) ?: return

        // 他カメラアプリの仕様が不明のため、内蔵カメラのみ対象
        for (intentInfo in intentInfoList) {
            val packageName = intentInfo.activityInfo.packageName
            val name = intentInfo.activityInfo.name
            if (name.contains(CAMERA_CLS_NAME)) { // CAMERA_CLS_NAME → "com.android.camera"
                Intent(MediaStore.ACTION_IMAGE_CAPTURE).apply {
// ..... 略
                    // putExtra(MediaStore.EXTRA_OUTPUT, cameraUri) → 除外
                }
            }
        }
    }
// ..... 略

リンク

初めてのAndroidアプリ&Kotlinでハマった点の技術的原因と対応方法
1.Androidの画面遷移(フラグメント)処理
3.Androidの画像に関する処理

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
2