Configuring Auto Backup for Apps 翻訳

A+ a-

ランタイムパミッションの翻訳をアップした後、指紋認証の話、Android Studioと第三者ライブラリの注意点と、結構バラバラに記事をアップしています。RiskFinderの6.0対応で調べた事が色々たまっており、本当はランタイムパミッションの話を長々と書きたいのですが、他にも注意すべき事項はありますので、なるべく他の人が書いてないセキュリティ物を優先的に書いていきたいと思います。

今回は、Android Developer Siteのバックアップ機能の説明ページの翻訳です。


Configuring Auto Backup for Apps 

URL:https://developer.android.com/intl/ja/training/backup/autosyncapi.html

ユーザはアプリを好みの設定にするのに多くの時間と労力を費やします。
新しいデイバイスに乗り換えた時は気をつけないと全ての設定を消してしまうことになります。
Android 6.0以上が動作するデバイスではアプリの自動バックアップ機能によってデフォルトでほぼすべてのアプリデータがバックアップされます。
この処理のためにアプリに特別なコードを追加する必要はありません。

ユーザが新しい端末にアプリをインストールした時や、ファクトリリセットした端末に改めてアプリをインストールした場合などにシステムは自動的にアプリデータをクラウドからレストアします。
このレッスンでは自動バックアップ機能の構築の仕方としてシステムデフォルトの動作と
特定のデータをバックアップから除外させる方法を学びます。

自動バックアップ機能はアプリによって生成されたデータをユーザのGoogle Drive上に暗号化してアップロードすることで保護します。
Google Drive上のバックアップデータはGoogle Driveの課金対象及びストレージ容量の計算には含まれません。
各アプリは上限25MBまでバックアップすることができ、容量が25MBに到達するとそれ以降クラウドにデータが送信されません。
その状態でレストアする場合は最後にクラウドにバックアップしたスナップショットが使用されます。

訳注 : Drive上では非公開ファイルとして扱われてユーザに表示されません。
また、端末設定 > バックアップとリセット > データのバックアップ からバックアップを無効にすることも可能です。
その他、同設定画面でバックアップで使用するアカウントの選択や自動復元の有効無効も設定できます。

自動バックアップは以下の条件が満たされている場合に実行されます。
  • デバイスがアイドル状態の時
  • デバイスが充電されている時
  • デバイスがWiFiに接続されている時
  • 最後にバックアップしてから24時間以上経過している時 

データバックアップの設定

Android6.0(API level 23)以上では、システムはデフォルトでアプリが作成したデータ全てをバックアップします。
例外としては後述の「自動的に除外されるデータ」があります。
このセクションではAndroidManifest.xmlを用いてバックアップされるデータに対して制限を設定する方法を説明します。
訳注 : 自動バックアップが動作するにはアプリのtargetSdkVersionが23以上である必要があります。

バックアップに含めるデータと除外するデータ

ファイルやディレクトリをバックアップ する/しない のルールを指定することにより、アプリがデータを保存する際の方法が変わります。

自動バックアップのルールはAndroidManifest.xmlに定義する内容で指定します。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        package="com.my.appexample">
    <uses-sdk android:minSdkVersion="MNC"/>
    <uses-sdk android:targetSdkVersion="MNC"/>
    <application ...
        android:fullBackupContent="@xml/mybackupscheme">
    </app>
    ...
</manifest>
(訳注 : "MNC"となっている箇所はプレビュー版ドキュメントのためであり、Android 6.0がリリースされた現状は"23"として読み替えて下さい。)
上の例では「android:fullBackupContent」属性とその参照先であるres/xml配下の「mybackupscheme.xml"」でどのファイルをバックアップするかのルールを設定しています。
以下の指定ではdevice_info.dbをバックアップから除外することを指定しています。

<?xml version="1.0" encoding="utf-8"?>
<full-backup-content>
    <exclude domain="database" path="device_info.db"/>
</full-backup-content>

自動的に除外されるデータ

大抵のアプリは全てのデータをバックアップすることを望みません。
例えば一時ファイルやキャッシュなどはシステムによってバックアップされないべきです。
そのため、自動バックアップサービスはデフォルトで以下のファイルを除外します。

  • getCacheDir()とgetCodeCacheDir()*1が参照するディレクトリ配下のファイルとディレクトリ
  • getExternalFilesDir()が参照するディレクトリ配下以外の外部ストレージのファイルとディレクトリ
  • getNoBackupFilesDir()*2が参照するディレクトリ配下のファイルとディレクトリ

バックアップ設定のシンタックス

バックアップサービスの設定では特定のファイルをバックアップに含めたり除外するように指定することができます。
XMLによるバックアップ設定の定義方法はこのようになります。

<full-backup-content>
    <include domain=["file" | "database" | "sharedpref" | "external" | "root"]
    path="string" />
    <exclude domain=["file" | "database" | "sharedpref" | "external" | "root"]
    path="string" />
</full-backup-content>
この後に続くエレメントと属性はファイルを含めたり除外したりする指定に使用します。

  • <include> :
    バックアップするリソースを指定します。
    これによりデフォルトのフルバックアップが無効になり、<include>で指定したリソースのみがバックアップされます。
    複数のリソースを指定する場合は<include>を複数使用します。
  • <exclude> :
    バックアップから除外するデータを指定します。
    <include>と<exclude>の両方が指定されている場合、<exclude>が優先されます。
  • domain :
    リソースタイプを指定するために以下の値を指定します。
    • root : アプリのルートディレクトリ内のリソース
    • file : getFilesDir()が参照するディレクトリ内のリソース
    • database : getDatabasePath()が参照するディレクトリ(SQLiteOpenHelperで利用される)内のデータベース
    • sharedpref : getSharedPreferences()で返されるSharedPreferenceオブジェクト
    • external : getExternalFilesDir()が参照する外部ストレージ内のリソース
  • path :
    リソースのファイルパスを指定します。
訳注 :
domainにdatabaseを指定した場合はSQLiteで自動的に生成されるジャーナルファイルも自動的に指定したことになる。

 例 :
  <exclude domain="database" path="mydtabase.db"/>を指定した場合は以下の2つが除外ファイルになる。
  - /[app-data-dir]/databases/mydatabase.db
  - /[app-data-dir]/databases/mydatabase.db-journal
  

pathにはファイルのほかディレクトリ名を指定することができる。
  例 :
  <exclude domain="root" path="hoge"/>を指定した場合は
  /[app-data-dir]/hoge 以下のファイルが全て除外対象となる(hogeディレクトリも除外対象)

データバックアップの無効化

アプリの全データに対してAutoBackupを無効化するにはAndroidManifest.xmlのappエレメント内で「android:allowBackup」属性にfalseを設定します。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        package="com.my.appexample">
    <uses-sdk android:minSdkVersion="MNC"/>
    <uses-sdk android:targetSdkVersion="MNC"/>
    <application ...        android:allowBackup="false">
    </application>
    ...</manifest>

以前のバージョンのサポート

Android 6.0(API level 23)より古い端末をサポートする2つのシナリオが考えられます。
一つは既存のアプリをアップデートすることで古い端末でのバックアップ動作をサポートしながら、Android6.0の端末で実行された場合に新しいバックアップが行われるようにするというものです。
もう一つは、新しいアプリをリリースする際に6.0未満の端末でもバックアップ機能をサポートするというものです。

Auto Backupに対応させるために既存のアプリをアップデートする場合

Androidの以前のバージョンではkey/valueペアによるバックアップの仕組みがサポートされています。
それはアプリにBackupAngetのサブクラスを定義してAndroidManifestにandroid:backupAgent属性を定義する方法です。
もしアプリがこのレガシーな方法を使用している場合、新しいバックアップ方法に移行するにはAndroidManifest.xmlの<application/>エレメントにandroid:fullBackupOnly="true"属性を追加します。
Android5.1(API level 22)以下の端末で実行した場合、マニフェストファイルの値は無視されて既存のバックアップ方法が使用されます。

もしkey/valueによるバックアップを使用していない場合でもBackupAgent.onCreate()やonFullBackup()などのカスタム処理を使用し続けることができます。また、レストアの完了通知を受けるためのBackupAgent.onRestoreFinished()も同様に使用できます。
この状態でXML設定(include/exclude)に基づくシステムデフォルトのAuto Backupを実行したい場合はsuper.onFullBackup()をコールする必要があります。

新しいアプリに古いバージョン向けのサポートを追加する場合

Android6.0をターゲットとするがAndroid5.1(API level 22)以前の古いデバイスでもクラウドバックアップを有効にする場合はBackup API(https://developer.android.com/training/backup/backupapi.html)を実装する必要があります。

バックアップ設定のテスト

バックアップの設定を作成したらバックアップとレストアが適切に実行されるかテストすることができます。

バックアップログ出力の有効化

バックアップ機能がどのようにXMLファイルの設定をパースしたかを知るために、実際のテストを実行するためにログ出力を有効化します。

$ adb shell setprop log.tag.BackupXmlParserLogging VERBOSE

バックアップテスト

手動でバックアップを実行するには、まずBackup Managerを初期化するために以下のコマンドを実行します。

$ adb shell bmgr run

次に以下のコマンドを用いてアプリの手動バックアップを実行します。
<PACKAGE>の箇所にはアプリのパッケージ名を指定します。

$ adb shell bmgr fullbackup <PACKAGE> 

レストアテスト

システムがバックアップしたアプリデータを手動レストアするには以下のコマンドを実行します。
<PACKAGE>の箇所にはアプリのパッケージ名を指定します。

$ adb shell bmgr restore <PACKAGE> 

!!! 注意点 この操作はアプリを停止させてレストア実行前のデータを消します !!!

自動的なレストアはアプリをアンインストールして再度インストールすることでテストできます。
アプリデータはインストール完了時に一度だけ自動的にレストアされます。

バックアップにおけるトラブルシューティング

バックアップが失敗する場合は Setting > Backup でバックアップのON/OFFを切り替える、ファクトリーリセット、または以下のコマンドでバックアップデータか関連するメタデータのどちらかをクリアすることができます。

$ adb shell bmgr wipe <TRANSPORT> <PACKAGE>
<TRANSPORT>の値の先頭に com.google.android.gms を追加する必要があります。
transportsのリストを取得するには以下のコマンドを実行します。

$ adb shell bmgr list transports

注釈 : 
上記のwipeコマンドを実行することでDrive側のファイルが削除されることを期待したが削除されなかった。
また、設定画面のバックアップ設定をON/OFFすると、「端末のデータ(Wi-Fiのパスワードや通話履歴など)とアプリのデータ(アプリ で保存された設定やファイルなど)のバックアップを停止し、Googleドライブ上のすべてのコピーを消去しますか?」と聞かれるのでサーバのファイルも削除されます。但しこの場合は全アプリのバックアップが消える。

Google Cloud Messagingの扱い方

プッシュ通知を受けるためにGoogle Cloud Messaging(GCM)を使用しているアプリにとってGCMの登録時に返されるregistrationトークンをバックアップ&レストアをすることは予期しない動作を引き起こす可能性があります。
これは新しい端末にアプリをインストールした場合、アプリは必ず新しいregistrationトークンを要求する必要が有るためです。
もし古いregistorationトークンがバックアップ&レストアによって提供されてしまった場合アプリは新しいトークンの取得を行いません。
この問題を回避するにはregistorationトークンをバックアップの候補から除外してください。

[*1]
API level 21(5.0)で追加されたメソッド。
実行時にアプリケーションによって生成されたコンパイルまたは最適化されたコードを格納するためのディレクトリ。
このディレクトリ内のファイルはアプリケーションの更新とプラットフォームアップグレード時に削除される。

[*2]
API level 21(5.0)で追加されたメソッド。
既存のBackupAgentでも使用されていたっぽい。

がく

がく

アンドロイドアプリの脆弱性検査ツールのRiskFinder株式会社 代表取締役 スマフォのセキュリティ色々やってます。

リスクファインダーはAndroidアプリのセキュリティホールを見つけます!

Androidスマートフォンが急速に普及するとともにアプリの脆弱性報告も急増しています。
リスクファインダーは、Androidアプリの脆弱性診断WEBサービスです。
500項目以上のチェックでアプリの脆弱性や問題を検出し、セキュアなアプリ開発をサポートします。

  • ブラウザでファイルをアップロードするだけ
  • アプリの脆弱性を指摘するだけでなく対処方法も提示
  • 頻繁にバージョンアップするAndroidの最新情報に素早く対応

リスクファインダーの詳細はこちら