HMS Scan Kit実装入門

# HMS Scan Kitの特徴
HMS Scan KitはQRコードやバーコードのスキャン機能を提供するライブラリです。簡単に導入できるのが特徴です。

# サポートデバイス
Android 4.4以上

# サポートコード
- QR Code
- Data Matrix
- PDF417
- Aztec
- EAN-8
- EAN-13
- UPC-A
- UPC-E
- Codabar
- Code 39
- Code 93
- Code 128
- ITF-14

# 実装手順

## 前準備
(1) Huaweu Developerを登録します。

(2) AppGallery Connectでアプリのプロジェクトを登録します。
<img width="300" alt="スクリーンショット 2020-10-01 155726.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/7ad86f57-75ef-2aa1-7f8a-89ba53ec0ae1.png">
<img width="300" alt="スクリーンショット 2020-10-01 155747.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/910d9b63-0bf4-90fd-3aba-168b4eb26310.png">
<img width="300" alt="スクリーンショット 2020-10-01 155822.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/890cd9ee-09ad-3e72-d9fb-7b1d95d48c45.png">
<img width="300" alt="スクリーンショット 2020-10-01 155911.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/50d68b1d-4b5f-d185-2ecc-3b03c4175ad7.png">
<img width="300" alt="スクリーンショット 2020-10-01 155946.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/25cf901a-7e9f-fbde-9eeb-63504bb9a821.png">

(3) keytoolで生成したSHA256をAppGallery Connectのアプリプロジェクトに登録します。
<img width="300" alt="スクリーンショット 2020-10-01 160111.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/60cc348f-e029-8b02-8291-b16df40dd33d.png">

(4) agconnect-services.jsonをダウンロードし、appフォルダに配置します。
<img width="300" alt="スクリーンショット 2020-10-01 161111.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/f50eb1bb-6cbd-4575-0cb3-8f40b19c871d.png">
<img width="200" alt="スクリーンショット 2020-10-01 162011.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/74e4218e-ea0d-fbbf-6cc3-134ff40d9c0f.png">

## HMS SDKを導入
(1) プロジェクトのbuild.gradleを開き、mavenとclasspathを追加します。
<img width="200" alt="スクリーンショット 2020-10-01 162820.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/7ee345a1-2c6d-9857-deed-776060a09de4.png">

```gradle:build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    ext.kotlin_version = "1.3.72"
    repositories {
        google()
        jcenter()

        // こちらの行を追加
        maven {url 'http://developer.huawei.com/repo/'}
    }
    dependencies {
        classpath "com.android.tools.build:gradle:4.0.1"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files

        // こちらの行を追加
        classpath 'com.huawei.agconnect:agcp:1.3.1.300'
    }
}

allprojects {
    repositories {
        google()
        jcenter()

        // こちらの行を追加
        maven { url 'http://developer.huawei.com/repo/' }
    }
}
```

(2) モジュールのbuild.gradleを開き、次のようにを追加します。
<img width="200" alt="スクリーンショット 2020-10-01 162842.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/7cd74ac6-a36a-dbdd-30ea-fb24c14f0408.png">

```gradle:build.gradle
plugins {
    id 'com.android.application'
    id 'kotlin-android'

    // こちらの行を追加
    id 'com.huawei.agconnect'
}

android {
    // signingConfigsを追加
    signingConfigs {
        debug {
            storePassword 'My password'
            keyAlias 'My keyAlias'
            keyPassword 'My password'
            storeFile file('My keystore file.jks')
            v1SigningEnabled true
            v2SigningEnabled true
        }
        release {
            storePassword 'My password'
            keyAlias 'My keyAlias'
            keyPassword 'My password'
            storeFile file('My keystore file.jks')
            v1SigningEnabled true
            v2SigningEnabled true
        }
    }

    buildTypes {
        release {
            // signingConfigを追加
            signingConfig signingConfigs.release

            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }

        debug {
            // signingConfigを追加
            signingConfig signingConfigs.debug

            debuggable true
        }
    }

    buildFeatures {
        dataBinding true
    }
}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.core:core-ktx:1.6.0'
    implementation 'androidx.appcompat:appcompat:1.3.1'
    implementation 'com.google.android.material:material:1.4.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
    implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

    // こちらの１行を追加
    implementation 'com.huawei.hms:scan:2.2.0.300'
}
```

(3) proguard-rules.proを開き、次のようにを追加します。
<img width="200" alt="スクリーンショット 2020-10-01 162901.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/01ff236e-58c6-0000-165a-99daa78f64e8.png">

```java:proguard-rules.pro
-ignorewarnings
-keepattributes *Annotation*
-keepattributes Exceptions
-keepattributes InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
-keep class com.huawei.hianalytics.**{*;}
-keep class com.huawei.updatesdk.**{*;}
-keep class com.huawei.hms.**{*;}
```

## 権限付与
入力でカメラを使う場合はカメラの権限（CAMERA）を、画像を使う場合はストレージ読み込みの権限（READ_EXTERNAL_STORAGE）を宣言します。

```xml:AndroidManifest.xml
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
```

## ライブラリの使用
本稿では入力をカメラにします。

(1) カメラの権限を要求します
ロジックはこちらをご参照ください
https://qiita.com/Rei_2020/items/63fe4216835141d03c4a#%E3%83%91%E3%83%BC%E3%83%9F%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E8%A6%81%E8%AB%8B

(2) Scan Kitを起動します

```kotlin
companion object {
    private const val REQUEST_CODE_SCAN_ONE = 200
}

.
.
.

ScanUtil.startScan(
    requireActivity(),
    REQUEST_CODE_SCAN_ONE,
    null
)
```

(3) スキャン結果を受け取ります

```kotlin
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)

    if (resultCode != Activity.RESULT_OK) {
        return
    }

    data?.let { data ->
        when (requestCode) {
            REQUEST_CODE_SCAN_ONE -> {
                val hmsScan = data.getParcelableExtra(ScanUtil.RESULT) as HmsScan?
                hmsScan?.let { hmsScan ->
                    // QRコードのリンク：hmsScan.linkUrl.linkvalue
                }
            }
            else -> {

            }
        }
    }
}
```


# GitHub
[https://github.com/Rei2020GitHub/MyPublicProject/tree/master/ScanKitDemo](https://github.com/Rei2020GitHub/MyPublicProject/tree/master/ScanKitDemo)

# 参考
* HMS：[https://developer.huawei.com/consumer/jp/](https://developer.huawei.com/consumer/jp/)
* HMS Scan Kitの紹介：[https://developer.huawei.com/consumer/jp/hms/huawei-scankit/](https://developer.huawei.com/consumer/jp/hms/huawei-scankit/)
* HMS Scan Kitのドキュメント：[https://developer.huawei.com/consumer/jp/doc/development/HMSCore-Guides/service-introduction-0000001050041994](https://developer.huawei.com/consumer/jp/doc/development/HMSCore-Guides/service-introduction-0000001050041994)
* Huawei Developers：[https://forums.developer.huawei.com/forumPortal/en/home](https://forums.developer.huawei.com/forumPortal/en/home)
* Facebook Huawei Developersグループ：[https://www.facebook.com/Huaweidevs/](https://www.facebook.com/Huaweidevs/)