HMS対応におけるGoogle Play 開発者サービスをサポートしないというポップアップの問題点とその解決策

# Google Play 開発者サービスについて
Google Play 開発者サービスとは、Android端末でグーグルのサービスを利用するためのものです。たとえば、グーグルのプッシュ通知やグーグルアカウントを使う場合、Google Play 開発者サービスがないと使えません。

# Google Play 開発者サービスをサポートしないというポップアップ
通常、アプリ開発の際、グーグルのサービスを利用する場合は次のようなロジックを実装します。

1. Google Play 開発者サービスが利用できるかどうかを確認する。
2. Google Play 開発者サービスが利用できる場合、そのまま進む。
3. Google Play 開発者サービスが利用できない場合、エラー処理に入る。

ネットでサンプルコードを調べたら、だいたいこのような書き方が出てきます。

```java
private boolean checkPlayServices() {
    GoogleApiAvailability googleAPI = GoogleApiAvailability.getInstance();
    int result = googleAPI.isGooglePlayServicesAvailable(this);
    if(result != ConnectionResult.SUCCESS) {
        if(googleAPI.isUserResolvableError(result)) {
            googleAPI.getErrorDialog(this, result,
                    PLAY_SERVICES_RESOLUTION_REQUEST).show();
        }

        return false;
    }

    return true;
}
```

そのロジックはこういうものです。

1. GoogleApiAvailability.isGooglePlayServicesAvailable()でGoogle Play 開発者サービスの利用可能状況を取得する。
2. 戻り値がConnectionResult.SUCCESSでなければ、Google Play 開発者サービスが利用できないと判断する。
3. その場合、GoogleApiAvailability.getErrorDialog()でエラーダイアログを生成し、表示する。

GoogleApiAvailability.getErrorDialog()のエラーダイアログはこのようなものです。
<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/7d7ef65b-5770-aef0-2ee3-04951110819c.jpeg">
表示される文言は決まっています。

# 既存アプリの[HMS](https://developer.huawei.com/consumer/jp/)対応の動き
Google Play 開発者サービスの利用を前提に開発されるアプリでは、Google Play 開発者サービスが利用できないと分かった時点で、すぐにエラーダイアログを出すというロジックをとるものが多いです。しかし、このやり方だと、集客の幅を制限してしまいます。

[HMS](https://developer.huawei.com/consumer/jp/)はファーウェイが開発しているモバイルサービスであり、Google Play 開発者サービスと同等なサービスを提供しています（詳細はこちらへ：[HMSとAppGalleryについて](https://qiita.com/Kirin9000/items/76b7aca0135aa3ade517)）。Google Play 開発者サービスが利用できない場合、すぐにエラーダイアログを出すのではなく、HMSの存在を確認し、HMSが利用できる場合、HMSを利用するというロジックをとったほうが、より多くのユーザーにアプリを使ってもらえます。

そのため、最近既存アプリをHMSに対応する動きが広まっています。

# [HMS](https://developer.huawei.com/consumer/jp/)対応時の注意点
HMS対応において、ロジックは一般的に次のように改修します。

1. Google Play 開発者サービスが利用できるかどうかを確認する。
2. Google Play 開発者サービスが利用できる場合、Google Play 開発者サービスを利用する。
3. Google Play 開発者サービスが利用できない場合、HMSが利用できるかどうかを確認する。
4. HMSが利用できる場合、HMSを利用する。
5. HMSも利用できない場合、Google Play 開発者サービスをサポートしないというポップアップ、またはHMSをサポートしないというポップアップを出す。

もとのロジックを上記のロジックに改修するときの注意点はエラーポップアップを出すタイミングです。HMSが利用できる場合はエラーポップアップを出さないことがこの改修のポイントです。

下記は改修のサンプルコードです。

```kotlin:MainActivity.kt
private fun checkGooglePlayServicesAndHmsAvailable() {
    val googleApiAvailability = GoogleApiAvailability.getInstance()

    // まずGMSの存在確認を行う
    googleApiAvailability.isGooglePlayServicesAvailable(this).let { googleErrorCode ->
        // com.google.android.gms.common.ConnectionResult.SUCCESS = 0: The connection was successful.
        // com.google.android.gms.common.ConnectionResult.SERVICE_MISSING = 1: Google Play services is missing on this device.
        // com.google.android.gms.common.ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED = 2: The installed version of Google Play services is out of date.
        // com.google.android.gms.common.ConnectionResult.SERVICE_DISABLED = 3: The installed version of Google Play services has been disabled on this device.
        // com.google.android.gms.common.ConnectionResult.SERVICE_INVALID = 9: The version of the Google Play services installed on this device is not authentic.
        // com.google.android.gms.common.ConnectionResult.SERVICE_UPDATING = 9004: Google Play service is currently being updated on this device.
        if (com.google.android.gms.common.ConnectionResult.SUCCESS != googleErrorCode) {
            val huaweiApiAvailability = HuaweiApiAvailability.getInstance()

            // GMSが使えない場合はHMSの存在確認
            huaweiApiAvailability.isHuaweiMobileServicesAvailable(this).let { huaweiErrorCode ->
                // com.huawei.hms.api.ConnectionResult.SUCCESS = 0: connection succeeded.
                // com.huawei.hms.api.ConnectionResult.SERVICE_MISSING = 1: no HMS Core (APK) found on the device.
                // com.huawei.hms.api.ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED = 2: The installed HMS Core (APK) is out of date.
                // com.huawei.hms.api.ConnectionResult.SERVICE_DISABLED = 3: The HMS Core (APK) installed on this device is unavailable.
                // com.huawei.hms.api.ConnectionResult.SERVICE_INVALID = 9: The HMS Core (APK) installed on the device is not the official version.
                // com.huawei.hms.api.ConnectionResult.SERVICE_UNSUPPORTED = 21: The device is too old to be supported.
                if (com.huawei.hms.api.ConnectionResult.SUCCESS != huaweiErrorCode) {
                    // GMSもHMSも使えない場合、まずユーザーがGMSエラー対処ができるかどうかを確認する
                    if (googleApiAvailability.isUserResolvableError(googleErrorCode)) {
                        // GMSエラー対処が可能な場合は、GMSエラーダイアログを表示する
                        googleApiAvailability.getErrorDialog(
                                this,
                                googleErrorCode,
                                REQUEST_CODE
                        ).apply {
                            setOnDismissListener {
                                // GMSが見つからないポップアップ終了後の処理
                            }
                        }.show()
                    }
                    // ユーザーがGMSエラー対処ができない場合、ユーザーがHMSエラー対処ができるかどうかを確認する
                    else if (huaweiApiAvailability.isUserResolvableError(huaweiErrorCode)) {
                        // HMSエラー対処が可能な場合は、HMSエラーダイアログを表示する
                        huaweiApiAvailability.getErrorDialog(
                                this,
                                huaweiErrorCode,
                                REQUEST_CODE
                        ).apply {
                            setOnDismissListener {
                                // HMSが見つからないポップアップ終了後の処理
                            }
                        }.show()
                    } else {
                        // ユーザーが対処不可なエラー
                    }
                }
            }
        }
    }
}
```

# サンプルコードの実行結果
サンプルコードのAndroidプロジェクトはGitHubにあります。それを3種類の端末で実行してみます。

### HMSあり、GMSなしの端末
HMSあり、GMSなしの端末（HUAWEI P40 lite 5G）で実行します。
<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/558de376-367c-07ff-be73-726f52c5fbb4.jpeg">
“GMSを確認する”ボタンをタップすると、こうなります。
<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/5db55b50-4508-b2a6-3eba-e67d741302c5.jpeg">
Google Play 開発者サービスをサポートしないというポップアップが出てきます。

### HMSあり、GMSありの端末
次はHMSあり、GMSありの端末（HUAWEI P30 lite）で実行します。結果がこうなります。
<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/19862ed9-2fcc-8d81-56e1-c52d32302889.jpeg">

### HMSなし、GMSなしの端末
最後はHMSなし、GMSありのエミュレータで実行します。
<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/84a69f47-7720-e63f-ca9a-59e2f03a787f.png">
“GMSを確認する”ボタンをタップすると、こうなります。
<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/2b71f4f8-458e-2c72-9596-783445f46b9e.png">
“HMSを確認する”ボタンをタップすると、こうなります。
<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/94345a3a-6afc-e0bd-307b-2dd3b5f4b9db.png">
“先にGMSを確認し、見つからない場合はHMSを確認する”ボタンをタップすると、こうなります。
<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/7adf7801-ce87-250f-c2d9-c6f5081b2034.png">

# 最後
Google Play 開発者サービスのエラーポップアップは、HMS対応における最初の課題です。しかしこの課題の解決策は非常に簡単です。みなさんもぜひ上記のサンプルを参考に、HMS対応を始めてみてください。

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

# 参考
* HMS：[https://developer.huawei.com/consumer/jp/](https://developer.huawei.com/consumer/jp/)
* HuaweiApiAvailability：[https://developer.huawei.com/consumer/jp/doc/development/HMS-References/huaweiapiavailability](https://developer.huawei.com/consumer/jp/doc/development/HMS-References/huaweiapiavailability)
* 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/)