Android 向けアプリ切り替え

OAuth ベースのアプリ切り替えリンク(アプリ切り替え)では、Android アプリが Google アカウントのリンクのフロー。従来のアカウントのリンクフローでは、 認証情報をブラウザに入力する必要があります。アプリ切り替えを使用するとユーザーが できます。これにより、既存の あります。ユーザーがアプリにログインしていれば、 認証情報を再入力してアカウントをリンクします。最小限のコード Android アプリにアプリ切り替えを実装するには、変更が必要です。

このドキュメントでは、Android アプリを アプリ切り替え。

サンプルを試す

アプリ切り替えのリンクのサンプルアプリ は、Android でのアプリ切り替え対応のアカウント リンク統合を示しています。マイページ このアプリを使用して、デバイスから受信したアプリ切り替えインテントに応答する方法を確認できます。 Google モバイルアプリ。

サンプルアプリは、App Flip Test Tool for Android、 を使用して、Android アプリと App Store との統合を検証できます。 Google とのアカウントのリンクを設定する前に裏返してください。このアプリは、 アプリ切り替えが有効な場合に Google モバイルアプリによってトリガーされるインテントです。

仕組み

アプリ切り替えの統合を行うには、次の手順が必要です。

  1. Google アプリは、アプリがデバイスにインストールされているかどうかを パッケージ名
  2. Google アプリは、パッケージ署名チェックを使用して、インストール済みの 正しいアプリであることを確認します。
  3. Google アプリは、アプリ内で指定されたアクティビティを開始するインテントを作成します。 このインテントには、リンクに必要な追加データが含まれています。また、 アプリがアプリ切り替えに対応しているかどうかを確認するには、 Android フレームワークです。
  4. リクエストが Google アプリからのものであることをアプリが検証します。そのためには、 アプリはパッケージの署名と指定されたクライアント ID をチェックします。
  5. アプリが OAuth 2.0 サーバーに認証コードをリクエストします。Google このフローが終了すると、認証コードまたはエラーが Google アプリ。
  6. Google アプリが結果を取得し、アカウントのリンクを続行します。条件 認証コードが提供されると、トークン交換が ブラウザベースの OAuth リンクと同じ方法で、サーバー間の接続を行います。 できます。

アプリ切り替えをサポートするように Android アプリを変更する

アプリ切り替えをサポートするには、Android アプリのコードを次のように変更します。

  1. アクションを使用して <intent-filter>AndroidManifest.xml ファイルに追加します。 [App Flip Intent] フィールドに入力した値と一致する文字列が表示されます。

    <activity android:name="AuthActivity">
      <!-- Handle the app flip intent -->
      <intent-filter>
        <action android:name="INTENT_ACTION_FROM_CONSOLE"/>
        <category android:name="android.intent.category.DEFAULT"/>
      </intent-filter>
    </activity>
    
  2. 呼び出し元アプリの署名を検証します。

    <ph type="x-smartling-placeholder">
    private fun verifyFingerprint(
            expectedPackage: String,
            expectedFingerprint: String,
            algorithm: String
    ): Boolean {
    
        callingActivity?.packageName?.let {
            if (expectedPackage == it) {
                val packageInfo =
                    packageManager.getPackageInfo(it, PackageManager.GET_SIGNATURES)
                val signatures = packageInfo.signatures
                val input = ByteArrayInputStream(signatures[0].toByteArray())
    
                val certificateFactory = CertificateFactory.getInstance("X509")
                val certificate =
                    certificateFactory.generateCertificate(input) as X509Certificate
                val md = MessageDigest.getInstance(algorithm)
                val publicKey = md.digest(certificate.encoded)
                val fingerprint = publicKey.joinToString(":") { "%02X".format(it) }
    
                return (expectedFingerprint == fingerprint)
            }
        }
        return false
    }
    
  3. インテント パラメータからクライアント ID を抽出し、クライアントが ID が想定値と一致している。

    private const val EXPECTED_CLIENT = "<client-id-from-actions-console>"
    private const val EXPECTED_PACKAGE = "<google-app-package-name>"
    private const val EXPECTED_FINGERPRINT = "<google-app-signature>"
    private const val ALGORITHM = "SHA-256"
    ...
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    
        val clientId = intent.getStringExtra("CLIENT_ID")
    
        if (clientId == EXPECTED_CLIENT &&
            verifyFingerprint(EXPECTED_PACKAGE, EXPECTED_FINGERPRINT, ALGORITHM)) {
    
            // ...authorize the user...
        }
    }
    
  4. 認証が成功したら、結果として得られた認証コードを返送する Google に送信されます。

    // Successful result
    val data = Intent().apply {
        putExtra("AUTHORIZATION_CODE", authCode)
    }
    setResult(Activity.RESULT_OK, data)
    finish()
    
  5. エラーが発生した場合は、代わりにエラーの結果を返します。

    // Error result
    val error = Intent().apply {
        putExtra("ERROR_TYPE", 1)
        putExtra("ERROR_CODE", 1)
        putExtra("ERROR_DESCRIPTION", "Invalid Request")
    }
    setResult(-2, error)
    finish()
    

起動インテントの内容

アプリを起動する Android のインテントには次のフィールドがあります。

  • CLIENT_IDString): アプリで登録された Google client_id
  • SCOPEString[]): リクエストされたスコープのリスト。
  • REDIRECT_URIString): リダイレクト URL。

レスポンス データの内容

Google アプリに返されるデータは、setResult() を呼び出してアプリで設定します。 このデータには次のものが含まれます。

  • AUTHORIZATION_CODEString): 認証コードの値。
  • resultCodeint): プロセスの成功または失敗を通知し、 次のいずれかの値を取ります。 <ph type="x-smartling-placeholder">
      </ph>
    • Activity.RESULT_OK: 成功を示します。認証コードが返されます。
    • Activity.RESULT_CANCELLED: ユーザーが プロセスですこの場合、Google アプリは 認可 URL を入力します。
    • -2: エラーが発生したことを示します。さまざまな種類のエラー 以下で説明します。
  • ERROR_TYPEint): エラーのタイプ。次のいずれかになります。 values: <ph type="x-smartling-placeholder">
      </ph>
    • 1: 復元可能なエラー: Google アプリは次を使用してアカウントのリンクを試みます 指定します。
    • 2: 回復不能なエラー: Google アプリがアカウントのリンクを中止します。
    • 3: リクエスト パラメータが無効であるか、不明です。
  • ERROR_CODEint): エラーの性質を表す整数。詳細 各エラーコードの意味を確認するには、 エラーコードの表をご覧ください。
  • ERROR_DESCRIPTIONString、省略可): 人が読める形式のステータス メッセージ エラーの説明です。

AUTHORIZATION_CODE の値は、次の場合に想定されます。 resultCode == Activity.RESULT_OK。それ以外の場合はすべて、 AUTHORIZATION_CODE は空にする必要があります。resultCode == -2 の場合、 ERROR_TYPE の値は入力されることが想定されています。

エラーコードの表

次の表は、各エラーコードと、それぞれが回復できるエラーであるか、回復できないエラーであるかを示しています。

エラーコード 意味 回復できる 回収不可
1 INVALID_REQUEST
2 NO_INTERNET_CONNECTION
3 OFFLINE_MODE_ACTIVE
4 CONNECTION_TIMEOUT
5 INTERNAL_ERROR
6 AUTHENTICATION_SERVICE_UNAVAILABLE
8 CLIENT_VERIFICATION_FAILED
9 INVALID_CLIENT
10 INVALID_APP_ID
11 INVALID_REQUEST
12 AUTHENTICATION_SERVICE_UNKNOWN_ERROR
13 AUTHENTICATION_DENIED_BY_USER
14 CANCELLED_BY_USER
15 FAILURE_OTHER
16 USER_AUTHENTICATION_FAILED

すべてのエラーコードについて、setResult を介してエラー結果を 適切なフォールバックがトリガーされていることを確認します。