- 導入:端末移行で設定が消えると、だいたい炎上する
- まず整理:android:backupAgentで何ができる?
- 設計:何をバックアップ対象にするか
- 前提:Manifest設定
- サンプル実装:BackupAgentHelperでSharedPreferencesをバックアップ
- サンプル実装:ファイルをバックアップする
- 自動バックアップとの関係:fullBackupContent / dataExtractionRules
- DataStoreをバックアップしたい場合の考え方
- 開発中の動作確認:adbでバックアップ/リストアを回す
- よくあるハマりポイント
- デバッグ/確認チェックリスト
- よくある質問(Q&A)
- まとめ:独自バックアップは「対象の絞り込み」がすべて
導入:端末移行で設定が消えると、だいたい炎上する
アプリの設定やログイン状態、ちょっとしたフラグ。
端末移行・再インストール後にこれが消えると、ユーザー体験が一気に悪化します。
「バックアップされてる前提で設計してたのに…」
「復元されると思ったら全然されてない…」
Androidにはバックアップの仕組みがいくつかありますが、今回は android:backupAgent を使って独自バックアップを実装する話です。
さらに、開発中に「本当に動いてる?」を確認するために、adbでバックアップ/リストアを叩く手順も載せます。
先に結論(3行)です。
- backupAgentは「バックアップ対象を明示して管理したい」時に効く
- BackupAgentHelperを使うとSharedPreferences/ファイルを最短でバックアップできる
- 動作確認はadbで「バックアップ → 消す → リストア」のループが最速
まず整理:android:backupAgentで何ができる?
android:backupAgent は、アプリのバックアップ/リストア時に呼ばれるエントリポイントです。
標準の自動バックアップに任せるのではなく、アプリ側で
- 何をバックアップするか
- どのキーで保存するか
- 復元時にどう扱うか
を明示的にコントロールできます。
ただし、バックアップはOS・端末・ユーザー設定に左右されます。
「必ずバックアップされる」前提で設計するのは危険です。
設計:何をバックアップ対象にするか
ここが一番大事です。バックアップは便利ですが、全部入れると事故ります。
バックアップ候補(よくある)
- ユーザーの設定値(ON/OFF、テーマ、言語など)
- アプリ内の軽量な状態(チュートリアル既読など)
- ログイン状態に紐づく「再ログインを助ける」情報(※扱い注意)
基本的に入れない方がいいもの
- 巨大データ(キャッシュ、画像、ログの塊)
- 再取得可能なデータ(サーバから復元できるもの)
- 端末固有の情報に依存するもの
バックアップ設計のコツは、「復元されたら嬉しいが、復元されなくても壊れない」に寄せることです。
前提:Manifest設定
まず Manifest でバックアップを有効化し、backupAgent を指定します。
<application
android:allowBackup="true"
android:backupAgent=".backup.MyBackupAgent"
android:fullBackupContent="@xml/backup_rules"
android:restoreAnyVersion="false">
<!-- 省略 -->
</application>
ここでのポイント:
- allowBackup が false だと当然動きません
- backupAgent で自前のエージェントを指定
- fullBackupContent は自動バックアップの対象制御(後述)
サンプル実装:BackupAgentHelperでSharedPreferencesをバックアップ
まず最短で動く構成です。
バックアップ対象:SharedPreferences
例として、”settings_prefs” という SharedPreferences をバックアップします。
package com.example.app.backup
import android.app.backup.BackupAgentHelper
import android.app.backup.SharedPreferencesBackupHelper
class MyBackupAgent : BackupAgentHelper() {
override fun onCreate() {
// どのデータをバックアップするかを登録する
val prefsHelper = SharedPreferencesBackupHelper(
this,
"settings_prefs" // バックアップしたいSharedPreferences名
)
// "prefs" はバックアップキー(識別子)
addHelper("prefs", prefsHelper)
}
}
これだけで、SharedPreferencesの中身がバックアップ対象になります。
サンプル実装:ファイルをバックアップする
SharedPreferencesだけでなく、内部ファイルも対象にできます。
import android.app.backup.BackupAgentHelper
import android.app.backup.FileBackupHelper
class MyBackupAgent : BackupAgentHelper() {
override fun onCreate() {
val prefsHelper = SharedPreferencesBackupHelper(this, "settings_prefs")
addHelper("prefs", prefsHelper)
// files/ 配下の特定ファイルをバックアップ
val filesHelper = FileBackupHelper(this, "user_cache.json")
addHelper("files", filesHelper)
}
}
ファイルを入れる時は「復元後に古い/不整合が起きないか」を必ず確認してください。
特にバージョンアップでフォーマットが変わると事故ります。
自動バックアップとの関係:fullBackupContent / dataExtractionRules
バックアップ周りは複数の仕組みが混在します。
- backupAgent(Key/ValueやHelperでのバックアップ)
- 自動バックアップ(フルバックアップ)
「何が対象になるか」を曖昧にすると、想定外のデータが入ったり、逆に必要なものが入らなかったりします。
実務では、バックアップ対象を明示して管理するのが安全です。
DataStoreをバックアップしたい場合の考え方
DataStoreは内部的にはファイルです。
なので「DataStoreをバックアップする」=「DataStoreファイルをバックアップする」になります。
ただ、DataStoreは移行や破損回避のために内部構造が変わることもあります。
運用としては次のどちらかに寄せると安全です。
- バックアップ対象は「アプリの設定」だけに限定する(DataStore全体を丸ごとにしない)
- 復元後に読み込み失敗しても初期値で立ち上がる設計にする
開発中の動作確認:adbでバックアップ/リストアを回す
ここが実務で一番ありがたい部分です。
「バックアップは端末任せでいつ発動するか分からない」ので、検証がしづらい。
だから adb で叩いて確認します。
前提
- USBデバッグ有効
- 対象端末が adb で見えている
1) バックアップを実行する(bmgr)
バックアップマネージャの操作は bmgr を使います。
adb shell bmgr backupnow <あなたのパッケージ名>例:
adb shell bmgr backupnow com.example.app2) バックアップ状態を確認する
adb shell bmgr list transports
adb shell bmgr status端末や環境によってバックアップトランスポートが変わるので、ここで状況を把握します。
3) アプリデータを消す(復元テスト用)
本当に復元できているかを見るには、いったんアプリデータを消して復元します。
adb shell pm clear com.example.app4) リストアを実行する
adb shell bmgr restore <あなたのパッケージ名>例:
adb shell bmgr restore com.example.appこの後アプリを起動して、SharedPreferencesの値が戻っているか確認します。
よくあるハマりポイント
① allowBackup が false
基本中の基本ですが、これで詰まる人がいます。
「セキュリティのためにfalseにしていた」のを忘れがちです。
② バックアップ対象のPrefs名が違う
SharedPreferencesBackupHelper に渡す名前は、実際に保存している prefs 名と一致している必要があります。
③ 復元後にアプリが起動しなくなる
復元で古いデータが入った結果、データフォーマットが合わず例外が出るケースです。
バックアップ対象は最小限にして、復元後に壊れても初期値で立ち上がる設計が強いです。
④ 端末や設定でバックアップが無効
バックアップはユーザー設定や端末制限の影響を受けます。
「必ず復元される」前提で設計すると破綻します。
デバッグ/確認チェックリスト
- Manifestで allowBackup と backupAgent が正しく設定されている
- バックアップ対象を最小限にしている
- SharedPreferences名・ファイル名が一致している
- adbで backupnow → pm clear → restore の順で確認した
- 復元データが壊れても初期値で起動できる
よくある質問(Q&A)
Q. login token もバックアップしていい?
推奨しません。セキュリティ上の理由だけでなく、端末が変わると無効になる設計も多いです。
「復元されたら嬉しい」より「復元されなくても困らない」に寄せた方が運用が安定します。
Q. SharedPreferencesを全部バックアップしていい?
できますが、やりすぎると復元後の整合性が崩れます。
「必要最小限のキーだけ」に寄せる方が安全です。
Q. DataStoreはどう扱えばいい?
DataStoreはファイルなのでバックアップは可能ですが、丸ごと復元はリスクもあります。
設定だけを抜き出すか、復元失敗しても初期値で復旧できる作りが強いです。
まとめ:独自バックアップは「対象の絞り込み」がすべて
- backupAgentでバックアップ対象を明示できる
- BackupAgentHelperで最短実装ができる
- adbで backupnow → clear → restore のループが最速
迷ったら:バックアップ対象を減らす。
増やすのは後からでもできますが、増やしすぎの事故は戻すのが大変です。