バックアップ対象は、プログラマが自由に設定することが可能ですが、大まかに「ファイル」「共有環境設定」「何でも」という分類になります。ファイルだけ、あるいは共有環境設定だけのバックアップ/レストアなら非常に簡単です。データベースもファイルとしてバックアップしてしまうなら、簡単に済みます。「ファイル」「共有環境設定」で、それぞれデータを保持するようなケースだと、少し複雑になります。
今回のサンプルアプリでは、説明上機能的に簡単にしたので、「ファイル」を2通りの方法でバックアップ/レストアしています。1つは「FileBackupHelper」クラスを用いた簡単な方法、もう1つは「Helper」クラスを用いない、複雑だけど柔軟な方法です。
アプリをバックアップするには、以下よりグーグルが提供する開発者向けサービスへ登録する必要があります。
ここでアプリのパッケージ名を入力すると、以下のような「Android Backup Service Key」が発行されます。
ここに記載されている<meta-data>タグを以下のように「AndroidManifest.xml」に追加します。
<meta-data android:name="com.google.android.backup.api_key" android:value="AEdPqrEAAAAIbZCy_LgG1Y-fX57dd-sVMCpwOgnmaPAtctSnsQ" />
上記キーは、今回のサンプルでしか使用できないので、自身で作成したアプリには必ず自身のパッケージ名で登録したキーを入力してください。
AndroidManifest.xmlの<application>タグに、バックアップ関連の属性を追加します。
<application android:allowBackup="true" android:backupAgent="DataBackupAgent"
重要なのは上記2つです。「android:allowBackup」は、これがtrueになっていなければバックアップが行われません。「android:backupAgent」は、バックアップの実装が行われているBackupAgentを継承したクラスを指定します。
今回のサンプルアプリは、2種類のバックアップエージェントを実装してあります。「DataBackupAgent」クラスではなく「FileBackupAgent」クラスの動作を確認したい場合は、android:backupAgentの中を「FileBackupAgent」に書き換えて実行してください。その際、バックアップデータは「bmgr」コマンドで「wipe」するようにしてください。
バックアップ関連のその他の設定項目は、開発者が知っておきたいAndroid 2.2の新機能12連発【3】クラウド向けデータバックアップ用APIを参照してください。
「BackupAgentHelper」クラスを継承するバックアップエージェントの実装は、とても簡単です。以下のコードで説明します。
public class FileBackupAgent extends BackupAgentHelper { static final String FILENAME = "data.txt"; // 【1】 static final String FILES_BACKUP_KEY = "files"; // 【2】 static final Object LOCK = new Object(); // 【3】 static final String TAG = "FileBakupAgent"; @Override public void onCreate() { FileBackupHelper helper = new FileBackupHelper(this, FILENAME); addHelper(FILES_BACKUP_KEY, helper); // 【4】 } @Override public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState) throws IOException { Log.d(TAG, "Backup files..."); synchronized (LOCK) { // 【5】 super.onBackup(oldState, data, newState); } } @Override public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState) throws IOException { Log.d(TAG, "Restore files..."); synchronized (LOCK) { super.onRestore(data, appVersionCode, newState); } MainActivity.sendBroadcast(this); } }
【1】では、ファイル名を保持しています。ファイルはContext#getFilesDir()で取得するファイル用ディレクトリにあることが前提になるため、データベースファイルなどをバックアップする際には工夫が必要になります。
【2】では、バックアップヘルパーに関連付けるキーを保持しています。このキーを用いてレストア時にデータを個別に取り出すことも可能です。
【3】は、ファイル入出力を同期するロックオブジェクトです。バックアップ、レストア、アプリによるファイルアクセスはすべて非同期で行われるため、【5】のようにバックアップやレストアを排他しなければなりません。
【4】では、対象ファイルを登録したヘルパーをキーに関連付けて追加します。
基本的には、これだけでバックアップとレストアは自動的に行われます。ファイルの場合は同期処理が必要なので、onBackup()やonRestore()をオーバーライドしていますが、これがSharedPreferencesの場合は、SharedPreferences自体がスレッドセーフなので、バックアップエージェントはonCreate()だけで済んでしまいます。
Copyright © ITmedia, Inc. All Rights Reserved.