バックアップと復元をテストする

このページでは、アプリのクラウド バックアップとデバイス間(D2D)転送プロセスをテストする方法について説明します。ユーザーが新しいデバイスでアプリを引き続き使用できるように、アプリの各メジャー リリースでこれらの両方をテストすることが重要です。バックアップと転送はどちらも似ていますが、Android 12(API レベル 31)以降では 2 つに重要な違いがあります。最も注目すべき点は、クラウド バックアップの 25 MB から転送のデータサイズの上限が 2 GB である点です。

このガイドでは、開発サイクル全体でクラウドのバックアップと復元、D2D 転送を効率的にテストする方法について説明します。

バックアップのテストの仕組み

このセクションでは、Android バックアップ フレームワークのさまざまな要素と、自動バックアップおよび Key-Value バックアップをサポートするアプリの操作方法について説明します。アプリ開発段階では、フレームワークの内部動作のほとんどが抽象化されるため、この情報を把握する必要はありません。ただし、テストフェーズでは、これらのコンセプトを理解することがより重要になります。

次の図は、クラウドでのバックアップと復元時のデータフローを示しています。テスト目的で、同じデバイスをクラウドのバックアップと復元に使用できます。

バックアップ フレームワークのデータフロー

次の図は、D2D 転送中のデータフローを示しています。

転送フレームワークのデータフロー

クラウドのバックアップおよび復元のテストとは異なり、D2D テストにはコピー元のデバイスとターゲット デバイスが必要です。

バックアップ マネージャー サービスは、バックアップと復元の処理をオーケストレートして開始する Android システム サービスです。このサービスには、Backup Manager API を介してアクセスできます。

バックアップ操作中、サービスはアプリにバックアップ データをクエリして、バックアップ トランスポートに渡します。その後、データがクラウドにアーカイブされます。復元処理の間、バックアップ マネージャー サービスはバックアップ トランスポートからバックアップ データを取得し、デバイスにデータを復元します。D2D 転送の場合、バックアップ マネージャー サービスはアプリにバックアップ データを照会し、新しいデバイスのバックアップ マネージャー サービスに直接渡してアプリに読み込みます。

バックアップ トランスポートは、アプリデータの保存と取得を担う Android コンポーネントです。Android 搭載デバイスには 0 個以上のバックアップ トランスポートを含めることができますが、アクティブとしてマークできるのは 1 つだけです。デバイス メーカーとサービス プロバイダによるカスタマイズにより、利用可能なバックアップ トランスポートはデバイスによって異なりますが、ほとんどの Google Play 対応デバイスには以下のトランスポートが付属しています。

  • GMS トランスポート: ほとんどのデバイスで有効なクラウド バックアップ トランスポートです。Google モバイル サービスの一部です。このトランスポートは、Android Backup Service にデータを保存します。
  • D2D トランスポート: D2D 移行でデバイス間でデータを直接転送するために使用します。

ツール

バックアップと復元のオペレーションをテストするには、次のツールについて理解する必要があります。

  • adb: デバイスまたはエミュレータでコマンドを実行します。
  • bmgr: さまざまなバックアップと復元のオペレーションを実行します。
  • logcat: バックアップと復元のオペレーションの出力を表示します。

クラウド バックアップをテストする

このセクションの手順に沿って、クラウドのバックアップと復元を単一のデバイスで実行できます。

クラウド バックアップ用にデバイスまたはエミュレータを準備する

次のチェックリストを使用して、バックアップ テスト用のデバイスまたはエミュレータを準備します。

  1. 自動バックアップの場合は、Android 6.0(API レベル 23)以降を搭載しているデバイスまたはエミュレータを使用していることを確認します。
  2. Key-Value バックアップの場合は、Android 2.2(API レベル 8)以降を搭載しているデバイスまたはエミュレータを使用していることを確認してください。
  3. クラウド バックアップをテストするには、インターネット接続が必要です。
  4. Google アカウントでデバイスにログインし、[設定] -> [Google] -> [バックアップ] でバックアップ アカウントとして設定します。

クラウド バックアップをテストするには、クラウド バックアップをトリガーしてから、アプリをアンインストールしてから再インストールします。この手順を繰り返す可能にするには、次のスクリプト test_cloud_backup.sh を使用します。このスクリプトは、アプリをバックアップし、APK をローカルにダウンロードしてアンインストールし、APK の再インストールを行います。

#!/bin/bash -eu
: "${1?"Usage: $0 package name"}"

# Initialize and create a backup
adb shell bmgr enable true
adb shell bmgr transport com.android.localtransport/.LocalTransport | grep -q "Selected transport" || (echo "Error: error selecting local transport"; exit 1)
adb shell settings put secure backup_local_transport_parameters 'is_encrypted=true'
adb shell bmgr backupnow "$1" | grep -F "Package $1 with result: Success" || (echo "Backup failed"; exit 1)

# Uninstall and reinstall the app to clear the data and trigger a restore
apk_path_list=$(adb shell pm path "$1")
OIFS=$IFS
IFS=$'\n'
apk_number=0
for apk_line in $apk_path_list
do
    (( ++apk_number ))
    apk_path=${apk_line:8:1000}
    adb pull "$apk_path" "myapk${apk_number}.apk"
done
IFS=$OIFS
adb shell pm uninstall --user 0 "$1"
apks=$(seq -f 'myapk%.f.apk' 1 $apk_number)
adb install-multiple -t --user 0 $apks

# Clean up
adb shell bmgr transport com.google.android.gms/.backup.BackupTransportService
rm $apks

echo "Done"

テスト手順

  1. アプリを開き、ログインして、すべての設定を変更します。
  2. スクリプトを実行し、パッケージ名(例: test_cloud_backup.sh com.example.myapp)を渡します。
  3. アプリをもう一度開き、すべてのデータが保持された状態で、正しく動作することを確認します。

ユーザーがログインする必要がないようにする必要があります。また、すべてのユーザーの設定、進行状況、アプリデータを以前と同様に維持する必要があります。テスト結果がこれらの条件を満たしていない場合は、重要なデータを除外せずにバックアップを正しく構成していること、バックアップから除外したキャッシュ データの再作成を処理していることを確認してください。テストイテレーションごとにステップ 1 ~ 3 を繰り返します。

D2D 転送をテストする

D2D 転送をテストする最も包括的な方法は、スマートフォンのコンテンツ全体を新しい初期状態にリセットしたデバイスに移行し、正しく動作するかどうかを検証することです。ただし、プロセスを複数回繰り返す必要がある場合は、不便で時間がかかることがあります。以下の手順では、デバイスの出荷時設定へのリセットを繰り返し実行せずに、1 台のデバイスで転送をシミュレートする方法について説明します。

D2D テストに向けてデバイスを準備する

単一のデバイスで D2D 転送をテストするには、次のように準備します。

  1. デバイスに Android 12(API レベル 31)以降が搭載されている必要があります。
  2. D2D の最新バージョンをテストするには、アプリで Android 12(API レベル 31)以降をターゲットに設定します。
  3. テストの繰り返しをサポートするために、次のスクリプト test_d2d.sh を作成します。
#!/bin/bash -eu
: "${1?"Usage: $0 package name"}"

# Initialize and create a backup
adb shell bmgr enable true
adb shell settings put secure backup_enable_d2d_test_mode 1
adb shell bmgr transport com.google.android.gms/.backup.migrate.service.D2dTransport
adb shell bmgr init com.google.android.gms/.backup.migrate.service.D2dTransport
adb shell bmgr list transports | grep -q -F "  * com.google.android.gms/.backup.migrate.service.D2dTransport" || (echo "Failed to select and initialize backup transport"; exit 1)
adb shell bmgr backupnow "$1" | grep -F "Package $1 with result: Success" || (echo "Backup failed"; exit 1)

# Uninstall and reinstall the app to clear the data and trigger a restore
apk_path_list=$(adb shell pm path "$1")
OIFS=$IFS
IFS=$'\n'
apk_number=0
for apk_line in $apk_path_list
do
    (( ++apk_number ))
    apk_path=${apk_line:8:1000}
    adb pull "$apk_path" "myapk${apk_number}.apk"
done
IFS=$OIFS
adb shell pm uninstall --user 0 "$1"
adb shell bmgr transport com.google.android.gms/.backup.BackupTransportService
apks=$(seq -f 'myapk%.f.apk' 1 $apk_number)
adb install-multiple -t --user 0 $apks

# Clean up
adb shell bmgr init com.google.android.gms/.backup.migrate.service.D2dTransport
adb shell settings put secure backup_enable_d2d_test_mode 0
adb shell bmgr transport com.google.android.gms/.backup.BackupTransportService
rm $apks

echo "Done"

テスト手順

  1. テストするアプリをデバイスにインストールします。
  2. アプリを開き、ログインして、アプリの設定を変更します。
  3. デバイスでスクリプトを実行し、パッケージ名(test_d2d.sh com.example.myapp など)を渡します。
  4. スクリプトが完了したら、デバイス上でアプリを開き、すべてのデータが保持された状態で、正しく動作することを検証します。

ユーザーがログインする必要がないようにする場合、ユーザーのすべての設定、進行状況、アプリデータは、スクリプトを実行する前と同じように表示される必要があります。テスト結果がこれらの条件を満たしていない場合は、重要なデータを除外せずに転送が正しく構成されていることと、転送から除外したキャッシュ データの再作成を処理していることを確認してください。テスト反復処理ごとにステップ 2 ~ 4 を繰り返します。

バックアップと復元のトラブルシューティング

このセクションでは、一般的な問題のトラブルシューティングについて説明します。

トランスポートの割り当ての超過

logcat に次のメッセージは、アプリがトランスポートの割り当てを超過したことを示します。

I/PFTBT: Transport rejected backup of <PACKAGE>, skipping

--- or ---

I/PFTBT: Transport quota exceeded for package: <PACKAGE>

バックアップ データの量を減らして、もう一度お試しください。 たとえば、アプリのキャッシュ ディレクトリにのみデータをキャッシュに保存していることを確認します。このキャッシュ ディレクトリはバックアップに含まれません。

フル バックアップができない

logcat に次のメッセージは、デバイスで Key-Value バックアップ オペレーションがまだ発生していないためにフル バックアップ オペレーションが失敗したことを示しています。

I/BackupManagerService: Full backup not currently possible -- key/value backup
not yet run?

コマンド bmgr run で Key-Value バックアップをトリガーしてから、もう一度お試しください。

エージェント待機中のタイムアウト

Logcat に次のメッセージは、バックアップ用のアプリの起動に 10 秒以上かかっていることを示しています。

12-05 18:59:02.033  1910  2251 D BackupManagerService:
    awaiting agent for ApplicationInfo{5c7cde0 com.your.app.package}
12-05 18:59:12.117  1910  2251 W BackupManagerService:
    Timeout waiting for agent ApplicationInfo{5c7cde0 com.your.app.package}
12-05 18:59:12.117  1910  2251 W BackupManagerService:
    Can't find backup agent for com.your.app.package

ログ出力のタイムスタンプの違いに注目してください。このエラーは通常、アプリが ProGuard を使用せずに Multidex 構成を使用している場合に発生します。

バックアップ アカウントが初期化されていません

Logcat に次のメッセージは、バックアップ データセットが初期化されていないためにバックアップが停止したことを示しています。

01-31 14:32:45.698 17280 17292 I Backup: [GmsBackupTransport] Try to backup for
an uninitialized backup account.
01-31 14:32:45.699  1043 18255 W PFTBT: Transport failed; aborting backup: -1001
01-31 14:32:45.699  1043 18255 I PFTBT: Full backup completed with status: -1000

adb shell bmgr run コマンドでバックアップ マネージャーを実行してから、バックアップを再度実行してみてください。

アプリのメソッドが呼び出されていない

自動バックアップは Application の基本クラスでアプリを起動するため、アプリの設定メソッドが呼び出されない場合があります。自動バックアップもアプリのアクティビティは起動しないため、アプリがアクティビティ内でセットアップすると、エラーが発生することがあります。詳細については、BackupAgent を実装するをご覧ください。

一方、Key-Value バックアップでは、アプリ マニフェスト ファイルで宣言した Application サブクラスを使用してアプリが起動します。

バックアップするデータがありません

次のような Logcat のメッセージは、アプリにバックアップするデータがないことを示します。

I Backup  : [FullBackupSession] Package com.your.app.package doesn't have any backup data.

--- or ---

I Backup  : [D2dTransport] Package com.your.app.package doesn't have any backup data.

独自の BackupAgent を実装している場合は、バックアップにデータまたはファイルが追加されていない可能性があります。