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

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

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

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

このセクションでは、Android バックアップ フレームワークのさまざまな要素と、それらが自動バックアップと Key-Value バックアップをサポートするアプリとどのようにやり取りするかを説明します。アプリ開発段階では、フレームワークの内部作業のほとんどが抽象化されているため、このような情報を知る必要はありません。ただし、テスト段階では、こうした概念を理解することがより重要になります。

次の図は、クラウドのバックアップと復元中にデータがどのように流れるかを示しています。テスト目的では、クラウドのバックアップと復元に同じデバイスを使用できます。

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

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

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

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

バックアップ マネージャー サービスは、バックアップと復元処理を調整および開始する Android システム サービスです。このサービスには、Backup Manager API を使用してアクセスできます。

バックアップ処理中、このサービスはアプリにバックアップ データをクエリしてバックアップ トランスポートに渡します。データはバックアップ トランスポートによってクラウドにアーカイブされます。復元処理中、Backup Manager Service はバックアップ トランスポートからバックアップ データを取得し、デバイスにデータを復元します。D2D 転送の場合、Backup Manager サービスはアプリにバックアップ データを照会し、新しいデバイスの Backup Manager サービスに直接渡します。これにより、データがアプリに読み込まれます。

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

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

ツール

バックアップと復元処理をテストするには、以下のツールに関する知識が少々必要です。

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

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

このセクションの手順に沿って、単一のデバイスを使用して Cloud のバックアップと復元を行うことができます。

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

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

  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 テスト用にデバイスを準備する

1 台のデバイスで 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 を実装している場合は、バックアップにデータやファイルを追加していない可能性があります。