今日は、Googleの開発者向けのAPIについてお話します。 データ転送後にユーザーにアプリケーションへの再ログインを強制しない方法、より正確にはAndroid Account Transfer APIの使用方法について説明します。
おそらく、私たちはそれぞれ新しいスマートフォンを購入し、古いスマートフォンからすべての重要な情報とアプリケーションを転送する必要がありました。 現在、このプロセスはTap&Goテクノロジーのおかげで非常に簡単になりました。 しかし、一つだけあります。 可能な限り再度ログインする必要があります。 しかし、これがフィットネストラッカーなどのアプリケーションで、一度ログインして忘れてしまった場合はどうでしょうか? パスワードを回復しますか? 再び頭痛。 あなたは言うことができます:「しかし、スマートロックがあります!」そして、あなたは正しいでしょう、しかし、我々はすべてのケースを考慮に入れなければなりません。 ユーザーがパスワードを保存するのを忘れた場合はどうなりますか? または彼はただの妄想であり、パスワードを保存していませんか? または、アプリケーションはSmart Lockを使用していませんか? 認証データを忘れる理由は常にあると思います。 しかし、現在は解決策があり、ユーザーの資格情報を転送する負担を軽減できます。 ここでのみ、それは万人向けではない はい、少なくとも1年後には効果的に稼ぎます。
これから3つの質問が続きます。
1. Account Transfer APIとは何ですか?
2.なぜ皆のためではないのですか?
3.少なくとも1年で効果的に機能するのはなぜですか。
必要な要件
前述したように、アカウント転送APIを使用すると、開発者はトークンやアカウント情報などの認証データを古い携帯電話から新しい携帯電話に転送できます。 そして、これには何が必要ですか?
そして、この技術を実装するために必要な最も悲しい部分に遭遇します。
動作させるには何が必要ですか?
1. 4.0.1(APIレベル14)以上のAndroidバージョンの古いデバイス。
そのような問題ではない、とあなたは言います、そして私はこれに同意しますが、さらに見てください。
2.データをコピーする新しいデバイスは、Android 8.0(APIレベル26)以上のOSを実行している必要があります。
これは、「少なくとも1年で効果的に機能するのはなぜですか」という質問に対する答えです。 はい、今年は多くのデバイスがOreoのAndroidアップデートを受け取りますが、必要なAPIレベルのOSが既に組み込まれた状態で販売されることはほとんどありません。 最も可能性が高いのは、在庫バージョンが棚に残り、最大のAndroidマシュマロが搭載されることです。 また、購入後は手動で更新する必要があります。 そして、これが私たちの機能にとって重要な瞬間です。 ユーザーが最初に自分のデータをデバイスに転送し、その後でしか更新しない可能性が非常に高くなります。
根拠がないように、2018年2月5日付のGoogle情報をお見せします。
3.両方のデバイスにGoogle Playバージョン11.2.0以降が必要です。 もちろん、Google Playなしでデバイスをサポートしていない限り、これは大きな問題にはなりません。 彼らは転送を整理できません。
4. 11.2.0以上のGoogle Playサービスを使用してAPKを構築する必要があります。 このバージョンのサービスを使用しない、またはサービスをまったく使用しない理由がある場合にのみ、問題になる可能性があります。
5. AccountManagerと統合された、既に実装されたAbstractAccountAuthenticatorが必要です 。 実装に関する「Habré」 に関する記事の素晴らしいサイクルがあります。
どのように機能しますか?
すべての要件が満たされていれば、電話機間で安全な有線接続またはBluetooth経由の暗号化が作成されます。 転送中にバックエンドのトークンの有効性を確認する場合は、デバイスの1つをインターネットに接続する必要があります。
次に、システムは、データのエクスポートを開始する準備ができていることを示すブロードキャストメッセージ( ACTION_START_ACCOUNT_EXPORTまたはACTION_ACCOUNT_EXPORT_DATA_AVAILABLE )を送信します。 つまり 受信者デバイスへの安全な接続を介してユーザーアカウントデータを生成して送信する必要があります。
その後、システムは別のブロードキャストメッセージ( ACTION_ACCOUNT_IMPORT_DATA_AVAILABLE )を受信デバイスに送信します。 ここでは、フォアグラウンドサービスを実行し、受信した情報を処理する必要もあります。
データ転送時に受信側デバイスのサービスを作成できない状況が発生した場合、システムはユーザーデータを一時ストレージに保存します。 データは、アプリケーションを最初に起動したときに受信されます。
実装
最後に、実装を開始することにします。
これがまだ行われていない場合、最初にplay-services-authを接続する必要があります。
dependencies { // For Account Transfer api, use SDK version 11.2.0 or higher compile 'com.google.android.gms:play-services-auth-base:<VERSION_NUMBER>' }
次に、マニフェストでBroadcastReceiverとServiceを宣言します。
<receiver android:name=".AccountTransferBroadcastReceiver" android:enabled="true" android:exported="true" > <intent-filter> <action android:name="com.google.android.gms.auth.START_ACCOUNT_EXPORT" /> </intent-filter> <intent-filter> <action android:name="com.google.android.gms.auth.ACCOUNT_IMPORT_DATA_AVAILABLE" /> </intent-filter> <intent-filter> <action android:name="com.google.android.gms.auth.ACCOUNT_EXPORT_DATA_AVAILABLE" /> </intent-filter> </receiver> <service android:name=".AuthenticatorService"> <intent-filter> <action android:name="android.accounts.AccountAuthenticator"/> </intent-filter> <meta-data android:name="android.accounts.AccountAuthenticator" android:resource="@xml/authenticator"/> </service>
上記のように、対応するブロードキャストメッセージを受信すると、サービスを開始する必要があります。
public class AccountTransferBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // Long running tasks, like calling Account Transfer API, shouldn't happen here. Start a // foreground service to perform long running tasks. Intent serviceIntent = AccountTransferService.getIntent(context, intent.getAction()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { context.startForegroundService(serviceIntent); } else { context.startService(serviceIntent); } } }
それに応じて、サービスの部分的な実装:
protected void onHandleIntent(Intent intent) { String action = intent.getAction(); if (action == null) { return; } switch (action) { case AccountTransfer.ACTION_ACCOUNT_IMPORT_DATA_AVAILABLE: importAccount(); return; case ACTION_START_ACCOUNT_EXPORT: case AccountTransfer.ACTION_ACCOUNT_EXPORT_DATA_AVAILABLE: exportAccount(); return; } } private void importAccount() { // Handle to client object AccountTransferClient client = AccountTransfer.getAccountTransferClient(this); // Make RetrieveData api call to get the transferred over data. Task<byte[]> transferTask = client.retrieveData(ACCOUNT_TYPE); try { byte[] transferBytes = Tasks.await(transferTask, TIMEOUT_API, TIME_UNIT); //import logic } catch (ExecutionException | InterruptedException | TimeoutException | JSONException e) { client.notifyCompletion( ACCOUNT_TYPE, AuthenticatorTransferCompletionStatus.COMPLETED_FAILURE); return; } client.notifyCompletion( ACCOUNT_TYPE, AuthenticatorTransferCompletionStatus.COMPLETED_SUCCESS); } private void exportAccount() { byte[] transferBytes = Foo.yourOwnMethodToGetAccountTransferBytes(); AccountTransferClient client = AccountTransfer.getAccountTransferClient(this); if (transferBytes == null) { // Notifying is important. client.notifyCompletion( ACCOUNT_TYPE, AuthenticatorTransferCompletionStatus.COMPLETED_SUCCESS); return; } // Send the data over to the other device. Task<Void> exportTask = client.sendData(ACCOUNT_TYPE, transferBytes); try { Tasks.await(exportTask, TIMEOUT_API, TIME_UNIT); } catch (ExecutionException | InterruptedException | TimeoutException e) { // Notifying is important. client.notifyCompletion( ACCOUNT_TYPE, AuthenticatorTransferCompletionStatus.COMPLETED_FAILURE); return; } }
より詳細な例はgooglesamplesリポジトリにあります 。
テストのために、セットアップウィザードコマンドを起動することをお勧めします。
$ adb shell am start -a android.intent.action.MAIN -n com.google.android.gms/.smartdevice.d2d.ui.TargetActivity
これですべてです。新しいデバイスに再インストールした後、アプリケーションを操作するときに頭痛や不要なアクションを忘れるのに十分です。 おそらく、これがまさにアプリケーションを使用し続けるか、削除して忘れるかをユーザーに明確にする重要なポイントになるでしょう。
要約すると、Googleはユーザーが再認証に費やす時間を最小限に抑えたいと考えており、そのための論理的なステップを作成しています。 そして、この方向でそれらをサポートすることは素晴らしいことです。 時間のかかる実装が必要ですが、価値があります。 結局のところ、悪魔は詳細にあります。
このトピックに関する興味深い情報:
ドキュメント
ビデオ紹介
実装例