Google は、黒人コミュニティに対する人種平等の促進に取り組んでいます。取り組みを見る

Account Transfer API

タップ&ゴーを使用して、既存の Android デバイスから新しい Android デバイスに Google アカウントとデータをコピーできます。Account Transfer API を使用すると、AbstractAccountAuthenticator によって実装され AccountManager で統合されたカスタム アカウントの認証情報もユーザーがコピーできるようになります。システムは、新しいデバイスで実行されている [タップ&ゴー] 設定ウィザードから Account Transfer API を呼び出します。また、Account Transfer API を呼び出し、ケーブルを使用して Android スマートフォンから Pixel にデータを転送することもできます。

タップ&ゴーの開始画面。 タップ&ゴーのデータソース選択画面。

図 1. Account Transfer API は、新しいデバイスで実行されるタップ&ゴー設定ウィザードから呼び出されます。

カスタム アカウントの移行サポートを追加するには、Account Transfer API をアプリに統合します。Google Play 開発者サービスにより、既存のデバイス(ソースデバイス)と新しいデバイス(ターゲット デバイス)の間に双方向の暗号化チャネルを確立し、アカウント データを転送できるようになります(図 2 を参照)。転送を完了するうえで、暗号化チャネルは、サードパーティのサーバーへの接続には依存しません。

Account Transfer API をアプリに統合するときは、次の要件を考慮してください。

  • ソースデバイスで Android 4.0.1(API レベル 14)以上を実行している必要があります。
  • ターゲット デバイスで Android 8.0(API レベル 26)以上を実行している必要があります。
  • ソースデバイスとターゲット デバイスの両方で、Google Play 開発者サービス バージョン 11.2.0 以降を実行している必要があります。
  • APK は、Google Play 開発者サービス SDK バージョン 11.2.0 以降を使用して作成する必要があります。

ソースデバイスからターゲット デバイスへのアカウント転送のイラスト。

図 2. 転送は、Google Play 開発者サービスがソースデバイスとターゲット デバイスの間で確立する暗号化チャネルを介して行われます。

Account Transfer API をプロジェクトに追加する

Account Transfer API をプロジェクトで使用するには、まず Google Play 開発者サービス SDK でプロジェクトを設定する必要があります。Google Play 開発者サービス SDK のセットアップに関する詳細な手順については、Google Play 開発者サービスのセットアップをご覧ください。

Google Account Transfer API をアプリに選択的にコンパイルする場合は、アプリケーション モジュール ディレクトリ内の build.gradle ファイルの dependencies ブロックに次のビルドルールを追加します。

apply plugin: 'com.android.application'
        ...

        dependencies {
            // VERSION_NUMBER must be equal to or higher than 11.2.0.
            compile 'com.google.android.gms:play-services-auth:<VERSION_NUMBER>'
        }
    

カスタム アカウント転送のサポートを追加するには、アプリのマニフェストで認証システム サービスの START_ACCOUNT_EXPORT ブロードキャスト レシーバを宣言する必要があります。

<receiver android:name=".MyBroadcastReceiver"  android:exported="true">
        <intent-filter>
            <action android:name="com.google.android.gms.auth.START_ACCOUNT_EXPORT"/>
            ...
        </intent-filter>
    </receiver>
    

OEM システム イメージにアプリがインストールされておらず、今後 OEM システム イメージにアプリを配置する予定がない場合は、上記で説明したとおり、ソースデバイスで ACTION_START_ACCOUNT_EXPORT ブロードキャストをリッスンするように登録して、アカウント データをエクスポートします。

OEM システム イメージにアプリをインストールする場合は、次のブロードキャストにも登録する必要があります。

アカウント データを移行する

ユーザーが既存のデバイスからコンテンツを復元することを選択すると、ACTION_START_ACCOUNT_EXPORT ブロードキャストがソースデバイス上の適切なアカウントに関連付けられたパッケージに送信されます。

アカウント データを送信する

アカウント データを送信するには、ソースデバイスで認証システム サービスを開始し、サービスが ACTION_START_ACCOUNT_EXPORT ブロードキャストを受信した後に sendData() を呼び出します。AccountTransferClient オブジェクトへの参照を取得するには、getAccountTransferClient(Context) または getAccountTransferClient(Activity) を呼び出します。 次のコード スニペットは、ソースデバイスからデータを送信する方法を示しています。

Kotlin

    val client: AccountTransferClient = AccountTransfer.getAccountTransferClient(this)
    val exportTask: Task<Void> = client.sendData(ACCOUNT_TYPE, transferBytes)
    try {
        // Wait for the task to either complete or provide the callback.
        Tasks.await(exportTask, TIMEOUT_API, TIME_UNIT)
    } catch (e: Exception) {
        when(e) {
            is ExecutionException, is InterruptedException, is TimeoutException -> {
                client.notifyCompletion(ACCOUNT_TYPE,
                        AuthenticatorTransferCompletionStatus.COMPLETED_FAILURE)
                return
            }
            else -> throw e
        }
    }
    

Java

    AccountTransferClient client = AccountTransfer.getAccountTransferClient(this);
    Task<Void> exportTask = client.sendData(ACCOUNT_TYPE, transferBytes);
    try {
      // Wait for the task to either complete or provide the callback.
      Tasks.await(exportTask, TIMEOUT_API, TIME_UNIT);
    } catch (ExecutionException | InterruptedException | TimeoutException e) {
      client.notifyCompletion(ACCOUNT_TYPE,AuthenticatorTransferCompletionStatus.COMPLETED_FAILURE);
      return;
    }
    

ターゲット デバイスの設定ウィザードでアカウント データを受信します。

アカウント データを受信する

同じ認証システム サービスがこのデバイスにインストールされており、ACTION_ACCOUNT_IMPORT_DATA_AVAILABLE ブロードキャストをリッスンすることでインタレストを登録している場合、ターゲット デバイスは対応するパッケージに ACTION_ACCOUNT_IMPORT_DATA_AVAILABLE ブロードキャストを送信します。

ACTION_ACCOUNT_IMPORT_DATA_AVAILABLE ブロードキャストを受信したら、サービスを開始し、ターゲット デバイスで retrieveData() を呼び出して、ソースデバイスから送信されたデータを取得します。次のコード スニペットは、ターゲット デバイスでデータを取得する方法を示しています。

Kotlin

    val client: AccountTransferClient = AccountTransfer.getAccountTransferClient(this)
    val transportTask: Task<Void> = client.retrieveData(ACCOUNT_TYPE)
    try {
        val transferBytes: ByteArray = Tasks.await(transferTask, TIMEOUT_API, TIME_UNIT)
        // Add the transferred account(s) to AccountManager to register it with the framework.
    } catch (e: Exception) {
        when(e) {
            is ExecutionException, is InterruptedException, is TimeoutException -> {
                client.notifyCompletion(ACCOUNT_TYPE,
                        AuthenticatorTransferCompletionStatus.COMPLETED_FAILURE)
                return
            }
            else -> throw e
        }
     }
    client.notifyCompletion(ACCOUNT_TYPE, AuthenticatorTransferCompletionStatus.COMPLETED_SUCCESS)

    

Java

    AccountTransferClient client = AccountTransfer.getAccountTransferClient(this);
    Task<Void> transferTask = client.retrieveData(ACCOUNT_TYPE);
    try {
      byte[] transferBytes = Tasks.await(transferTask, TIMEOUT_API, TIME_UNIT);
      // Add the transferred account(s) to AccountManager to register it with the framework.
    } catch (ExecutionException | InterruptedException | TimeoutException e) {
      client.notifyCompletion(ACCOUNT_TYPE, AuthenticatorTransferCompletionStatus.COMPLETED_FAILURE);
      return;
    }
    client.notifyCompletion(ACCOUNT_TYPE, AuthenticatorTransferCompletionStatus.COMPLETED_SUCCESS);

    

転送を完了する

ターゲット デバイスの認証システム サービスは、必要に応じて、sendData() を呼び出してデータをソースデバイスに戻すこともできます。

ソースデバイスでデータを受信するには、認証システム サービスが ACTION_ACCOUNT_EXPORT_DATA_AVAILABLE ブロードキャストをリッスンする必要があります。同様に、ソースデバイスの認証システム サービスは、これ以降もターゲット デバイスにメッセージを送信できます。

転送が完了すると、認証システム サービスは適切な完了ステータスで notifyCompletion() を呼び出す必要があります。

セキュリティをさらに強化する必要がある場合は、ソースデバイスまたはターゲット デバイスのいずれかにユーザー向けの確認用画像を導入できます。まず、getDeviceMetaData() を呼び出して結果を調べ、確認用画像を表示できるかどうかを確認する必要があります。ターゲット デバイスの認証システム サービスが確認用画像をサポートしている場合は、showUserChallenge() を呼び出して確認用画像を表示することができます。

転送時に必要な認証システム サービスがターゲット デバイスにインストールされていない場合、転送されたデータは一時的なローカル ストレージに保存されます。アプリを最初にインストールして開くときに、retrieveData() を呼び出して、一時的なローカル ストレージに利用可能なデータがあるかどうかを確認できます。利用可能なデータがある場合、Account Transfer API はデータを返します。データがない場合は、呼び出しは失敗します。一時的なローカル ストレージにデータがない場合、それ以上データを取得しようとしても失敗する可能性があります。失敗する可能性があるため、notifyCompletion() を呼び出さないでください。

転送されたデータを一時的なローカル ストレージに保存するターゲット デバイスのイラスト。

図 3. 必要な認証システム サービスがターゲット デバイスにインストールされていない場合、転送されたデータは一時的なローカル ストレージに保存されます。

アカウントの移行をテストする

設定ウィザードは、新しいデバイスのセットアップ時に実行されます。セットアップとアカウントの移行をテストするために定期的にデバイスを工場出荷時の状態にリセットすることは、面倒で時間のかかる作業です。設定ウィザード フローの一部を実行して、デバイス間でユーザーのアカウントを移行するテストを行うこともできます。

テストを開始する前に、ソースデバイスに少なくとも 1 つのカスタム アカウントを作成してください。また、ターゲット デバイスがカスタム アカウントにログインしていないことも確認します。設定ウィザードの実行時にターゲット デバイスがカスタム アカウントにすでにログインしている場合、AccountManager.addAccountExplicitly() メソッドが呼び出されると、同じアカウントを追加しようとしても失敗します。

テストでは、Android 8.0(API レベル 26)以降を搭載するデバイスをターゲット デバイスとして使用する必要があります。

Android 4.0.1(API レベル 14)以降、Google Play 開発者サービス バージョン 11.2.0 以降を搭載するデバイスをソースデバイスとして使用できます。テスト用の APK を作成するには、Google Play 開発者サービス SDK バージョン 11.2.0 以降が必要です。

設定ウィザードのフローをテストするには、ターゲット デバイスで次のコマンドを実行します。

$ adb shell am start -a android.intent.action.MAIN -n com.google.android.gms/.smartdevice.d2d.ui.TargetActivity
    

このコマンドにより、アクティビティが起動し、設定ウィザードが表示されて、テストデバイスを別のデバイスとペアリングする準備が整います。デバイスの接続が確立したら、アカウントの移行プロセスを開始できます。