【コピペで作る】kotlin QRコード導入手順5ステップ

Androidアプリを作成していてQRコードで簡単に情報交換をするアプリが増えていますね。 調べるとたくさん導入方法が出てくるのですが、画面全体がQRコードリーダーになってしまい、デザイン性にかけるので、 この記事では好きな範囲だけQRコードとしてカメラの映像を設定できるやり方、ライブラリの導入までをご紹介したいと思います。


参考にしたサイトはこちらです。

AndroidアプリでQRコードの読取、生成をする
ZXing Android Embedded | GitHub
[エラー対策]Androidサポートライブラリのバージョンコンフリクト解消方法


手順

  1. ライブラリの導入
  2. カメラのViewを設置する
  3. パーミッションの確認
  4. QRカメラを初期化する
  5. ダイアログで権限を取得した後の処理
  6. 結果


ライブラリの導入

まずはライブラリを導入します。 今回はQRコードのライブラリの中でもっとも使用されている "zxing-android-embedded" を入れます。

// build.grade

dependencies {
    implementation 'com.journeyapps:zxing-android-embedded:3.6.0'
    ...
}

Syncするとこの様に怒られると思います。

バージョンのコンフリクト

All com.android.support libraries must use the exact same version specification (mixing version can lead to runtime crashes).Found versions 28.0.0, 25.3.1.Examples include com.android.support:animated-vector-drawable:28.0.0 and com.android.support:support-media-compat:25.3.1

つまり、ライブラリの中にあるバージョンが矛盾しているので、どっちかにして。 ということです。


実際にライブラリの中のモジュールを探っていくと。 「 Project > プロジェクト名 > .idea > libraries 」

ライブラリの確認
コンフリクトを起こしているバージョン確認

違うバージョンのサポートファイルがありました。 のでそれらをアップデートしてくれる様に以下を追記します。

dependencies {
    // ↓ 追記
    implementation 'com.android.support:support-media-compat:28.0.0'
    implementation 'com.android.support:support-v4:28.0.0'

    implementation 'com.journeyapps:zxing-android-embedded:3.6.0'
    ...
}

するとエラーが解消できます。


さらに AndroidManifest.xml<Application> タグ内、<uses-permission> にも以下の利用権限について追記しておきましょう。

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<application
            ...
            android:hardwareAccelerated="true">


カメラのViewを設置する

xmlファイルにカメラが起動する範囲の設定をします。 画面全体をQRカメラにする事も可能ですが、デザインに融通がきく様にxmlファイルにviewを明示的に設置することをお勧めします。

// activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <com.journeyapps.barcodescanner.CompoundBarcodeView
            android:id="@+id/qr_view"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintDimensionRatio="1:1"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintHorizontal_bias="0.0" android:layout_marginBottom="8dp"
            app:layout_constraintBottom_toBottomOf="parent" android:layout_marginTop="8dp"
            app:layout_constraintTop_toTopOf="parent" android:layout_marginEnd="8dp" android:layout_marginRight="8dp"
            android:layout_marginLeft="8dp" android:layout_marginStart="8dp"/>

</android.support.constraint.ConstraintLayout>

view設定


パーミッションの確認

QRコードを利用するKotlinファイルの初めにパーミッションの確認をする為のメソッドを用意しておきましょう。

private fun checkPermissions() {
    // already we got permission.
    if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
        qr_view.resume()
    }

    if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.CAMERA)) {
        ActivityCompat.requestPermissions(this, arrayOf(android.Manifest.permission.CAMERA), 999)
    }
}


QRカメラを初期化する

QRカメラを初期化する為の処理と権限がなかった時にダイアログを出すメソッドを用意しておきます。 そして権限があった場合にカメラを起動するメソッドも書いておきます。

companion object {
    const val REQUEST_CAMERA_PERMISSION:Int = 1
}

@SuppressLint("WrongConstant")
private fun initQRCamera() {

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return

    val isReadPermissionGranted = (checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
    val isWritePermissionGranted = (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
    val isCameraPermissionGranted = (checkSelfPermission(android.Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED)

    if (isReadPermissionGranted && isWritePermissionGranted && isCameraPermissionGranted) {
        openQRCamera() // ← カメラ起動
    } else {
        requestPermissions(arrayOf(android.Manifest.permission.CAMERA, android.Manifest.permission.WRITE_EXTERNAL_STORAGE), REQUEST_CAMERA_PERMISSION)
    }
}
private fun openQRCamera() {
    qr_view.decodeContinuous(object : BarcodeCallback {
        override fun barcodeResult(result: BarcodeResult?) {
            if (result != null) {
                onPause()
                Log.d("QRCode", "$result")
            }
        }

        override fun possibleResultPoints(resultPoints: MutableList<ResultPoint>?) { }
    })
}


ダイアログで権限を取得した後の処理

このままだとダイアログで権限を取得した後にQRカメラをアクティブモードにしていないので、 カメラは起動しますが、QRコードを読み取りません。 下記の様にダイアログで権限を取得した後の処理 onRequestPermissionsResult を追記しておきます。

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    checkPermissions()
    initQRCamera()
}

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    when(requestCode) {
        REQUEST_CAMERA_PERMISSION -> { initQRCamera() }
    }
}


結果

まず、カメラとストレージについて権限を聞かれます。

権限アラート

その後QRコードの読み込みが可能になります。 上記のソースではログに結果の文字列を出力しています。

QRコードが読み取れた


終わりに

以上がQRコードの読み込み画面の作成になります。 QRコードの書き出しについては、先にあげたサイトを参考にしていただくといいと思います。 最近は文字の入力を極力少なくした様なUXでないと面倒と感じる事が多くなってきましたね。

QRコードはよく使う分、デザイナーさんもおしゃれなUIにしたいはずです。 なので今回はデザインに融通のきく様なQRコードの実装について書きました。

この記事がお役にたったら嬉しく思います。

最後まで読んでいただきありがとうございました。

0 コメント