AndroidアプリでGoogle Play Serviceの使用可否を検証する


AndroidアプリでGoogle APIやFirebaseを利用する場合、Google Play Service(Google Play開発者サービス) を介してGoogleの各サービスにアクセスします。
このとき、アプリは端末に入っているGoogle Play Serviceのバージョンが適切かどうかチェックするよう推奨しています。
一例として、別のエントリでFirebase Cloud Messagingの実装方法について書きましたが、Firebase公式のドキュメントにはこんなことが書かれていたりします。

Play開発者サービスのSDKに依存するアプリについては、Google Play開発者サービス機能にアクセスする前に、互換性のあるGoogle Play開発者サービスのAPKが端末にインストールされているかどうかをアプリが必ずチェックする必要があります。

Googleサービスにアクセスするために必須と思われるこの作業について検証しました。

Google Play Serviceについて

Androidユーザーなら一度は目にしたことのあるはずの「Google Play開発者サービス」がそれです。詳細についてはこの記事など、探せば色々出てきますので気になる方は調べてみてください。
アプリがGoogleの各種サービス(Google MapやGoogle Driveなど)にアクセスするための仲介をしてくれるものだと考えればだいたい間違いないと思います。

Google Play Service自体はAndroidに内包されているものではなく、Google Playで配布されています。
そのため、アプリは端末がGoogle Play Serviceをサポートしているかを気にする必要がありません。必要ならGoogle Playからダウンロードして貰うというスタンスです。

環境

このページに書かれているコード等は以下の環境下で動作・検証しています。

  • macOS Mojave 10.14.4
  • Android Studio 3.4.1
  • Nexus5x + Android 7.1.2

テスト可能な環境について書かれている内容をテストするには以下のいずれかが必要です。
  • PlayストアがインストールされたAndroid4.1以降の端末
  • Google APIsプラットフォームが含まれるAndroid4.2.2以上のエミュレータ

Google Play Serviceのセットアップ

Android Studioのメニューから、Tools > Android > SDK Manager の順にクリック。
SDK Managerが起動したら、「SDK Tools」タブにある項目のうち「Support Repository」を展開します。
その下に「Google Repository」というのがありますので、これをアップデートしてください。

APIの追加

app/build.gradleのdependenciesにビルドルールを追加します。
公式にGoogleサービスごとにdependenciesに追加すべき内容がリストされていますので、必要な記述を追加してください。
本稿ではFirebase Cloud Messagingを使いますので、以下の記述を追加しています。

build.gradle
implementation 'com.google.firebase:firebase-messaging:18.0.0'

バージョンを検証する

バージョンを検証するためにはGoogleApiAvailabilityを使います。
以前は GoogleApiClient も使えたのですが、非推奨になっていました。

GoogleApiAvailability クラスのメソッド isGooglePlayServicesAvailable を使います。
「is〜」で始まるメソッドですが、返ってくるのは Boolean でなく状態を示す Int 値です。この Int 値は、ConnectionResultクラスの定数に対応します。

// 1. Google APIの使用可否を判定
val errorCode = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this)

// 2. 1の戻り値を調べて、何が起こったのかログに吐いてみる
Log.i("GOOGLE-SERVICE", when (errorCode) {
    ConnectionResult.SUCCESS -> "The connection was successful."
    ConnectionResult.SERVICE_MISSING -> "Google Play services is missing on this device."
    ConnectionResult.SERVICE_UPDATING -> "Google Play service is currently being updated on this device."
    ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED -> "The installed version of Google Play services is out of date."
    ConnectionResult.SERVICE_DISABLED -> "The installed version of Google Play services has been disabled on this device."
    ConnectionResult.SERVICE_INVALID -> "The version of the Google Play services installed on this device is not authentic."
    else -> "Unknown."
})

バージョンを検証したあとの対応

端末に適当なバージョンにGoogle Play Serviceが入っていなければ、ダイアログを出してPlayストアで更新するように勧めます。
GoogleApiAvailability#isGooglePlayServicesAvailable で得られるエラーコードを使えば、いくつかの方法でユーザーに更新を促すことができます。
ここでは、ダイアログを出す方法と通知を出す方法を書いておきます。

ダイアログを出す

Playストアを起動させるダイアログを表示します。リクエストコードを使って、Playストアから戻ってきたタイミングをonActivityResultで捕捉することもできます。

val requestCode = 10001
GoogleApiAvailability.getInstance().showErrorDialogFragment(this, errorCode, requestCode)

ダイアログです。『更新』を押すと、PlayストアのGoogle Play開発者サービスのページが開きます。

通知を出す

Playストアを起動させる通知を表示します。

googleapiavailability.getinstance().showerrornotification(this, errorcode)

1番上がその通知です。タップすると、PlayストアのGoogle Play開発者サービスのページが開きます。

バージョンを検証するタイミング

これらの検証は、onCreateやonResumeで行うことを推奨されています。

メインアクティビティの onCreate() メソッドと onResume() メソッドの 2 か所で行うことをおすすめします。onCreate() では、チェックにパスしないとアプリを使用できないようにします。onResume() では、ユーザーが [戻る] ボタンなどの他の手段を使って実行中のアプリに戻った場合にもチェックされるようにします。

Google Play開発者サービスの初期化について

これらをテストするためにGoogle Play開発者サービスをダウングレードする必要があるかも知れません。
初期化したい場合は、Android7(Nexus5x)なら設定画面からセキュリティ > 端末管理アプリと遷移して、『Androidデバイスマネージャー』のチェックを外すと、Google Play管理者サービスのアプリ詳細画面で『アップデートのアンインストール』が押せるようになります。

Android9(Pixel3a)だと、セキュリティと現在地情報 > 詳細設定 > 端末管理アプリで『デバイスを探す』が変更できます。他のバージョンでも同じような場所にあると思われます。

まとめ

Google Play Serviceのバージョンを検証する方法についてまとめてみました。
余談ですが、Firebase Cloud MessagingはGoogle Play開発者サービスが適切なバージョンでなくてもメッセージが受信できてしまいます。
この判定要らないのかも…とは思うのですが、Google御大が推奨しているので検証した方がいいのでしょう。

改訂履歴

  • 2019/05/21
    • サンプルコードをKotlinに変更しました。
    • サンプルコードの動作・検証環境を変更しました。
    • 非推奨となったGoogleApiClient関連の記述を削除しました。
    • Playに遷移するためのトリガーに通知を追加しました。