Posted at

allowBackupの設定は適切ですか?

More than 3 years have passed since last update.

AndroidStudioで新しいプロジェクトを作成した時、AndroidManifestにデフォルトで記載されるあの記述 android:allowBackup="true" この設定実は危険なんです。

皆さんのアプリでは適切に設定されていますか?

<application

android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
...


Android Mからどうやら問題が発生しそう

allowBackupの設定自体はAndroid 2.2の時から存在していましたが、バックアップの方法が明示的には示されていませんでした。

しかし、Android MからはAuto Backup for Appsと機能が導入され、自動的にバックアップがGoogleDriveにとられるようになりました。

Auto Backup for Appsについてによると


GCMのregistration idとかは端末ごとに割り当てるものなので、バックアップを取られるとプッシュ通知が送られてこなくなる

端末に依存したファイルがある場合バックアップの対象から外すか、ファイルに書き込まない設計にする


プッシュ通知が届かないと、サービスによっては大きなダメージを受けてしまいますね。

バックアップや復元はどんな状態で起きるのでしょうか?


自動バックアップの発動条件


  • 端末がアイドル状態

  • 端末が充電状態

  • 端末がwifiに接続されていること

  • 以前のバックアップから24時間以上経過していること


どのユーザーに影響するのか?


  • Android M以上

  • 設定 -> バックアップとリセット -> データのバックアップがONになっている

  • 機種変更もしくは初期化後、バックアップから復元を選択したユーザー

最近端末を初期化する機会があったので試してみましたが、私のアプリ採点簿trueを指定していたので、実際にデータがすべて復元されました。

※プッシュ通知が届くかどうかはまだ未検証です。


回避策はあるのか?

一番簡単なのはandroid:allowBackup="false"を指定することです。

しかし、アプリによっては機種変更時のデータ引き継ぎを簡単にできるこの設定をそう簡単に捨てるのは嫌ですよね。

Googleのサンプルによると、バックアップの設定を個別に設定できそうでした。

https://github.com/googlesamples/android-AutoBackupForApps/blob/master/Application/src/main/res/xml/backup.xml#L24

<exclude domain="sharedpref" path="gcm"/>

と、バックアップから除外出来る設定がありました。

もし、バックアップを有効にするのであればここの設定を見直したほうが良いです。


バックアップ設定に使えるタグ

<full-backup-content>

<指定したファイルが除外される domain=["file" | "database" | "sharedpref" | "external" | "root"]
path="string" />
<exclude domain=["file" | "database" | "sharedpref" | "external" | "root"]
path="string" />
</full-backup-content>


  • include:それ以外のファイルはバックアップされなくなる

  • exclude:指定したファイルが除外される

  • file:getFilesDir()で取得できるファイルディレクトリ

  • database:アプリのデータベース

  • sharedpref:アプリのshared_prefs

  • external:getExternalFilesDir() で取得出来るディレクトリ

  • root:getApplicationInfo().dataDir()で取得出来るアプリのデータディレクトリ


確認方法

アプリをビルドしたら、実際に除外設定が出来ているか確認します。

都合上、私のアプリのパッケージ名com.bowyer.KyudoScoreBookSecondを指定しています。

コマンドにはご自身のパッケージ名を指定して下さい。


設定ファイルのパースをログ出力するためのフラグを立てる

$ adb shell setprop log.tag.BackupXmlParserLogging VERBOSE


自分でバックアップを発生させるには、次のコマンドを使ってBackup Managerを初期化する

$ adb shell bmgr run


初期化が完了したら、バックアップを実行

$ adb shell bmgr fullbackup com.bowyer.KyudoScoreBookSecond


バックアップが取得できたらアプリのデータを消して次のコマンドを実行し、復元の検証

$ adb shell bmgr restore com.bowyer.KyudoScoreBookSecond

私のアプリはandroid:allowBackup="true"になっているので、完全にデータが復元されてしまいました。

※プッシュ通知が受信できるかどうかは後日検証したら追記します。

検証したりする余裕がある方は、ぜひ各項目の設定を試してみてください。