バックアップと復元のテスト

このページでは、アプリでデータを適切に保存および復元するため、自動バックアップKey-Value バックアップを使用してバックアップと復元処理を手動でトリガーする方法について説明します。

バックアップの仕組み

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

次の図は、バックアップと復元時のデータの流れを示しています。バックアップ フレームワーク

バックアップ マネージャー サービスは、バックアップと復元処理を調整および開始する Android システム サービスです。このサービスには BackupManager API でアクセスできます。バックアップ処理では、このサービスはアプリにバックアップ データをクエリしてバックアップ トランスポートに渡します。データはバックアップ トランスポートによってアーカイブされます。復元処理では、バックアップ マネージャー サービスはバックアップ トランスポートからバックアップ データを取得し、デバイスにデータを復元します。

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

  • Google トランスポート(デフォルト)- ほとんどのデバイスでアクティブなバックアップ トランスポート。Google モバイル サービスの一部です。このドキュメントでは、ユーザーが Google トランスポートを使用していることを前提としています。このトランスポートは、自動バックアップ データをユーザーの Google ドライブ アカウントのプライベート フォルダに保存します。Key-Value バックアップ データは Android Backup Service に保存されます。
  • ローカル トランスポート - バックアップ データをデバイスにローカルで保存します。通常、このトランスポートは開発またはデバッグ目的で使用され、実際の環境では役に立ちません。

デバイスにバックアップ トランスポートがない場合、データをバックアップすることはできませんが、アプリに悪影響はありません。

注意: デバイスによってバックアップ トランスポートが異なる可能性があるため、Android はバックアップの使用時にデータのセキュリティを保証することができません。バックアップを使用してユーザー名やパスワードなどの機密データを保存する場合は、注意が必要です。

前提条件

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

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

デバイスまたはエミュレータを準備する

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

  • 自動バックアップの場合は、Android 6.0(API レベル 23)以上を搭載したデバイスまたはエミュレータを使用していることを確認します。
  • Key-Value バックアップの場合は、Android 2.2(API レベル 8)以上を搭載したデバイスまたはエミュレータを使用していることを確認します。
  • バックアップと復元がデバイスまたはエミュレータで有効になっており、Google アカウントが追加されていることを確認します。これを確認するには次の 2 つの方法があります。
    • デバイスのバージョンに応じて、[設定] > [バックアップと復元] に移動するか、画面上部の検索バーで「バックアップ」を検索します。
    • adb シェルから bmgr enabled を実行します。

    通常、物理デバイスでは初期設定ウィザードでバックアップと復元が有効になっています。エミュレータでは設定ウィザードが実行されないため、必ずデバイス設定でバックアップを有効にしてバックアップ アカウントを指定してください。

  • 次のコマンドを実行して、Google バックアップ トランスポートが使用可能かつアクティブになっていることを確認します。
    adb shell bmgr list transports
    

    次に、コンソールで以下の出力が表示されていることを確認します。

    android/com.android.internal.backup.LocalTransport
    * com.google.android.gms/.backup.BackupTransportService
    

Google Play を搭載していない物理デバイスと Google API のないエミュレータには、Google バックアップ トランスポートが含まれていない可能性があります。この記事では、Google バックアップ トランスポートを使用していることを前提としています。他のバックアップ トランスポートでもバックアップと復元をテストできますが、手順と出力が異なる場合があります。

バックアップをテストする

アプリのバックアップを開始するには、次のコマンドを実行します。

adb shell bmgr backupnow <PACKAGE>

backupnow コマンドは、Android 7.0 以降を搭載したデバイスとエミュレータで使用できます。パッケージのマニフェスト宣言に応じて、Key-Value バックアップまたは自動バックアップが実行されます。バックアップ手順の出力を調べるには、logcat を確認します。次に例を示します。

D/BackupManagerService: fullTransportBackup()
I/GmsBackupTransport: Attempt to do full backup on <PACKAGE>

---- or ----

V/BackupManagerService: Scheduling immediate backup pass
D/PerformBackupTask: starting key/value Backup of BackupRequest{pkg=<PACKAGE>}

デバイスで backupnow コマンドを使用できない場合は、自動バックアップまたは Key-Value バックアップのいずれかの手順(下記参照)を実施します。

自動バックアップの場合は、次の手順を実施します。

  1. 次のコマンドを実行します。
    adb shell bmgr backup @pm@ && adb shell bmgr run
    
  2. adb logcat で下記の出力をモニタリングして、前の手順のコマンドが終了するのを待ちます。
    I/BackupManagerService: K/V backup pass finished.
    
  3. フル バックアップを行うには、次のコマンドを実行します。
    adb shell bmgr fullbackup <PACKAGE>
    

注: fullbackup コマンドは、アプリが Key-Value バックアップを実装している場合でも、アプリにフル バックアップを強制します。システムはアプリのバックアップ設定を無視し、android:fullBackupOnly 属性が true に設定されているかのように動作します。

Key-Value バックアップの場合は、次の手順でバックアップをスケジュールして実行します。

  1. 前回のバックアップ以降アプリが BackupManager.dataChanged() を呼び出していない場合は、次のコマンドを実行して、テスト目的のバックアップ処理にアプリを含めることができます。
    adb shell bmgr backup <PACKAGE>
    
  2. 次に、下記のコマンドを実行して、バックアップをトリガーできます。
    adb shell bmgr run
    

bmgr backup は、バックアップ マネージャーのキューにアプリを追加します。 bmgr run はバックアップ処理を開始します。これにより、バックアップ マネージャーはそのキューにあるすべてのバックアップ リクエストを実行します。

Key-Value バックアップをテストする場合は、すべての設定変更でバックアップがスケジュールされていることを確認する必要があります。次のいずれかの方法でバックアップがスケジュールされていることを確認できます。

  • adb shell dumpsys backup を実行し、Pending key/value backup の下に表示されるコマンドの出力に、アプリがリストされていることを確認します。
  • バックアップのスケジュールを設定するときにメッセージをログに記録します。その後、adb logcat を実行し、コマンドの出力を確認して、バックアップがスケジュールされたことを確認します。

復元をテストする

手動で復元を開始するには、バックアップ トークン(取得方法については後述)を使用して次のコマンドを実行します。

adb shell bmgr restore <TOKEN> <PACKAGE>

バックアップ トークンを検索するには、adb shell dumpsys backup を実行します。トークンは、Ancestral: ラベルと Current: ラベルの後に続く 16 進文字列です。ancestral トークンは、デバイスの初期設定時(デバイス設定ウィザードを使用)にデバイスを復元するために使用されたバックアップ データセットを参照します。current トークンは、デバイスの現在のバックアップ データセット(デバイスから現在バックアップ データが送信されているデータセット)を参照します。

次に、logcat をチェックして復元手順の出力を確認します。次に例を示します。

V/BackupManagerService: beginRestoreSession: pkg=<PACKAGE> transport=null
V/RestoreSession: restorePackage pkg=<PACKAGE> token=368abb4465c5c683
...
I/BackupManagerService: Restore complete.

アプリの自動復元をテストするには、adb を使用するか、Google Play ストア アプリを使用して、アプリをアンインストールして再インストールします。

トラブルシューティング

このセクションでは、よくある問題のトラブルシューティングについて説明します。

トランスポートの容量を超過した

logcat に以下のメッセージが表示される場合があります。

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

--- or ---

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

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

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

logcat に次のメッセージが表示される場合があります。

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

これは、Key-Value バックアップ処理がまだデバイスで行われていないため、フル バックアップ処理が失敗したことを示します。bmgr run コマンドで Key-Value バックアップをトリガーしてから、もう一度試してください。

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

logcat に次のメッセージが表示される場合があります。

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

これは、アプリがバックアップを起動するのに 10 秒以上かかっていることを示します。ログ出力に示されているタイムスタンプの差分を確認してください。通常、このエラーはアプリが 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 サブクラスを使用してアプリを起動します。