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


Google Play 開発者サービスについて

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

Google Play 開発者サービスをサポートしないというポップアップ

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

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

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

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()のエラーダイアログはこのようなものです。

表示される文言は決まっています。

既存アプリのHMS対応の動き

Google Play 開発者サービスの利用を前提に開発されるアプリでは、Google Play 開発者サービスが利用できないと分かった時点で、すぐにエラーダイアログを出すというロジックをとるものが多いです。しかし、このやり方だと、集客の幅を制限してしまいます。

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

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

HMS対応時の注意点

HMS対応において、ロジックは一般的に次のように改修します。

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

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

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

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)で実行します。

“GMSを確認する”ボタンをタップすると、こうなります。

Google Play 開発者サービスをサポートしないというポップアップが出てきます。

HMSあり、GMSありの端末

次はHMSあり、GMSありの端末(HUAWEI P30 lite)で実行します。結果がこうなります。

HMSなし、GMSなしの端末

最後はHMSなし、GMSありのエミュレータで実行します。

“GMSを確認する”ボタンをタップすると、こうなります。

“HMSを確認する”ボタンをタップすると、こうなります。

“先にGMSを確認し、見つからない場合はHMSを確認する”ボタンをタップすると、こうなります。

最後

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

GitHub

参考