【Android/Kotlin】QRコードを生成する

# QRコード生成
## やること
- gradleに追加 
 `implementation 'com.journeyapps:zxing-android-embedded:4.3.0`
- `MultiFormatWriter` クラスをインスタンス化
- `MultiFormatWriter` クラスの `encode` メソッドを使用し `BitMatrix` を作る

## しらない登場人物の説明
- `MultiFormatWriter` クラス
→　要求された内容でバーコードをエンコードするクラス
- `BitMatrix`
→ QRコードのデータを保持する二次元配列。
　QRコードの白黒のパターンが、0と1のビット列で表現されており、`MultiFormatWriter`クラスの`encode()`メソッドによって生成され、QRコードのパターンとそのサイズを指定する。
- `Bitmap`
→ Androidで画像を表現するために使用されるクラスで、ビットマップ形式のイメージを表す。`BarcodeEncoder`の`createBitmap()`メソッドによって`BitMatrix`を`Bitmap`に変換する。
変換後、`Bitmap`は画像として表示することができる。

## 使用するライブラリの説明
- zxing
 https://github.com/journeyapps/zxing-android-embedded
 → Android開発でQRコード生成や読み取りといったら、このライブラリ！！

## こだわりポイント
- 関数を分けることで一つの関数の役割を明確に、可読性も高くする

## 作ってみる
##### QRコード生成
- QRコードの生成に失敗したらcatch に入りエラーログを出力する
- catch に入ったらなにもreturn しないため null をreturn する

```kotlin
/**
 * QRコードを生成する
 * @param data QRコード化したいデータ
 */
fun createQrCode(data: String): Bitmap? {
        return try {
            val bitMatrix = createBitMatrix(data)
            bitMatrix?.let { createBitmap(it) }
        } catch (e: Exception) {
            Log.e(simpleName, "${e.message}\n${e.stackTrace.joinToString("\n")}")
            null
        }
    }

```

##### BitMatrixを作成する
- `MultiFormatWriter` をインスタンス化する
- 変数`hints` に QRコードを生成するときのオプションを任意で追加する
- `MultiFormatWriter` クラスの `encode` メソッドを使用して `BitMatrix` を生成する

```kotlin
/**
 * BitMatrixを作成する
 * @param data QRコード化したいデータ
 */
fun createBitMatrix(data: String): BitMatrix? {
      val multiFormatWriter = MultiFormatWriter()
      val hints = mapOf(
          // マージン
          EncodeHintType.MARGIN to 0,
          // 誤り訂正レベルを一番低いレベルで設定 エンコード対象のデータ量が少ないため
          EncodeHintType.ERROR_CORRECTION to ErrorCorrectionLevel.L
      )

       return multiFormatWriter.encode(
          data, // QRコード化したいデータ
          BarcodeFormat.QR_CODE, // QRコードにしたい場合はこれを指定
          200, // 生成されるイメージの高さ(px)
          200, // 生成されるイメージの横幅(px)
          hints // オプション
      )
  }
```

##### Bitmap を作成する
- `BarcodeEncoder` をインスタンス化する
- `BarcodeEncoder` クラスの`createBitmap` メソッドを使用して、`BitMatrix`を`Bitmap`に変換する

```kotlin
fun createBitmap(bitMatrix: BitMatrix): Bitmap {
        val barcodeEncoder = BarcodeEncoder()
        return barcodeEncoder.createBitmap(bitMatrix)
    }
```

##### いよいよQRコードを作成する
- QRコード化したいStringデータを引数にとる
- `BitMatrix` 生成メソッドで`BitMatrix`を生成し変数に格納
- `Bitmap` 生成メソッドで`BitMatrix`を引数にとり実行
- 以上の処理とtry,catchし、結果を`return`する

```kotlin
fun createQrCode(data: String): Bitmap? {
        return try {
            val bitMatrix = createBitMatrix(data)
            bitMatrix?.let { createBitmap(it) }
        } catch (e: Exception) {
            // エラーハンドリングなどはよしなに
            null
        }
    }
```

##### QRコード生成メソッドを実行する
```kotlin
// Acticity
ImageView qrImage = findViewById(R.id.qr_image);

val qrCode = createQrCode("おつかれさまでした")

qrImage.setImageBitmap(qrCode)
```
```html
<ImageView
    android:id="@+id/qr_image"
    android:layout_width="250dp"
    android:layout_height="250dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent" />
```

##### ImageView にこのようなQRコードが埋め込まれる
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917260/41286e5b-2700-5a18-8456-622b19a8225b.png)

## さいごに
QRコード生成の`bitmap`やら`BitMatrix`やらがなんなのかわからずQRコード生成にてこずったのでまとめてみました。
がんばるぞい！