From f0968050f6ae40a35b92dda32d19c571fcc0b15c Mon Sep 17 00:00:00 2001
From: Mark Lu By default, Auto Backup includes files in most of the directories that are
+assigned to your app by the system:
+ Auto Backup excludes files in directories returned by
+ {@link android.content.Context#getCacheDir()},
+ {@link android.content.Context#getCodeCacheDir()}, or
+ {@link android.content.Context#getNoBackupFilesDir()}. The files saved
+ in these locations are only needed temporarily, or are intentionally
+ excluded from backup operations.
+
+ You can configure your app to include and exclude particular files.
+For more information, see the Include and exclude files
+section.
+
+ Backup data is stored in a private folder in the user's Google Drive account,
+limited to 25MB per app. The saved data does not count towards the user's
+personal Google Drive quota. Only the most recent backup is stored. When a
+backup is made, the previous backup (if one exists) is deleted.
+
+ Users can see a list of apps that have been backed up in the Google Drive app under
+Settings -> Auto Backup for apps -> Manage backup. The
+backup data cannot be read by the user or other applications on the device.
+
+ Backups from each device-setup-lifetime are stored in separate datasets
+as shown in the following examples:
+ Caution: Once the amount of data reaches
+25MB, the app is banned from sending data to the
+cloud, even if the amount of data later falls under the 25MB threshold. The ban
+affects only the offending device (not other devices that the user owns) and
+lasts for the entire device-setup-lifetime. For example, if the user removes and
+reinstalls the application, the ban is still in effect. The ban is lifted when
+the user performs factory reset on the device.
+
+ Backups occur automatically when all of the following conditions are met:
+ In practice, these conditions occur roughly every night. To conserve network
+bandwidth, upload takes place only if app data has changed.
+
+ During Auto Backup, the system shuts down the app to make sure it is no longer
+writing to the file system. By default, the backup system ignores apps that are
+running in the foreground because users would notice their apps being shut down.
+You can override the default behavior by setting the
+backupInForeground
+attribute to true.
+
+ To simplify testing, Android includes tools that let you manually initiate
+a backup of your app. For more information, see
+Testing Backup and Restore.
+
+ Data is restored whenever the app is installed, either from the Play store,
+during device setup (when the system installs previously installed apps), or
+from running adb install. The restore operation occurs after the APK is
+installed, but before the app is available to be launched by the user.
+
+ During the initial device setup wizard, the user is shown a list of available backup
+datasets and is asked which one to restore the data from. Whichever backup
+dataset is selected becomes the ancestral dataset for the device. The device can
+restore from either its own backups or the ancestral dataset. The device
+prioritize its own backup if backups from both sources are available. If the
+user didn't go through the device setup wizard, then the device can restore only from
+its own backups.
+
+ To simplify testing, Android includes tools that let you manually initiate
+a restore of your app. For more information, see
+Testing Backup and Restore.
+
+ Apps that target Android 6.0 (API level 23) or higher automatically participate
+in Auto Backup. This is because the
+android:allowBackup
+attribute, which enables/disables backup, defaults to To disable Auto Backup, add either of the following attributes to the
+application element in your manifest file:
+
+ By default, the system backs up almost all app data. For more information,
+see Files that are backed up. This section shows you how to
+define custom XML rules to control what gets backed up.
+
+ The XML syntax for the configuration file is shown below:
+
+ Inside the note: Files in directories returned by Note: If your configuration file specifies both elements, then the
+backup contains everything captured by the Each element must include the following two attributes:
+ Note: You cannot backup files outside of these locations. Apps that implement Auto Backup do not need to implement {@link android.app.backup.BackupAgent}. However, you can optionally implement a custom {@link android.app.backup.BackupAgent}. Typically, there are two reasons for doing this:
+ Note: Your For more information, see
+Extending
+BackupAgent.
\ No newline at end of file
diff --git a/docs/html/guide/topics/data/backup.jd b/docs/html/guide/topics/data/backup.jd
index 619c79021870..a688c6e9889b 100644
--- a/docs/html/guide/topics/data/backup.jd
+++ b/docs/html/guide/topics/data/backup.jd
@@ -1,930 +1,34 @@
-page.title=Data Backup
-@jd:body
-
-
- Android's {@link android.app.backup backup} service allows you to copy your persistent
-application data to remote "cloud" storage, in order to provide a restore point for the
-application data and settings. If a user performs a factory reset or converts to a new
-Android-powered device, the system automatically restores your backup data when the application
-is re-installed. This way, your users don't need to reproduce their previous data or
-application settings. This process is completely transparent to the user and does not affect the
-functionality or user experience in your application. During a backup operation (which your application can request), Android's Backup Manager ({@link
-android.app.backup.BackupManager}) queries your application for backup data, then hands it to
-a backup transport, which then delivers the data to the cloud storage. During a
-restore operation, the Backup Manager retrieves the backup data from the backup transport and
-returns it to your application so your application can restore the data to the device. It's
-possible for your application to request a restore, but that shouldn't be necessary—Android
-automatically performs a restore operation when your application is installed and there exists
-backup data associated with the user. The primary scenario in which backup data is restored is when
-a user resets their device or upgrades to a new device and their previously installed
-applications are re-installed. Note: The backup service is not designed for
-synchronizing application data with other clients or saving data that you'd like to access during
-the normal application lifecycle. You cannot read or write backup data on demand and cannot access
-it in any way other than through the APIs provided by the Backup Manager. The backup transport is the client-side component of Android's backup framework, which is
-customizable by
-the device manufacturer and service provider. The backup transport may differ from device to device
-and which backup transport is available on any given device is transparent to your application. The
-Backup Manager APIs isolate your application from the actual backup transport available on a given
-device—your application communicates with the Backup Manager through a fixed set of APIs,
-regardless of the underlying transport. Data backup is not guaranteed to be available on all Android-powered
-devices. However, your application is not adversely affected in the event
-that a device does not provide a backup transport. If you believe that users will benefit from data
-backup in your application, then you can implement it as described in this document, test it, then
-publish your application without any concern about which devices actually perform backup. When your
-application runs on a device that does not provide a backup transport, your application operates
-normally, but will not receive callbacks from the Backup Manager to backup data. Although you cannot know what the current transport is, you are always assured that your
-backup data cannot be read by other applications on the device. Only the Backup Manager and backup
-transport have access to the data you provide during a backup operation. Caution: Because the cloud storage and transport service can
-differ from device to device, Android makes no guarantees about the security of your data while
-using backup. You should always be cautious about using backup to store sensitive data, such as
-usernames and passwords. To backup your application data, you need to implement a backup agent. Your backup
-agent is called by the Backup Manager to provide the data you want to back up. It is also called
-to restore your backup data when the application is re-installed. The Backup Manager handles all
-your data transactions with the cloud storage (using the backup transport) and your backup agent
-handles all your data transactions on the device. To implement a backup agent, you must:In this document
+
+
+
+ Key classes
+
+
+
+Files that are backed up
+
+
+
+Backup location
+
+
+
+Backup schedule
+
+
+
+Restore schedule
+Enabling and disabling backup
+true if omitted.
+To avoid confusion, we recommend you explicitly set the attribute in the <application>
+element of your AndroidManifest.xml. For example:
+
+<application ...
+ android:allowBackup="true">
+</app>
+
+
+
+
+android:allowBackup to false. This completely disables data
+ backup. You may want to disable backups when your app can recreate its state
+ through some other mechanism or when your app deals with sensitive
+ information that should not be backed up.android:allowBackup to true and
+ android:fullBackupOnly to false. With these settings,
+ your app always participates in Key/Value Backup, even when running on devices that
+ support Auto Backup.Including and excluding files
+
+
AndroidManifest.xml, add the android:fullBackupContent attribute to the
+ <application> element. This attribute points to an XML file that contains backup
+ rules. For example:
+ <application ...
+ android:fullBackupContent="@xml/my_backup_rules">
+ </app>
my_backup_rules.xml in the res/xml/ directory. Inside the file, add rules with the <include> and <exclude> elements. The following sample backs up all shared preferences except device.xml:
+ <?xml version="1.0" encoding="utf-8"?>
+<full-backup-content>
+ <include domain="sharedpref" path="."/>
+ <exclude domain="sharedpref" path="device.xml"/>
+</full-backup-content>
XML Config Syntax
+<full-backup-content>
+ <include domain=["file" | "database" | "sharedpref" | "external" | "root"]
+ path="string" />
+ <exclude domain=["file" | "database" | "sharedpref" | "external" | "root"]
+ path="string" />
+</full-backup-content>
+
+<full-backup-content> tag, you can define <include> and <exclude>
+elements:
+
+
+
+
+<include> - Specifies a file or folder to backup. By default, Auto Backup
+includes almost all app files. If you specify an <include> element, the system
+no longer includes any files by default and backs up only the files
+specified. To include multiple files, use multiple <include> elements.
+ getCacheDir(), getCodeCacheDir(), or
+getNoBackupFilesDir() are always excluded even if you try to include them.<exclude> - Specifies a file or folder to exclude during backup. Here are
+some files that are typically excluded from backup:
+
+ <exclude
+domain="file" path="instant-run"/>
+ <include> elements minus the
+resources named in the <exclude> elements. In other words,
+<exclude> takes precedence.
+
+
+
+
+domain - specifies the location of resource. Valid values for this attribute
+include the following:
+
+ root - the directory on the filesystem where all private files belonging to
+this app are stored.
+ file - directories returned by {@link android.content.Context#getFilesDir()}.
+ database - directories returned by {@link android.content.Context#getDatabasePath(String) getDatabasePath()}.
+Databases created with {@link android.database.sqlite.SQLiteOpenHelper}
+are stored here.
+ sharedpref - the directory where {@link android.content.SharedPreferences}
+are stored.
+ external the directory returned by {@link android.content.Context#getExternalFilesDir(String) getExternalFilesDir()}
+ path: Specifies a file or folder to include in or exclude from backup. Note
+that:
+
. to reference the current directory, however, you cannot
+reference the parent directory .. for security reasons.
+ Implementing BackupAgent
+
+
+
+super.onFullBackup().BackupAgent must
+implement the abstract methods
+{@link android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) onBackup()}
+and {@link android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) onRestore()}.
+Those methods are used for Key/Value Backup. So if
+you are not using Key/Value Backup, implement those methods and leave them blank.
+
+Quickview
-
-
-
- In this document
-
-
-
- Key classes
-
-
-
- See also
-
-
-The Basics
-
-
-
The {@link android.app.backup.BackupAgent} class provides the central interface with -which your application communicates with the Backup Manager. If you extend this class -directly, you must override {@link -android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) -onBackup()} and {@link -android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) -onRestore()} to handle the backup and restore operations for your data.
-Or
-The {@link android.app.backup.BackupAgentHelper} class provides a convenient -wrapper around the {@link android.app.backup.BackupAgent} class, which minimizes the amount of code -you need to write. In your {@link android.app.backup.BackupAgentHelper}, you must use one or more -"helper" objects, which automatically backup and restore certain types of data, so that you do not -need to implement {@link -android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) -onBackup()} and {@link -android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) -onRestore()}.
-Android currently provides backup helpers that will backup and restore complete files -from {@link android.content.SharedPreferences} and internal storage.
-This is the easiest step, so once you've decided on the class name for your backup agent, declare
-it in your manifest with the {@code
-android:backupAgent} attribute in the {@code
-
For example:
- --<manifest ... > - ... - <application android:label="MyApplication" - android:backupAgent="MyBackupAgent"> - <activity ... > - ... - </activity> - </application> -</manifest> -- -
Another attribute you might want to use is {@code -android:restoreAnyVersion}. This attribute takes a boolean value to indicate whether you -want to restore the application data regardless of the current application version compared to the -version that produced the backup data. (The default value is "{@code false}".) See Checking the Restore Data Version for more information.
- -Note: The backup service and the APIs you must use are -available only on devices running API Level 8 (Android 2.2) or greater, so you should also -set your {@code android:minSdkVersion} -attribute to "8".
- - - - -Google provides a backup transport with Android Backup Service for most -Android-powered devices running Android 2.2 or greater.
- -In order for your application to perform backup using Android Backup Service, you must -register your application with the service to receive a Backup Service Key, then -declare the Backup Service Key in your Android manifest.
- -To get your Backup Service Key, register for Android Backup Service.
-When you register, you will be provided a Backup Service Key and the appropriate {@code
-
-<application android:label="MyApplication" - android:backupAgent="MyBackupAgent"> - ... - <meta-data android:name="com.google.android.backup.api_key" - android:value="AEdPqrEAAAAIDaYEVgU6DJnyJdBmU7KLH3kszDXLv_4DIsEIyQ" /> -</application> -- -
The android:name must be "com.google.android.backup.api_key" and
-the android:value must be the Backup Service Key received from the Android Backup
-Service registration.
If you have multiple applications, you must register each one, using the respective package -name.
- -Note: The backup transport provided by Android Backup Service is
-not guaranteed to be available
-on all Android-powered devices that support backup. Some devices might support backup
-using a different transport, some devices might not support backup at all, and there is no way for
-your application to know what transport is used on the device. However, if you implement backup for
-your application, you should always include a Backup Service Key for Android Backup Service so
-your application can perform backup when the device uses the Android Backup Service transport. If
-the device does not use Android Backup Service, then the {@code
Most applications shouldn't need to extend the {@link android.app.backup.BackupAgent} class -directly, but should instead extend BackupAgentHelper to take -advantage of the built-in helper classes that automatically backup and restore your files. However, -you might want to extend {@link android.app.backup.BackupAgent} directly if you need to:
-If you don't need to perform any of the tasks above and want to back up complete files from -{@link android.content.SharedPreferences} or internal storage, you -should skip to Extending BackupAgentHelper.
- - - -When you create a backup agent by extending {@link android.app.backup.BackupAgent}, you -must implement the following callback methods:
- -When it's time to back up your application data, the Backup Manager calls your {@link -android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) -onBackup()} method. This is where you must provide your application data to the Backup Manager so -it can be saved to cloud storage.
- -Only the Backup Manager can call your backup agent's {@link -android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) -onBackup()} method. Each time that your application data changes and you want to perform a backup, -you must request a backup operation by calling {@link -android.app.backup.BackupManager#dataChanged()} (see Requesting -Backup for more information). A backup request does not result in an immediate call to your -{@link -android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) -onBackup()} method. Instead, the Backup Manager waits for an appropriate time, then performs -backup for all applications that have requested a backup since the last backup was performed.
- -Tip: While developing your application, you can initiate an -immediate backup operation from the Backup Manager with the {@code bmgr} tool.
- -When the Backup Manager calls your {@link -android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) -onBackup()} method, it passes three parameters:
- -Using these parameters, you should implement your {@link -android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) -onBackup()} method to do the following:
- -
-// Get the oldState input stream
-FileInputStream instream = new FileInputStream(oldState.getFileDescriptor());
-DataInputStream in = new DataInputStream(instream);
-
-try {
- // Get the last modified timestamp from the state file and data file
- long stateModified = in.readLong();
- long fileModified = mDataFile.lastModified();
-
- if (stateModified != fileModified) {
- // The file has been modified, so do a backup
- // Or the time on the device changed, so be safe and do a backup
- } else {
- // Don't back up because the file hasn't changed
- return;
- }
-} catch (IOException e) {
- // Unable to read state file... be safe and do a backup
-}
-
- If nothing has changed and you don't need to back up, skip to step 3.
-You must write each chunk of data as an "entity" in the {@link -android.app.backup.BackupDataOutput}. An entity is a flattened binary data -record that is identified by a unique key string. Thus, the data set that you back up is -conceptually a set of key-value pairs.
-To add an entity to your backup data set, you must:
-For example, the following code flattens some data into a byte stream and writes it into a -single entity:
--// Create buffer stream and data output stream for our data -ByteArrayOutputStream bufStream = new ByteArrayOutputStream(); -DataOutputStream outWriter = new DataOutputStream(bufStream); -// Write structured data -outWriter.writeUTF(mPlayerName); -outWriter.writeInt(mPlayerScore); -// Send the data to the Backup Manager via the BackupDataOutput -byte[] buffer = bufStream.toByteArray(); -int len = buffer.length; -data.writeEntityHeader(TOPSCORE_BACKUP_KEY, len); -data.writeEntityData(buffer, len); --
Perform this for each piece of data that you want to back up. How you divide your data into -entities is up to you (and you might use just one entity).
-The following example saves a representation of the current data into {@code newState} using -the file's last-modified timestamp:
--FileOutputStream outstream = new FileOutputStream(newState.getFileDescriptor()); -DataOutputStream out = new DataOutputStream(outstream); - -long modified = mDataFile.lastModified(); -out.writeLong(modified); --
Caution: If your application data is saved to a file, make sure -that you use synchronized statements while accessing the file so that your backup agent does not -read the file while an Activity in your application is also writing the file.
- - - - -When it's time to restore your application data, the Backup Manager calls your backup -agent's {@link android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) -onRestore()} method. When it calls this method, the Backup Manager delivers your backup data so -you can restore it onto the device.
- -Only the Backup Manager can call {@link -android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) -onRestore()}, which happens automatically when the system installs your application and -finds existing backup data. However, you can request a restore operation for -your application by calling {@link -android.app.backup.BackupManager#requestRestore(RestoreObserver) requestRestore()} (see Requesting restore for more information).
- -Note: While developing your application, you can also request a -restore operation with the {@code bmgr} -tool.
- -When the Backup Manager calls your {@link -android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) -onRestore()} method, it passes three parameters:
- -In your implementation of {@link -android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) -onRestore()}, you should call {@link android.app.backup.BackupDataInput#readNextHeader()} on the -{@code data} to iterate -through all entities in the data set. For each entity found, do the following:
- -For example, here's how you can restore the data backed up by the example in the previous -section:
- -
-@Override
-public void onRestore(BackupDataInput data, int appVersionCode,
- ParcelFileDescriptor newState) throws IOException {
- // There should be only one entity, but the safest
- // way to consume it is using a while loop
- while (data.readNextHeader()) {
- String key = data.getKey();
- int dataSize = data.getDataSize();
-
- // If the key is ours (for saving top score). Note this key was used when
- // we wrote the backup entity header
- if (TOPSCORE_BACKUP_KEY.equals(key)) {
- // Create an input stream for the BackupDataInput
- byte[] dataBuf = new byte[dataSize];
- data.readEntityData(dataBuf, 0, dataSize);
- ByteArrayInputStream baStream = new ByteArrayInputStream(dataBuf);
- DataInputStream in = new DataInputStream(baStream);
-
- // Read the player name and score from the backup data
- mPlayerName = in.readUTF();
- mPlayerScore = in.readInt();
-
- // Record the score on the device (to a file or something)
- recordScore(mPlayerName, mPlayerScore);
- } else {
- // We don't know this entity key. Skip it. (Shouldn't happen.)
- data.skipEntityData();
- }
- }
-
- // Finally, write to the state blob (newState) that describes the restored data
- FileOutputStream outstream = new FileOutputStream(newState.getFileDescriptor());
- DataOutputStream out = new DataOutputStream(outstream);
- out.writeUTF(mPlayerName);
- out.writeInt(mPlayerScore);
-}
-
-
-In this example, the {@code appVersionCode} parameter passed to {@link -android.app.backup.BackupAgent#onRestore onRestore()} is not used. However, you might want to use -it if you've chosen to perform backup when the user's version of the application has actually moved -backward (for example, the user went from version 1.5 of your app to 1.0). For more information, see -the section about Checking the Restore Data Version.
- -For an example implementation of {@link android.app.backup.BackupAgent}, see the {@code -ExampleAgent} class in the Backup and Restore sample -application.
-You should build your backup agent using {@link android.app.backup.BackupAgentHelper} if you want -to back up complete files (from either {@link android.content.SharedPreferences} or internal storage). -Building your backup agent with {@link android.app.backup.BackupAgentHelper} requires far less -code than extending {@link android.app.backup.BackupAgent}, because you don't have to implement -{@link -android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) -onBackup()} and {@link -android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) -onRestore()}.
- -Your implementation of {@link android.app.backup.BackupAgentHelper} must -use one or more backup helpers. A backup helper is a specialized -component that {@link android.app.backup.BackupAgentHelper} summons to perform backup and -restore operations for a particular type of data. The Android framework currently provides two -different helpers:
-You can include multiple helpers in your {@link android.app.backup.BackupAgentHelper}, but only -one helper is needed for each data type. That is, if you have multiple {@link -android.content.SharedPreferences} files, then you need only one {@link -android.app.backup.SharedPreferencesBackupHelper}.
- -For each helper you want to add to your {@link android.app.backup.BackupAgentHelper}, you must do -the following during your {@link android.app.backup.BackupAgent#onCreate()} method:
-The following sections describe how to create a backup agent using each of the available -helpers.
- - - -When you instantiate a {@link android.app.backup.SharedPreferencesBackupHelper}, you must -include the name of one or more {@link android.content.SharedPreferences} files.
- -For example, to back up a {@link android.content.SharedPreferences} file named -"user_preferences", a complete backup agent using {@link android.app.backup.BackupAgentHelper} looks -like this:
- -
-public class MyPrefsBackupAgent extends BackupAgentHelper {
- // The name of the SharedPreferences file
- static final String PREFS = "user_preferences";
-
- // A key to uniquely identify the set of backup data
- static final String PREFS_BACKUP_KEY = "prefs";
-
- // Allocate a helper and add it to the backup agent
- @Override
- public void onCreate() {
- SharedPreferencesBackupHelper helper =
- new SharedPreferencesBackupHelper(this, PREFS);
- addHelper(PREFS_BACKUP_KEY, helper);
- }
-}
-
-
-That's it! That's your entire backup agent. The {@link -android.app.backup.SharedPreferencesBackupHelper} includes all the code -needed to backup and restore a {@link android.content.SharedPreferences} file.
- -When the Backup Manager calls {@link -android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) -onBackup()} and {@link -android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) -onRestore()}, {@link android.app.backup.BackupAgentHelper} calls your backup helpers to perform -backup and restore for your specified files.
- -Note: {@link android.content.SharedPreferences} are threadsafe, so -you can safely read and write the shared preferences file from your backup agent and -other activities.
- - - -When you instantiate a {@link android.app.backup.FileBackupHelper}, you must include the name of -one or more files that are saved to your application's internal storage -(as specified by {@link android.content.ContextWrapper#getFilesDir()}, which is the same -location where {@link android.content.Context#openFileOutput(String,int) openFileOutput()} writes -files).
- -For example, to backup two files named "scores" and "stats," a backup agent using {@link -android.app.backup.BackupAgentHelper} looks like this:
- -
-public class MyFileBackupAgent extends BackupAgentHelper {
- // The name of the file
- static final String TOP_SCORES = "scores";
- static final String PLAYER_STATS = "stats";
-
- // A key to uniquely identify the set of backup data
- static final String FILES_BACKUP_KEY = "myfiles";
-
- // Allocate a helper and add it to the backup agent
- @Override
- public void onCreate() {
- FileBackupHelper helper = new FileBackupHelper(this,
- TOP_SCORES, PLAYER_STATS);
- addHelper(FILES_BACKUP_KEY, helper);
- }
-}
-
-
-The {@link android.app.backup.FileBackupHelper} includes all the code necessary to backup and -restore files that are saved to your application's internal storage..
- -However, reading and writing to files on internal storage is not threadsafe. To -ensure that your backup agent does not read or write your files at the same time as your activities, -you must use synchronized statements each time you perform a read or write. For example, -in any Activity where you read and write the file, you need an object to use as the intrinsic -lock for the synchronized statements:
- --// Object for intrinsic lock -static final Object sDataLock = new Object(); -- -
Then create a synchronized statement with this lock each time you read or write the files. For -example, here's a synchronized statement for writing the latest score in a game to a file:
- -
-try {
- synchronized (MyActivity.sDataLock) {
- File dataFile = new File({@link android.content.Context#getFilesDir()}, TOP_SCORES);
- RandomAccessFile raFile = new RandomAccessFile(dataFile, "rw");
- raFile.writeInt(score);
- }
-} catch (IOException e) {
- Log.e(TAG, "Unable to write to file");
-}
-
-
-You should synchronize your read statements with the same lock.
- -Then, in your {@link android.app.backup.BackupAgentHelper}, you must override {@link -android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) -onBackup()} and {@link -android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) -onRestore()} to synchronize the backup and restore operations with the same -intrinsic lock. For example, the {@code MyFileBackupAgent} example from above needs the following -methods:
- -
-@Override
-public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
- ParcelFileDescriptor newState) throws IOException {
- // Hold the lock while the FileBackupHelper performs backup
- synchronized (MyActivity.sDataLock) {
- super.onBackup(oldState, data, newState);
- }
-}
-
-@Override
-public void onRestore(BackupDataInput data, int appVersionCode,
- ParcelFileDescriptor newState) throws IOException {
- // Hold the lock while the FileBackupHelper restores the file
- synchronized (MyActivity.sDataLock) {
- super.onRestore(data, appVersionCode, newState);
- }
-}
-
-
-That's it. All you need to do is add your {@link android.app.backup.FileBackupHelper} in the -{@link android.app.backup.BackupAgent#onCreate()} method and override {@link -android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) -onBackup()} and {@link -android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) -onRestore()} to synchronize read and write operations.
- -For an example implementation of {@link -android.app.backup.BackupAgentHelper} with {@link android.app.backup.FileBackupHelper}, see the -{@code FileHelperExampleAgent} class in the Backup and Restore sample -application.
-When the Backup Manager saves your data to cloud storage, it automatically includes the version -of your application, as defined by your manifest file's {@code android:versionCode} -attribute. Before the Backup Manager calls your backup agent to restore your data, it -looks at the {@code -android:versionCode} of the installed application and compares it to the value -recorded in the restore data set. If the version recorded in the restore data set is -newer than the application version on the device, then the user has downgraded their -application. In this case, the Backup Manager will abort the restore operation for your application -and not call your {@link -android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) onRestore()} -method, because the restore set is considered meaningless to an older version.
- -You can override this behavior with the {@code -android:restoreAnyVersion} attribute. This attribute is either "{@code true}" or "{@code -false}" to indicate whether you want to restore the application regardless of the restore set -version. The default value is "{@code false}". If you define this to be "{@code true}" then the -Backup Manager will ignore the {@code android:versionCode} -and call your {@link -android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) onRestore()} -method in all cases. In doing so, you can manually check for the version difference in your {@link -android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) onRestore()} -method and take any steps necessary to make the data compatible if the versions conflict.
- -To help you handle different versions during a restore operation, the {@link -android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) onRestore()} -method passes you the version code included with the restore data set as the {@code appVersionCode} -parameter. You can then query the current application's version code with the {@link -android.content.pm.PackageInfo#versionCode PackageInfo.versionCode} field. For example:
- -
-PackageInfo info;
-try {
- String name = {@link android.content.ContextWrapper#getPackageName() getPackageName}();
- info = {@link android.content.ContextWrapper#getPackageManager
-getPackageManager}().{@link android.content.pm.PackageManager#getPackageInfo(String,int)
-getPackageInfo}(name,0);
-} catch (NameNotFoundException nnfe) {
- info = null;
-}
-
-int version;
-if (info != null) {
- version = info.versionCode;
-}
-
-
-Then simply compare the {@code version} acquired from {@link android.content.pm.PackageInfo} -to the {@code appVersionCode} passed into {@link -android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) onRestore()}. -
- -Caution: Be certain you understand the consequences of setting -{@code -android:restoreAnyVersion} to "{@code true}" for your application. If each version of your -application that supports backup does not properly account for variations in your data format during -{@link -android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) onRestore()}, -then the data on the device could be saved in a format incompatible with the version currently -installed on the device.
- - - -You can request a backup operation at any time by calling {@link -android.app.backup.BackupManager#dataChanged()}. This method notifies the Backup Manager that you'd -like to backup your data using your backup agent. The Backup Manager then calls your backup -agent's {@link -android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) -onBackup()} method at an opportune time in the future. Typically, you should -request a backup each time your data changes (such as when the user changes an application -preference that you'd like to back up). If you call {@link -android.app.backup.BackupManager#dataChanged()} several times consecutively, before the Backup -Manager requests a backup from your agent, your agent still receives just one call to {@link -android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) -onBackup()}.
- -Note: While developing your application, you can request a -backup and initiate an immediate backup operation with the {@code bmgr} -tool.
- - -During the normal life of your application, you shouldn't need to request a restore operation. -They system automatically checks for backup data and performs a restore when your application is -installed. However, you can manually request a restore operation by calling {@link -android.app.backup.BackupManager#requestRestore(RestoreObserver) requestRestore()}, if necessary. In -which case, the Backup Manager calls your {@link -android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) onRestore()} -implementation, passing the data from the current set of backup data.
- -Note: While developing your application, you can request a -restore operation with the {@code bmgr} -tool.
- - -Once you've implemented your backup agent, you can test the backup and restore functionality -with the following procedure, using {@code bmgr}.
- -adb shell bmgr enable true-
If you've properly implemented backup in your application, then it should request a -backup each time the data changes. For example, each time the user changes some data, your app -should call {@link android.app.backup.BackupManager#dataChanged()}, which adds a backup request to -the Backup Manager queue. For testing purposes, you can also make a request with the following -{@code bmgr} command:
-adb shell bmgr backup your.package.name-
adb shell bmgr run-
This forces the Backup Manager to perform all backup requests that are in its -queue.
-adb uninstall your.package.name-
If your backup agent is successful, all the data you initialized in step 4 is restored.
+startpage=true +@jd:body +Users often invest significant time and effort creating data and setting +preferences within apps. Preserving that data for users if they replace a broken +device or upgrade to a new one is an important part of ensuring a great user +experience. This section covers techniques for backing up data to the cloud so +that users can restore their data. + +
Android provides two ways for apps to backup their data to the cloud: +Auto Backup for Apps and +Key/Value Backup. +Auto Backup, which is available starting API 23, preserves app data by uploading +it to the user’s Google Drive account. The Key/Value Backup feature (formerly +known as the Backup API and the Android Backup Service) preserves app data by +uploading it to the Android Backup Service. + +
Generally, we recommend Auto Backup because it requires no work to implement. +Apps that target Android 6.0 (API level 23) or higher are automatically enabled +for Auto Backup. The Auto Backup feature does have some limitations in terms of +what data it can backup and it's availability on Android 6.0 and higher devices. +Consider using the Key/Value Backup feature if you have more specific needs for +backing up your app data. For more information, see Comparison of Key/Value and Auto Backup
+ +Note: These data backup features are not designed for synchronizing app data with other clients or +saving data that you'd like to access during the normal application lifecycle. +You cannot read or write backup data on demand. For synchronizing app data, see +Transferring +Data Using Sync Adapters or Google Drive Android +API. \ No newline at end of file diff --git a/docs/html/guide/topics/data/images/backup-framework.png b/docs/html/guide/topics/data/images/backup-framework.png new file mode 100644 index 000000000000..2ba2e612c9bd Binary files /dev/null and b/docs/html/guide/topics/data/images/backup-framework.png differ diff --git a/docs/html/guide/topics/data/index.jd b/docs/html/guide/topics/data/index.jd index 3872825f1619..2365f18aaeb8 100644 --- a/docs/html/guide/topics/data/index.jd +++ b/docs/html/guide/topics/data/index.jd @@ -5,21 +5,3 @@ page.landing.image= @jd:body -
Since Android 2.2 (API 8), Android has offered the Key/Value Backup +feature as a way for developers to backup app data to the cloud. The Key/Value +Backup feature (formerly known as the Backup API and the Android Backup Service) +preserves app data by uploading it to +Android Backup Service. +The amount of data is limited to 5MB per user of your app and there is +no charge for storing backup data. + +
Note: If your app implements Key/Value Backup +and targets API 23 or higher, you should set +android:fullBackupOnly. +This attribute indicates whether or not to use Auto Backup on devices where it is available. + +
Like Auto Backup, Key/Value Backups are restored automatically whenever the app +is installed. The following table describes some of the key differences between Key/Value Backup and Auto Backup: + +
| Key/Value Backup | +Auto Backup | +
|---|---|
| Available in API 8, Android 2.2 | +Available in API 23, Android 6.0 | +
| Apps must implement a {@link android.app.backup.BackupAgent}. The backup agent defines what data to backup and how to +restore data. | +By default, Auto Backup includes almost all of the app's files. You can +use XML to include and exclude files. Under the hood, Auto Backup relies on a +backup agent that is built into the framework. | +
| Apps must issue a request when there is data +that is ready to be backed up. Requests +from multiple apps are batched and executed every few hours. | +Backups happen automatically roughly once a day. | +
| Backup data can be transmitted via wifi or cellular data. | +Backup data is tranmitted only via wifi. If the device is never connected to a +wifi network, then Auto Backup never occurs. | +
| Apps are not shut down during backup. | +The system shuts down the app during backup. | +
| Backup data is stored in Android Backup Service limited to 5MB per app. | +Backup data is stored in the user's Google Drive limited to 25MB per app. | +
Related API methods are not filed based:
|
+ Related API methods are filed based:
|
+
To backup your application data, you need to implement a backup agent. Your backup +agent is called by the Backup Manager both during backup and restore.
+ +To implement a backup agent, you must:
+ +The {@link android.app.backup.BackupAgent} class provides the central interface with +which your application communicates with the Backup Manager. If you extend this class +directly, you must override {@link +android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) +onBackup()} and {@link +android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) +onRestore()} to handle the backup and restore operations for your data.
+Or
+The {@link android.app.backup.BackupAgentHelper} class provides a convenient +wrapper around the {@link android.app.backup.BackupAgent} class, which minimizes the amount of code +you need to write. In your {@link android.app.backup.BackupAgentHelper}, you must use one or more +"helper" objects, which automatically backup and restore certain types of data, so that you do not +need to implement {@link +android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) +onBackup()} and {@link +android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) +onRestore()}.
+Android currently provides backup helpers that will backup and restore complete files +from {@link android.content.SharedPreferences} and internal storage.
+This is the easiest step, so once you've decided on the class name for your backup agent, declare
+it in your manifest with the {@code
+android:backupAgent} attribute in the {@code
+
For example:
+ ++<manifest ... > + ... + <application android:label="MyApplication" + android:backupAgent="MyBackupAgent"> + <activity ... > + ... + </activity> + </application> +</manifest> ++ +
Another attribute you might want to use is {@code +android:restoreAnyVersion}. This attribute takes a boolean value to indicate whether you +want to restore the application data regardless of the current application version compared to the +version that produced the backup data. (The default value is "{@code false}".) See Checking the Restore Data Version for more information.
+ +Note: The backup service and the APIs you must use are +available only on devices running API Level 8 (Android 2.2) or greater, so you should also +set your {@code android:minSdkVersion} +attribute to "8".
+ + + + +Google provides a backup transport with Android Backup Service for most +Android-powered devices running Android 2.2 or greater.
+ +In order for your application to perform backup using Android Backup Service, you must +register your application with the service to receive a Backup Service Key, then +declare the Backup Service Key in your Android manifest.
+ +To get your Backup Service Key, register for Android Backup Service.
+When you register, you will be provided a Backup Service Key and the appropriate {@code
+
+<application android:label="MyApplication" + android:backupAgent="MyBackupAgent"> + ... + <meta-data android:name="com.google.android.backup.api_key" + android:value="AEdPqrEAAAAIDaYEVgU6DJnyJdBmU7KLH3kszDXLv_4DIsEIyQ" /> +</application> ++ +
The android:name must be "com.google.android.backup.api_key" and
+the android:value must be the Backup Service Key received from the Android Backup
+Service registration.
If you have multiple applications, you must register each one, using the respective package +name.
+ +Note: The backup transport provided by Android Backup Service is
+not guaranteed to be available
+on all Android-powered devices that support backup. Some devices might support backup
+using a different transport, some devices might not support backup at all, and there is no way for
+your application to know what transport is used on the device. However, if you implement backup for
+your application, you should always include a Backup Service Key for Android Backup Service so
+your application can perform backup when the device uses the Android Backup Service transport. If
+the device does not use Android Backup Service, then the {@code
Most applications shouldn't need to extend the {@link android.app.backup.BackupAgent} class +directly, but should instead extend BackupAgentHelper to take +advantage of the built-in helper classes that automatically backup and restore your files. However, +you might want to extend {@link android.app.backup.BackupAgent} directly if you need to:
+If you don't need to perform any of the tasks above and want to back up complete files from +{@link android.content.SharedPreferences} or internal storage, you +should skip to Extending BackupAgentHelper.
+ + + +When you create a backup agent by extending {@link android.app.backup.BackupAgent}, you +must implement the following callback methods:
+ +When it's time to back up your application data, the Backup Manager calls your {@link +android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) +onBackup()} method. This is where you must provide your application data to the Backup Manager so +it can be saved to cloud storage.
+ +Only the Backup Manager can call your backup agent's {@link +android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) +onBackup()} method. Each time that your application data changes and you want to perform a backup, +you must request a backup operation by calling {@link +android.app.backup.BackupManager#dataChanged()} (see Requesting +Backup for more information). A backup request does not result in an immediate call to your +{@link +android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) +onBackup()} method. Instead, the Backup Manager waits for an appropriate time, then performs +backup for all applications that have requested a backup since the last backup was performed.
+ +Tip: While developing your application, you can initiate an +immediate backup operation from the Backup Manager with the {@code bmgr} tool.
+ +When the Backup Manager calls your {@link +android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) +onBackup()} method, it passes three parameters:
+ +Using these parameters, you should implement your {@link +android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) +onBackup()} method to do the following:
+ +
+// Get the oldState input stream
+FileInputStream instream = new FileInputStream(oldState.getFileDescriptor());
+DataInputStream in = new DataInputStream(instream);
+
+try {
+ // Get the last modified timestamp from the state file and data file
+ long stateModified = in.readLong();
+ long fileModified = mDataFile.lastModified();
+
+ if (stateModified != fileModified) {
+ // The file has been modified, so do a backup
+ // Or the time on the device changed, so be safe and do a backup
+ } else {
+ // Don't back up because the file hasn't changed
+ return;
+ }
+} catch (IOException e) {
+ // Unable to read state file... be safe and do a backup
+}
+
+ If nothing has changed and you don't need to back up, skip to step 3.
+You must write each chunk of data as an "entity" in the {@link +android.app.backup.BackupDataOutput}. An entity is a flattened binary data +record that is identified by a unique key string. Thus, the data set that you back up is +conceptually a set of key-value pairs.
+To add an entity to your backup data set, you must:
+For example, the following code flattens some data into a byte stream and writes it into a +single entity:
++// Create buffer stream and data output stream for our data +ByteArrayOutputStream bufStream = new ByteArrayOutputStream(); +DataOutputStream outWriter = new DataOutputStream(bufStream); +// Write structured data +outWriter.writeUTF(mPlayerName); +outWriter.writeInt(mPlayerScore); +// Send the data to the Backup Manager via the BackupDataOutput +byte[] buffer = bufStream.toByteArray(); +int len = buffer.length; +data.writeEntityHeader(TOPSCORE_BACKUP_KEY, len); +data.writeEntityData(buffer, len); ++
Perform this for each piece of data that you want to back up. How you divide your data into +entities is up to you (and you might use just one entity).
+The following example saves a representation of the current data into {@code newState} using +the file's last-modified timestamp:
++FileOutputStream outstream = new FileOutputStream(newState.getFileDescriptor()); +DataOutputStream out = new DataOutputStream(outstream); + +long modified = mDataFile.lastModified(); +out.writeLong(modified); ++
Caution: If your application data is saved to a file, make sure +that you use synchronized statements while accessing the file so that your backup agent does not +read the file while an Activity in your application is also writing the file.
+ + + + +When it's time to restore your application data, the Backup Manager calls your backup +agent's {@link android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) +onRestore()} method. When it calls this method, the Backup Manager delivers your backup data so +you can restore it onto the device.
+ +Only the Backup Manager can call {@link +android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) +onRestore()}, which happens automatically when the system installs your application and +finds existing backup data. However, you can request a restore operation for +your application by calling {@link +android.app.backup.BackupManager#requestRestore(RestoreObserver) requestRestore()} (see Requesting restore for more information).
+ +Note: While developing your application, you can also request a +restore operation with the {@code bmgr} +tool.
+ +When the Backup Manager calls your {@link +android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) +onRestore()} method, it passes three parameters:
+ +In your implementation of {@link +android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) +onRestore()}, you should call {@link android.app.backup.BackupDataInput#readNextHeader()} on the +{@code data} to iterate +through all entities in the data set. For each entity found, do the following:
+ +For example, here's how you can restore the data backed up by the example in the previous +section:
+ +
+@Override
+public void onRestore(BackupDataInput data, int appVersionCode,
+ ParcelFileDescriptor newState) throws IOException {
+ // There should be only one entity, but the safest
+ // way to consume it is using a while loop
+ while (data.readNextHeader()) {
+ String key = data.getKey();
+ int dataSize = data.getDataSize();
+
+ // If the key is ours (for saving top score). Note this key was used when
+ // we wrote the backup entity header
+ if (TOPSCORE_BACKUP_KEY.equals(key)) {
+ // Create an input stream for the BackupDataInput
+ byte[] dataBuf = new byte[dataSize];
+ data.readEntityData(dataBuf, 0, dataSize);
+ ByteArrayInputStream baStream = new ByteArrayInputStream(dataBuf);
+ DataInputStream in = new DataInputStream(baStream);
+
+ // Read the player name and score from the backup data
+ mPlayerName = in.readUTF();
+ mPlayerScore = in.readInt();
+
+ // Record the score on the device (to a file or something)
+ recordScore(mPlayerName, mPlayerScore);
+ } else {
+ // We don't know this entity key. Skip it. (Shouldn't happen.)
+ data.skipEntityData();
+ }
+ }
+
+ // Finally, write to the state blob (newState) that describes the restored data
+ FileOutputStream outstream = new FileOutputStream(newState.getFileDescriptor());
+ DataOutputStream out = new DataOutputStream(outstream);
+ out.writeUTF(mPlayerName);
+ out.writeInt(mPlayerScore);
+}
+
+
+In this example, the {@code appVersionCode} parameter passed to {@link +android.app.backup.BackupAgent#onRestore onRestore()} is not used. However, you might want to use +it if you've chosen to perform backup when the user's version of the application has actually moved +backward (for example, the user went from version 1.5 of your app to 1.0). For more information, see +the section about Checking the Restore Data Version.
+ +For an example implementation of {@link android.app.backup.BackupAgent}, see the {@code +ExampleAgent} class in the Backup and Restore sample +application.
+You should build your backup agent using {@link android.app.backup.BackupAgentHelper} if you want +to back up complete files (from either {@link android.content.SharedPreferences} or internal storage). +Building your backup agent with {@link android.app.backup.BackupAgentHelper} requires far less +code than extending {@link android.app.backup.BackupAgent}, because you don't have to implement +{@link +android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) +onBackup()} and {@link +android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) +onRestore()}.
+ +Your implementation of {@link android.app.backup.BackupAgentHelper} must +use one or more backup helpers. A backup helper is a specialized +component that {@link android.app.backup.BackupAgentHelper} summons to perform backup and +restore operations for a particular type of data. The Android framework currently provides two +different helpers:
+You can include multiple helpers in your {@link android.app.backup.BackupAgentHelper}, but only +one helper is needed for each data type. That is, if you have multiple {@link +android.content.SharedPreferences} files, then you need only one {@link +android.app.backup.SharedPreferencesBackupHelper}.
+ +For each helper you want to add to your {@link android.app.backup.BackupAgentHelper}, you must do +the following during your {@link android.app.backup.BackupAgent#onCreate()} method:
+The following sections describe how to create a backup agent using each of the available +helpers.
+ + + +When you instantiate a {@link android.app.backup.SharedPreferencesBackupHelper}, you must +include the name of one or more {@link android.content.SharedPreferences} files.
+ +For example, to back up a {@link android.content.SharedPreferences} file named +"user_preferences", a complete backup agent using {@link android.app.backup.BackupAgentHelper} looks +like this:
+ +
+public class MyPrefsBackupAgent extends BackupAgentHelper {
+ // The name of the SharedPreferences file
+ static final String PREFS = "user_preferences";
+
+ // A key to uniquely identify the set of backup data
+ static final String PREFS_BACKUP_KEY = "prefs";
+
+ // Allocate a helper and add it to the backup agent
+ @Override
+ public void onCreate() {
+ SharedPreferencesBackupHelper helper =
+ new SharedPreferencesBackupHelper(this, PREFS);
+ addHelper(PREFS_BACKUP_KEY, helper);
+ }
+}
+
+
+That's it! That's your entire backup agent. The {@link +android.app.backup.SharedPreferencesBackupHelper} includes all the code +needed to backup and restore a {@link android.content.SharedPreferences} file.
+ +When the Backup Manager calls {@link +android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) +onBackup()} and {@link +android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) +onRestore()}, {@link android.app.backup.BackupAgentHelper} calls your backup helpers to perform +backup and restore for your specified files.
+ +Note: The methods of {@link android.content.SharedPreferences} +are threadsafe, so +you can safely read and write the shared preferences file from your backup agent and +other activities.
+ + + +When you instantiate a {@link android.app.backup.FileBackupHelper}, you must include the name of +one or more files that are saved to your application's internal storage +(as specified by {@link android.content.ContextWrapper#getFilesDir()}, which is the same +location where {@link android.content.Context#openFileOutput(String,int) openFileOutput()} writes +files).
+ +For example, to backup two files named "scores" and "stats," a backup agent using {@link +android.app.backup.BackupAgentHelper} looks like this:
+ +
+public class MyFileBackupAgent extends BackupAgentHelper {
+ // The name of the file
+ static final String TOP_SCORES = "scores";
+ static final String PLAYER_STATS = "stats";
+
+ // A key to uniquely identify the set of backup data
+ static final String FILES_BACKUP_KEY = "myfiles";
+
+ // Allocate a helper and add it to the backup agent
+ @Override
+ public void onCreate() {
+ FileBackupHelper helper = new FileBackupHelper(this,
+ TOP_SCORES, PLAYER_STATS);
+ addHelper(FILES_BACKUP_KEY, helper);
+ }
+}
+
+
+The {@link android.app.backup.FileBackupHelper} includes all the code necessary to backup and +restore files that are saved to your application's internal storage..
+ +However, reading and writing to files on internal storage is not threadsafe. To +ensure that your backup agent does not read or write your files at the same time as your activities, +you must use synchronized statements each time you perform a read or write. For example, +in any Activity where you read and write the file, you need an object to use as the intrinsic +lock for the synchronized statements:
+ ++// Object for intrinsic lock +static final Object sDataLock = new Object(); ++ +
Then create a synchronized statement with this lock each time you read or write the files. For +example, here's a synchronized statement for writing the latest score in a game to a file:
+ +
+try {
+ synchronized (MyActivity.sDataLock) {
+ File dataFile = new File({@link android.content.Context#getFilesDir()}, TOP_SCORES);
+ RandomAccessFile raFile = new RandomAccessFile(dataFile, "rw");
+ raFile.writeInt(score);
+ }
+} catch (IOException e) {
+ Log.e(TAG, "Unable to write to file");
+}
+
+
+You should synchronize your read statements with the same lock.
+ +Then, in your {@link android.app.backup.BackupAgentHelper}, you must override {@link +android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) +onBackup()} and {@link +android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) +onRestore()} to synchronize the backup and restore operations with the same +intrinsic lock. For example, the {@code MyFileBackupAgent} example from above needs the following +methods:
+ +
+@Override
+public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
+ ParcelFileDescriptor newState) throws IOException {
+ // Hold the lock while the FileBackupHelper performs backup
+ synchronized (MyActivity.sDataLock) {
+ super.onBackup(oldState, data, newState);
+ }
+}
+
+@Override
+public void onRestore(BackupDataInput data, int appVersionCode,
+ ParcelFileDescriptor newState) throws IOException {
+ // Hold the lock while the FileBackupHelper restores the file
+ synchronized (MyActivity.sDataLock) {
+ super.onRestore(data, appVersionCode, newState);
+ }
+}
+
+
+That's it. All you need to do is add your {@link android.app.backup.FileBackupHelper} in the +{@link android.app.backup.BackupAgent#onCreate()} method and override {@link +android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) +onBackup()} and {@link +android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) +onRestore()} to synchronize read and write operations.
+ +For an example implementation of {@link +android.app.backup.BackupAgentHelper} with {@link android.app.backup.FileBackupHelper}, see the +{@code FileHelperExampleAgent} class in the Backup and Restore sample +application.
+When the Backup Manager saves your data to cloud storage, it automatically includes the version +of your application, as defined by your manifest file's {@code android:versionCode} +attribute. Before the Backup Manager calls your backup agent to restore your data, it +looks at the {@code +android:versionCode} of the installed application and compares it to the value +recorded in the restore data set. If the version recorded in the restore data set is +newer than the application version on the device, then the user has downgraded their +application. In this case, the Backup Manager will abort the restore operation for your application +and not call your {@link +android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) onRestore()} +method, because the restore set is considered meaningless to an older version.
+ +You can override this behavior with the {@code +android:restoreAnyVersion} attribute. This attribute is either "{@code true}" or "{@code +false}" to indicate whether you want to restore the application regardless of the restore set +version. The default value is "{@code false}". If you define this to be "{@code true}" then the +Backup Manager will ignore the {@code android:versionCode} +and call your {@link +android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) onRestore()} +method in all cases. In doing so, you can manually check for the version difference in your {@link +android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) onRestore()} +method and take any steps necessary to make the data compatible if the versions conflict.
+ +To help you handle different versions during a restore operation, the {@link +android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) onRestore()} +method passes you the version code included with the restore data set as the {@code appVersionCode} +parameter. You can then query the current application's version code with the {@link +android.content.pm.PackageInfo#versionCode PackageInfo.versionCode} field. For example:
+ +
+PackageInfo info;
+try {
+ String name = {@link android.content.ContextWrapper#getPackageName() getPackageName}();
+ info = {@link android.content.ContextWrapper#getPackageManager
+getPackageManager}().{@link android.content.pm.PackageManager#getPackageInfo(String,int)
+getPackageInfo}(name,0);
+} catch (NameNotFoundException nnfe) {
+ info = null;
+}
+
+int version;
+if (info != null) {
+ version = info.versionCode;
+}
+
+
+Then simply compare the {@code version} acquired from {@link android.content.pm.PackageInfo} +to the {@code appVersionCode} passed into {@link +android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) onRestore()}. +
+ +Caution: Be certain you understand the consequences of setting +{@code +android:restoreAnyVersion} to "{@code true}" for your application. If each version of your +application that supports backup does not properly account for variations in your data format during +{@link +android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) onRestore()}, +then the data on the device could be saved in a format incompatible with the version currently +installed on the device.
+ + + +You can request a backup operation at any time by calling {@link +android.app.backup.BackupManager#dataChanged()}. This method notifies the Backup Manager that you'd +like to backup your data using your backup agent. The Backup Manager then calls your backup +agent's {@link +android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) +onBackup()} method at an opportune time in the future. Typically, you should +request a backup each time your data changes (such as when the user changes an application +preference that you'd like to back up). If you call {@link +android.app.backup.BackupManager#dataChanged()} several times consecutively, before the Backup +Manager requests a backup from your agent, your agent still receives just one call to {@link +android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor) +onBackup()}.
+ +Note: While developing your application, you can request a +backup and initiate an immediate backup operation with the {@code bmgr} +tool.
+ + +During the normal life of your application, you shouldn't need to request a restore operation. +They system automatically checks for backup data and performs a restore when your application is +installed. However, you can manually request a restore operation by calling {@link +android.app.backup.BackupManager#requestRestore(RestoreObserver) requestRestore()}, if necessary. In +which case, the Backup Manager calls your {@link +android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) onRestore()} +implementation, passing the data from the current set of backup data.
+ +Note: While developing your application, you can request a +restore operation with the {@code bmgr} +tool.
+ + +You can transition your app to full-data backups by setting android:fullBackupOnly to true in the <application> element in the manifest file. When
+running on a device with Android 5.1 (API level 22) or lower, your app ignores
+this value in the manifest, and continues performing Key/Value Backups. When
+running on a device with Android 6.0 (API level 23) or higher, your app performs
+Auto Backup instead of Key/Value Backup.
\ No newline at end of file
diff --git a/docs/html/guide/topics/data/testingbackup.jd b/docs/html/guide/topics/data/testingbackup.jd
new file mode 100644
index 000000000000..6ff5837e2411
--- /dev/null
+++ b/docs/html/guide/topics/data/testingbackup.jd
@@ -0,0 +1,181 @@
+page.title=Testing Backup and Restore
+page.tags=backup, marshmallow, androidm
+page.keywords=backup, restore, testing
+
+@jd:body
+
+
This page shows you how to manually trigger Auto Backup, Key/Value Backup, and restore operations to +ensure your app saves and restores data properly. + +
The section describes various pieces in the Android backup framework and how they +interact with apps that support Auto Backup and Key/Value Backup. During the app +development phase, most of the inner working of the framework were abstracted away, so you didn't need to know this information. However, during the +testing phase, an understanding of these concepts is important. + +
The following diagram illustrates how data flows during backup and restore:
+
+
+
+
The Backup Manager Service is an Android system +service which orchestrates and initiates backup and restore operations. The service +is accessible through the {@link android.app.backup.BackupManager} +API. During a backup operation, the service queries your app for backup data, +then hands it to the backup transport, which then archives the data. +During a restore operation, the backup manager service retrieves the backup data +from the backup transport and restores the data to the device. + +
Backup Transports are Android components that are responsible +for storing and retrieving backups. An Android device can have zero or more +backup transports, but only one of those transports can be marked active. The +available backup transports may differ from device to device (due to +customizations by device manufacturers and service providers), but most Google +Play enabled devices ship with the following transports: +
If a device does not have any backup transports, then the data cannot be +backed up. Your app is not adversely affected. + +
Caution: Because the backup transport +can differ from device to device, Android cannot guarantee the security +of your data while using backup. Be cautious about using backup to store +sensitive data, such as usernames and passwords. + +
You need to know a bit about the following tools: + +
Prepare your device or emulator for backup testing by working through the +following checklist: +
bmgr enableOn physical devices, backup and restore is typically enabled during the +initial setup wizard. Emulators do not run the setup wizard, so don't forget to +enable backup and specify a backup account in device settings. +
$ bmgr list transports+
Then, check the console for the following output: +
android/com.android.internal.backup.LocalTransport +* com.google.android.gms/.backup.BackupTransportService+
Physical devices without Google Play and emulators without Google APIs +might not include the GMS Backup Transport. This article assumes you are using +the GMS Backup Transport. You can test backup and restore with other backup +transports, but the procedure and output can differ. +
To initiate a backup of your app, run the following command: + +
$ bmgr backupnow <PACKAGE>+ +
The backupnow command runs either a Key/Value Backup or Auto Backup depending on
+the package's manifest declarations. Check logcat to see the output of the
+backup procedure. For example:
+
+
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>}
+
+
+If the backupnow command is not available on your device, you need to run one
+of the following commands:
+
bmgr fullbackup <PACKAGE>
+ $ bmgr backup <PACKAGE> +$ bmgr run+
bmgr backup adds your app to the Backup Manager's queue. bmgr run initiates the
+backup operation, which forces the Backup Manager to perform all backup requests
+that are in its queue.
+
To manually initiate a restore, run the following command: + +
$ bmgr restore <PACKAGE>+ +
Warning: This action stops your app and wipes its data before performing the +restore operation. + +
Then, check logcat to see the output of the restore procedure. For example: + +
V/BackupManagerService: beginRestoreSession: pkg=<PACKAGE> transport=null +V/RestoreSession: restorePackage pkg=<PACKAGE> token=368abb4465c5c683 +... +I/BackupManagerService: Restore complete. ++ +
You also can test automatic restore for your app by uninstalling and
+reinstalling your app either with adb or through the Google
+Play Store app.
+
+
Exceeded Quota + +
If you see the the following messages in logcat: + +
I/PFTBT: Transport rejected backup of <PACKAGE>, skipping + +--- or --- + +I/PFTBT: Transport quota exceeded for package: <PACKAGE> ++ +
Your app has exceeded the quota and has been banned from backing up +data on this device. To lift the ban, either factory reset your device or change +the backup account. + +
Full Backup Not Possible + +
If you see the the following message in logcat: + +
I/BackupManagerService: Full backup not currently possible -- key/value backup not yet run? ++ +
The fullbackup operation failed because no Key/Value Backup operation has yet
+occurred on the device. Trigger a Key/Value Backup with the command bmgr
+run and then try again.
\ No newline at end of file
diff --git a/docs/html/training/_book.yaml b/docs/html/training/_book.yaml
index e9635be74ec3..b965e6252c09 100644
--- a/docs/html/training/_book.yaml
+++ b/docs/html/training/_book.yaml
@@ -438,16 +438,6 @@ toc:
path: /training/efficient-downloads/redundant_redundant.html
- title: Modifying Patterns Based on the Connectivity Type
path: /training/efficient-downloads/connectivity_patterns.html
- - title: Backing up App Data to the Cloud
- path: /training/backup/index.html
- path_attributes:
- - name: description
- value: How to sync and back up app and user data to remote web services in the cloud and how to restore the data back to multiple devices.
- section:
- - title: Configuring Auto Backup
- path: /training/backup/autosyncapi.html
- - title: Using the Backup API
- path: /training/backup/backupapi.html
- title: Resolving Cloud Save Conflicts
path: /training/cloudsave/conflict-res.html
path_attributes:
@@ -1156,7 +1146,7 @@ toc:
value: 维护兼容性
- name: zh-tw-lang
value: 維持相容性
- - title: Selecting Colors with the Palette API
+ - title: Selecting Colors with the Palette API
path: /training/material/palette-colors.html
- title: Best Practices for User Input
diff --git a/docs/html/training/backup/autosyncapi.jd b/docs/html/training/backup/autosyncapi.jd
deleted file mode 100644
index e0df7bb658ae..000000000000
--- a/docs/html/training/backup/autosyncapi.jd
+++ /dev/null
@@ -1,370 +0,0 @@
-page.title=Configuring Auto Backup for Apps
-page.tags=backup, marshmallow, androidm
-page.keywords=backup, autobackup
-page.image=images/cards/card-auto-backup_2x.png
-
-@jd:body
-
-
- Users frequently invest time and effort to configure apps just the way they like them. Switching - to a new device can cancel out all that careful configuration. For apps whose target SDK version - is Android 6.0 (API level 23) and higher, devices running Android 6.0 and higher automatically - back up app data to the cloud. The system performs this automatic backup - for nearly all app data by default, and does so without your having to write any additional app - code. -
- --Note: To protect user privacy, the device user must have opted in to Google -services for Auto Backup to work. The Google services opt-in dialog appears when the user goes -through the Setup Wizard or configures the first Google account on the device. -
- -- When a user installs your app on - a new device, or reinstalls your app on one (for example, after a factory reset), the system - automatically restores the app data from the cloud. This lesson provides information about how to - configure the Auto Backup for Apps feature, explaining its default behavior and how to - exclude data that you don't want the system to back up. -
- -- The automatic backup feature preserves the data your app creates on a user device by uploading it - to the user’s Google Drive account and encrypting it. There is no charge to you or the user for - data storage, and the saved data does not count towards the user's personal Google Drive quota. - Each app can store up to 25MB. Once its backed-up data reaches 25MB, the app no longer sends - data to the cloud. If the system performs a data restore, it uses the last data snapshot that - the app had sent to the cloud. -
- -Automatic backups occur when the following conditions are met:
-- On devices running Android 6.0 (API level 23) or higher, the default system behavior is to back up - almost all data that an app creates. The exception is - automatically excluded data files. This section explains how you can use settings in - your app manifest to further - limit and configure what data the system backs up. -
- -- Depending on what data your app needs and how you save it, you may need to set specific - rules for including or excluding certain files or directories. Auto Backup for Apps - lets you set these backup rules through the app manifest, in which you specify a backup scheme - configuration XML file. For example: -
- --<?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="23"/> - <uses-sdk android:targetSdkVersion="23"/> - <application ... - android:fullBackupContent="@xml/mybackupscheme"> - </app> - ... -</manifest> -- -
- In this example, the android:fullBackupContent attribute specifies an XML file
- called {@code mybackupscheme.xml}, which resides in the res/xml/ directory of your
- app development project. This configuration file contains rules controlling which files are backed
- up. The following example code shows a configuration file that excludes a specific file,
- {@code device_info.db}:
-
-<?xml version="1.0" encoding="utf-8"?> -<full-backup-content> - <exclude domain="database" path="device_info.db"/> -</full-backup-content> -- -
- Most apps do not need to, and in fact should not, back up all data. For example, the system - should not back up temporary files and caches. For this reason, the automatic backup - service excludes certain data files by default: -
- -- The backup service configuration allows you to specify what files to include or exclude from - backup. The syntax for the data backup configuration XML file is as follows: -
- --<full-backup-content> - <include domain=["file" | "database" | "sharedpref" | "external" | "root"] - path="string" /> - <exclude domain=["file" | "database" | "sharedpref" | "external" | "root"] - path="string" /> -</full-backup-content> -- -
- The following elements and attributes allow you to specify the files to include in, and exclude - from, backup: -
- -<include>: Specifies a set of resources to
- back up, instead of having the system back up all data in your app by default. If you specify
- an <include> element, the system backs up only the resources specified
- with this element. You can specify multiple sets of resources to back up by using multiple
- <include> elements
- <exclude>: Specifies any data you want the system to exclude
- when it does a full backup. If you target the same set of resources with both the
- <include> and <exclude> elements,
- <exclude> takes precedence.
- domain: Specifies the type of resource you want to include in,
- or exclude from, backup. Valid values for this attribute include:
-
-
-
- root: Specifies that the resource is in the app’s root directory.
- file: Specifies a resource in the directory returned by the
- {@link android.content.Context#getFilesDir getFilesDir()} method.
- database: Specifies a database that the
- {@link android.content.Context#getDatabasePath getDatabasePath()} method returns, or that
- the app interacts with via the {@link android.database.sqlite.SQLiteOpenHelper} class.
- sharedpref: Specifies a {@link android.content.SharedPreferences} object
- that the {@link android.content.Context#getSharedPreferences getSharedPreferences()}
- method returns.
- external: Specifies that the resource is in external storage, and corresponds
- to a file in the directory that the
- {@link android.content.Context#getExternalFilesDir getExternalFilesDir()} method returns.
- path: Specifies the file path to a resource that you want to include in, or
- exclude from, backup.
-
- You can choose to prevent automatic backups of any of your app data by setting the
- android:allowBackup attribute to false in the {@code app} element of
- your manifest. This setting is illustrated in the following example:
-
-<?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="23"/> - <uses-sdk android:targetSdkVersion="23"/> - <application ... - android:allowBackup="false"> - </application> - ... -</manifest> -- -
There are two scenarios in which you may also need to support versions of Android lower -than 6.0 (API level 23): You may be updating your existing app to take advantage of the -new auto backup functionality in Android 6.0, while wanting -to continue supporting earlier versions of Android. Or you may be releasing a new app, but -want to make sure devices running on versions of Android predating 6.0 also have backup -functionality.
- -Earlier versions of Android supported a key/value-pair-based backup mechanism, in which the app
-defines a subclass of {@link android.app.backup.BackupAgent} and sets
-
-{@code android:backupAgent} in its
-app manifest. If your app
-used this legacy approach, you can transition to full-data backups by adding the
-{@code android:fullBackupOnly="true"} attribute to the
-{@code
Even if you’re not using key/value backups, you can still use the approach described above to do -any custom processing in {@link android.app.Activity#onCreate(android.os.Bundle) onCreate()} -or {@link android.app.backup.BackupAgent#onFullBackup onFullBackup()}. You can also use that -approach to receive a notification when a restore operation happens in -{@link android.app.backup.BackupAgent#onRestoreFinished onRestoreFinished()}. If you want to retain -the system's default implementation of -XML include/exclude rules handling, call -{@link android.app.backup.BackupAgent#onFullBackup super.onFullBackup()}.
- -If you are creating a new app that targets Android 6.0, but you also want to enable cloud backup -for devices running on Android 5.1 (API level 22) and lower, you must also -implement the Backup API.
- -- Once you have created a backup configuration, you should test it to make sure your app saves data - and can restore it properly. -
- - -- To help determine how the backup feature is parsing your XML file, enable logging before - performing a test backup: -
- --$ adb shell setprop log.tag.BackupXmlParserLogging VERBOSE -- -
To manually run a backup, first initialize the Backup Manager by executing the following - command: -
- --$ adb shell bmgr run -- -
- Next, manually back up your application using the following command. Use the
- <PACKAGE> parameter to specify the package name for your app:
-
-$ adb shell bmgr fullbackup <PACKAGE>- - -
- To manually initiate a restore after the system has backed up your app data, execute the following
- command, using the <PACKAGE> parameter to specify the package name for your
- app:
-
-$ adb shell bmgr restore <PACKAGE> -- -
- Warning: This action stops your app and wipes its data before performing the restore - operation. -
- -- You can test automatic restore for your app by uninstalling and reinstalling your app. The app - data is automatically restored from the cloud once the app installation is complete. -
- - -- If backup fails, you can clear the backup data and associated metadata either by turning backup - off and on in Settings > Backup, factory-resetting the device, or - executing this command: -
- -$ adb shell bmgr wipe <TRANSPORT> <PACKAGE>- -
- You must prepend com.google.android.gms to the {@code
$ adb shell bmgr list transports- -
- For apps that use Google Cloud - Messaging (GCM) for push notifications, backing up the registration - token that Google Cloud Messaging registration returned can cause unexpected behavior in - notifications for the restored app. This is because when a user installs your app on a new device, - the app must - query the GCM API for a new registration token. If the old registration is present, because the - system had backed it up and restored it, the app doesn't seek the new token. To prevent this issue - from arising, exclude the registration token from the set of backed-up files. -
diff --git a/docs/html/training/backup/backupapi.jd b/docs/html/training/backup/backupapi.jd deleted file mode 100644 index 2f3e93943f37..000000000000 --- a/docs/html/training/backup/backupapi.jd +++ /dev/null @@ -1,200 +0,0 @@ -page.title=Using the Backup API -parent.title=Backing up App Data to the Cloud -parent.link=index.html - -trainingnavtop=true - -next.title=Making the Most of Google Cloud Messaging -next.link=gcm.html - -@jd:body - -When a user purchases a new device or resets their existing one, they might -expect that when Google Play restores your app back to their device during the -initial setup, the previous data associated with the app restores as well. On versions of Android -prior to 6.0 (API level 23), app data is not restored by default, and all the user's accomplishments -or settings in your app are lost.
-For situations where the volume of data is relatively light (less than a -megabyte), like the user's preferences, notes, game high scores or other -stats, the Backup API provides a lightweight solution. This lesson walks you -through integrating the Backup API into your application, and restoring data to -new devices using the Backup API. - -
-Note: Devices running Android 6.0 and higher -automatically back up -nearly all data by default. -
- -This lesson requires the use of the Android Backup - Service, which requires registration. Go ahead and register here. Once -that's done, the service pre-populates an XML tag for insertion in your Android -Manifest, which looks like this:
--<meta-data android:name="com.google.android.backup.api_key" -android:value="ABcDe1FGHij2KlmN3oPQRs4TUvW5xYZ" /> --
Note that each backup key works with a specific package name. If you have -different applications, register separate keys for each one.
- - -Use of the Android Backup Service requires two additions to your application -manifest. First, declare the name of the class that acts as your backup agent, -then add the snippet above as a child element of the Application tag. Assuming -your backup agent is going to be called {@code TheBackupAgent}, here's an example of -what the manifest looks like with this tag included:
- --<application android:label="MyApp" - android:backupAgent="TheBackupAgent"> - ... - <meta-data android:name="com.google.android.backup.api_key" - android:value="ABcDe1FGHij2KlmN3oPQRs4TUvW5xYZ" /> - ... -</application> --
The easiest way to create your backup agent is by extending the wrapper class -{@link android.app.backup.BackupAgentHelper}. Creating this helper class is -actually a very simple process. Just create a class with the same name as you -used in the manifest in the previous step (in this example, {@code -TheBackupAgent}), -and extend {@code BackupAgentHelper}. Then override the {@link -android.app.backup.BackupAgent#onCreate()}.
- -Inside the {@link android.app.backup.BackupAgent#onCreate()} method, create a {@link -android.app.backup.BackupHelper}. These helpers are -specialized classes for backing up certain kinds of data. The Android framework -currently includes two such helpers: {@link -android.app.backup.FileBackupHelper} and {@link -android.app.backup.SharedPreferencesBackupHelper}. After you create the helper -and point it at the data you want to back up, just add it to the -BackupAgentHelper using the {@link android.app.backup.BackupAgentHelper#addHelper(String, BackupHelper) addHelper()} -method, adding a key which is used to -retrieve the data later. In most cases the entire -implementation is perhaps 10 lines of code.
- -Here's an example that backs up a high scores file.
- -
-import android.app.backup.BackupAgentHelper;
-import android.app.backup.FileBackupHelper;
-
-
-public class TheBackupAgent extends BackupAgentHelper {
- // The name of the SharedPreferences file
- static final String HIGH_SCORES_FILENAME = "scores";
-
- // A key to uniquely identify the set of backup data
- static final String FILES_BACKUP_KEY = "myfiles";
-
- // Allocate a helper and add it to the backup agent
- @Override
- void onCreate() {
- FileBackupHelper helper = new FileBackupHelper(this, HIGH_SCORES_FILENAME);
- addHelper(FILES_BACKUP_KEY, helper);
- }
-}
-
-For added flexibility, {@link android.app.backup.FileBackupHelper}'s -constructor can take a variable number of filenames. You could just as easily -have backed up both a high scores file and a game progress file just by adding -an extra parameter, like this:
-
-@Override
- void onCreate() {
- FileBackupHelper helper = new FileBackupHelper(this, HIGH_SCORES_FILENAME, PROGRESS_FILENAME);
- addHelper(FILES_BACKUP_KEY, helper);
- }
-
-Backing up preferences is similarly easy. Create a {@link -android.app.backup.SharedPreferencesBackupHelper} the same way you did a {@link -android.app.backup.FileBackupHelper}. In this case, instead of adding filenames -to the constructor, add the names of the shared preference groups being used by -your application. Here's an example of how your backup agent helper might look if -high scores are implemented as preferences instead of a flat file:
- -
-import android.app.backup.BackupAgentHelper;
-import android.app.backup.SharedPreferencesBackupHelper;
-
-public class TheBackupAgent extends BackupAgentHelper {
- // The names of the SharedPreferences groups that the application maintains. These
- // are the same strings that are passed to getSharedPreferences(String, int).
- static final String PREFS_DISPLAY = "displayprefs";
- static final String PREFS_SCORES = "highscores";
-
- // An arbitrary string used within the BackupAgentHelper implementation to
- // identify the SharedPreferencesBackupHelper's data.
- static final String MY_PREFS_BACKUP_KEY = "myprefs";
-
- // Simply allocate a helper and install it
- void onCreate() {
- SharedPreferencesBackupHelper helper =
- new SharedPreferencesBackupHelper(this, PREFS_DISPLAY, PREFS_SCORES);
- addHelper(MY_PREFS_BACKUP_KEY, helper);
- }
-}
-
-
-You can add as many backup helper instances to your backup agent helper as you -like, but remember that you only need one of each type. One {@link -android.app.backup.FileBackupHelper} handles all the files that you need to back up, and one -{@link android.app.backup.SharedPreferencesBackupHelper} handles all the shared -preferencegroups you need backed up. -
- - -In order to request a backup, just create an instance of the {@link -android.app.backup.BackupManager}, and call it's {@link -android.app.backup.BackupManager#dataChanged()} method.
- -
-import android.app.backup.BackupManager;
-...
-
-public void requestBackup() {
- BackupManager bm = new BackupManager(this);
- bm.dataChanged();
-}
-
-
-This call notifies the backup manager that there is data ready to be backed -up to the cloud. At some point in the future, the backup manager then calls -your backup agent's {@link -android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor, BackupDataOutput, -ParcelFileDescriptor) onBackup()} method. You can make -the call whenever your data has changed, without having to worry about causing -excessive network activity. If you request a backup twice before a backup -occurs, the backup only occurs once.
- - -Typically you shouldn't ever have to manually request a restore, as it -happens automatically when your application is installed on a device. However, -if it is necessary to trigger a manual restore, just call the -{@link android.app.backup.BackupManager#requestRestore(RestoreObserver) requestRestore()} method.
diff --git a/docs/html/training/backup/index.jd b/docs/html/training/backup/index.jd deleted file mode 100644 index 4449fde1d5c3..000000000000 --- a/docs/html/training/backup/index.jd +++ /dev/null @@ -1,47 +0,0 @@ -page.title=Backing up App Data to the Cloud -page.tags=cloud,sync,backup - -trainingnavtop=true -startpage=true - -@jd:body - -Users often invest significant time and effort creating data and setting -preferences within apps. Preserving that data for users if they replace a broken -device or upgrade to a new one is an important part of ensuring a great user -experience.
- -This class covers techniques for backing up data to the cloud so that -users can restore their data when recovering from a data loss (such as a factory -reset) or installing your application on a new device.
- -It is important to note that the API for cloud backup changed with the -release of Android 6.0 (API level 23). For your app to support backup both -on devices running Android 6.0, and those running Android 5.1 (API level -22) and lower, you must implement both techniques that this class explains.
- -