Home | History | Annotate | Download | only in data
      1 page.title=Data Backup
      2 @jd:body
      3 
      4 
      5 <div id="qv-wrapper">
      6 <div id="qv">
      7 
      8   <h2>Quickview</h2>
      9   <ul>
     10     <li>Back up your data to the cloud in case the user looses it</li>
     11     <li>Easily back up SharedPreferences and private files with BackupAgentHelper</li>
     12     <li>Requires API Level 8</li>
     13   </ul>
     14 
     15   <h2>In this document</h2>
     16   <ol>
     17     <li><a href="#Basics">The Basics</a></li>
     18     <li><a href="#BackupManifest">Declaring the Backup Agent in Your Manifest</a></li>
     19     <li><a href="#BackupKey">Registering for Android Backup Service</a></li>
     20     <li><a href="#BackupAgent">Extending BackupAgent</a>
     21       <ol>
     22         <li><a href="#RequiredMethods">Required Methods</a></li>
     23         <li><a href="#PerformingBackup">Performing backup</a></li>
     24         <li><a href="#PerformingRestore">Performing restore</a></li>
     25       </ol>
     26     </li>
     27     <li><a href="#BackupAgentHelper">Extending BackupAgentHelper</a>
     28       <ol>
     29         <li><a href="#SharedPreferences">Backing up SharedPreferences</a></li>
     30         <li><a href="#Files">Backing up Private Files</a></li>
     31       </ol>
     32     </li>
     33     <li><a href="#RestoreVersion">Checking the Restore Data Version</a></li>
     34     <li><a href="#RequestingBackup">Requesting Backup</a></li>
     35     <li><a href="#RequestingRestore">Requesting Restore</a></li>
     36     <li><a href="#Testing">Testing Your Backup Agent</a></li>
     37   </ol>
     38 
     39   <h2>Key classes</h2>
     40   <ol>
     41     <li>{@link android.app.backup.BackupManager}</li>
     42     <li>{@link android.app.backup.BackupAgent}</li>
     43     <li>{@link android.app.backup.BackupAgentHelper}</li>
     44   </ol>
     45 
     46   <h2>See also</h2>
     47   <ol>
     48     <li><a href="{@docRoot}guide/developing/tools/bmgr.html">{@code bmgr} tool</a></li>
     49   </ol>
     50 
     51 </div>
     52 </div>
     53 
     54 <p>Android's {@link android.app.backup backup} service allows you to copy your persistent
     55 application data to remote "cloud" storage, in order to provide a restore point for the
     56 application data and settings. If a user performs a factory reset or converts to a new
     57 Android-powered device, the system automatically restores your backup data when the application
     58 is re-installed. This way, your users don't need to reproduce their previous data or
     59 application settings. This process is completely transparent to the user and does not affect the
     60 functionality or user experience in your application.</p>
     61 
     62 <p>During a backup operation (which your application can request), Android's Backup Manager ({@link
     63 android.app.backup.BackupManager}) queries your application for backup data, then hands it to
     64 a backup transport, which then delivers the data to the cloud storage. During a
     65 restore operation, the Backup Manager retrieves the backup data from the backup transport and
     66 returns it to your application so your application can restore the data to the device. It's
     67 possible for your application to request a restore, but that shouldn't be necessary&mdash;Android
     68 automatically performs a restore operation when your application is installed and there exists
     69 backup data associated with the user. The primary scenario in which backup data is restored is when
     70 a user resets their device or upgrades to a new device and their previously installed
     71 applications are re-installed.</p>
     72 
     73 <p class="note"><strong>Note:</strong> The backup service is <em>not</em> designed for
     74 synchronizing application data with other clients or saving data that you'd like to access during
     75 the normal application lifecycle. You cannot read or write backup data on demand and cannot access
     76 it in any way other than through the APIs provided by the Backup Manager.</p>
     77 
     78 <p>The backup transport is the client-side component of Android's backup framework, which is
     79 customizable by
     80 the device manufacturer and service provider. The backup transport may differ from device to device
     81 and which backup transport is available on any given device is transparent to your application. The
     82 Backup Manager APIs isolate your application from the actual backup transport available on a given
     83 device&mdash;your application communicates with the Backup Manager through a fixed set of APIs,
     84 regardless of the underlying transport.</p>
     85 
     86 <p>Data backup is <em>not</em> guaranteed to be available on all Android-powered
     87 devices. However, your application is not adversely affected in the event
     88 that a device does not provide a backup transport. If you believe that users will benefit from data
     89 backup in your application, then you can implement it as described in this document, test it, then
     90 publish your application without any concern about which devices actually perform backup. When your
     91 application runs on a device that does not provide a backup transport, your application operates
     92 normally, but will not receive callbacks from the Backup Manager to backup data.</p>
     93 
     94 <p>Although you cannot know what the current transport is, you are always assured that your
     95 backup data cannot be read by other applications on the device. Only the Backup Manager and backup
     96 transport have access to the data you provide during a backup operation.</p>
     97 
     98 <p class="caution"><strong>Caution:</strong> Because the cloud storage and transport service can
     99 differ from device to device, Android makes no guarantees about the security of your data while
    100 using backup. You should always be cautious about using backup to store sensitive data, such as
    101 usernames and passwords.</p>
    102 
    103 
    104 <h2 id="Basics">The Basics</h2>
    105 
    106 <p>To backup your application data, you need to implement a backup agent. Your backup
    107 agent is called by the Backup Manager to provide the data you want to back up. It is also called
    108 to restore your backup data when the application is re-installed. The Backup Manager handles all
    109 your data transactions with the cloud storage (using the backup transport) and your backup agent
    110 handles all your data transactions on the device.</p>
    111 
    112 <p>To implement a backup agent, you must:</p>
    113 
    114 <ol>
    115   <li>Declare your backup agent in your manifest file with the <a
    116 href="{@docRoot}guide/topics/manifest/application-element.html#agent">{@code
    117 android:backupAgent}</a> attribute.</li>
    118   <li>Register your application with a backup service. Google offers <a
    119 href="http://code.google.com/android/backup/index.html">Android Backup Service</a> as a backup
    120 service for most Android-powered devices, which requires that you register your application in
    121 order for it to work. Any other backup services available might also require you to register
    122 in order to store your data on their servers.</li>
    123   <li>Define a backup agent by either:</p>
    124     <ol type="a">
    125       <li><a href="#backupAgent">Extending BackupAgent</a>
    126         <p>The {@link android.app.backup.BackupAgent} class provides the central interface with
    127 which your application communicates with the Backup Manager. If you extend this class
    128 directly, you must override {@link
    129 android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
    130 onBackup()} and {@link
    131 android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor)
    132 onRestore()} to handle the backup and restore operations for your data.</p>
    133         <p><em>Or</em></p>
    134       <li><a href="#backupAgentHelper">Extending BackupAgentHelper</a>
    135         <p>The {@link android.app.backup.BackupAgentHelper} class provides a convenient
    136 wrapper around the {@link android.app.backup.BackupAgent} class, which minimizes the amount of code
    137 you need to write. In your {@link android.app.backup.BackupAgentHelper}, you must use one or more
    138 "helper" objects, which automatically backup and restore certain types of data, so that you do not
    139 need to implement {@link
    140 android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
    141 onBackup()} and {@link
    142 android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor)
    143 onRestore()}.</p>
    144         <p>Android currently provides backup helpers that will backup and restore complete files
    145 from {@link android.content.SharedPreferences} and <a
    146 href="{@docRoot}guide/topics/data/data-storage.html#filesInternal">internal storage</a>.</p>
    147       </li>
    148     </ol>
    149   </li>
    150 </ol>
    151 
    152 
    153 
    154 <h2 id="BackupManifest">Declaring the Backup Agent in Your Manifest</h2>
    155 
    156 <p>This is the easiest step, so once you've decided on the class name for your backup agent, declare
    157 it in your manifest with the <a
    158 href="{@docRoot}guide/topics/manifest/application-element.html#agent">{@code
    159 android:backupAgent}</a> attribute in the <a
    160 href="{@docRoot}guide/topics/manifest/application-element.html">{@code
    161 &lt;application&gt;}</a> tag.</p>
    162 
    163 <p>For example:</p>
    164 
    165 <pre>
    166 &lt;manifest ... &gt;
    167     &lt;application android:label="MyApplication"
    168                  <b>android:backupAgent="MyBackupAgent"</b>&gt;
    169         &lt;activity ... &gt;
    170             ...
    171         &lt;/activity&gt;
    172     &lt;/application&gt;
    173 &lt;/manifest&gt;
    174 </pre>
    175 
    176 <p>Another attribute you might want to use is <a
    177 href="{@docRoot}guide/topics/manifest/application-element.html#restoreany">{@code
    178 android:restoreAnyVersion}</a>. This attribute takes a boolean value to indicate whether you
    179 want to restore the application data regardless of the current application version compared to the
    180 version that produced the backup data. (The default value is "{@code false}".) See <a
    181 href="#RestoreVersion">Checking the Restore Data Version</a> for more information.</p>
    182 
    183 <p class="note"><strong>Note:</strong> The backup service and the APIs you must use are
    184 available only on devices running API Level 8 (Android 2.2) or greater, so you should also
    185 set your <a
    186 href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code android:minSdkVersion}</a>
    187 attribute to "8". However, if you implement proper <a
    188 href="{@docRoot}resources/articles/backward-compatibility.html">backward compatibility</a> in
    189 your application, you can support this feature for devices running API Level 8 or greater, while
    190 remaining compatible with older devices.</p>
    191 
    192 
    193 
    194 
    195 <h2 id="BackupKey">Registering for Android Backup Service</h2>
    196 
    197 <p>Google provides a backup transport with <a
    198 href="http://code.google.com/android/backup/index.html">Android Backup Service</a> for most
    199 Android-powered devices running Android 2.2 or greater.</p>
    200 
    201 <p>In order for you application to perform backup using Android Backup Service, you must
    202 register your application with the service to receive a Backup Service Key, then
    203 declare the Backup Service Key in your Android manifest.</p>
    204 
    205 <p>To get your Backup Service Key, <a
    206 href="http://code.google.com/android/backup/signup.html">register for Android Backup Service</a>.
    207 When you register, you will be provided a Backup Service Key and the appropriate {@code
    208 &lt;meta-data&gt;} XML code for your Android manifest file, which you must include as a child of the
    209 {@code &lt;application&gt;} element. For example:</p>
    210 
    211 <pre>
    212 &lt;application android:label="MyApplication"
    213              android:backupAgent="MyBackupAgent"&gt;
    214     ...
    215     &lt;meta-data android:name="com.google.android.backup.api_key"
    216         android:value="AEdPqrEAAAAIDaYEVgU6DJnyJdBmU7KLH3kszDXLv_4DIsEIyQ" /&gt;
    217 &lt;/application&gt;
    218 </pre>
    219 
    220 <p>The <code>android:name</code> must be <code>"com.google.android.backup.api_key"</code> and
    221 the <code>android:value</code> must be the Backup Service Key received from the Android Backup
    222 Service registration.</p>
    223 
    224 <p>If you have multiple applications, you must register each one, using the respective package
    225 name.</p>
    226 
    227 <p class="note"><strong>Note:</strong> The backup transport provided by Android Backup Service is
    228 not guaranteed to be available
    229 on all Android-powered devices that support backup. Some devices might support backup
    230 using a different transport, some devices might not support backup at all, and there is no way for
    231 your application to know what transport is used on the device. However, if you implement backup for
    232 your application, you should always include a Backup Service Key for Android Backup Service so
    233 your application can perform backup when the device uses the Android Backup Service transport. If
    234 the device does not use Android Backup Service, then the {@code &lt;meta-data&gt;} element with the
    235 Backup Service Key is ignored.</p>
    236 
    237 
    238 
    239 
    240 <h2 id="BackupAgent">Extending BackupAgent</h2>
    241 
    242 <p>Most applications shouldn't need to extend the {@link android.app.backup.BackupAgent} class
    243 directly, but should instead <a href="#BackupAgentHelper">extend BackupAgentHelper</a> to take
    244 advantage of the built-in helper classes that automatically backup and restore your files. However,
    245 you might want to extend {@link android.app.backup.BackupAgent} directly if you need to:</p>
    246 <ul>
    247   <li>Version your data format. For instance, if you anticipate the need to revise the
    248 format in which you write your application data, you can build a backup agent to cross-check your
    249 application version during a restore operation and perform any necessary compatibility work if the
    250 version on the device is different than that of the backup data. For more information, see <a
    251 href="#RestoreVersion">Checking the Restore Data Version</a>.</li>
    252   <li>Instead of backing up an entire file, you can specify the portions of data the should be
    253 backed up and how each portion is then restored to the device. (This can also help you manage
    254 different versions, because you read and write your data as unique entities, rather than
    255 complete files.)</li>
    256   <li>Back up data in a database. If you have an SQLite database that you want to restore when
    257 the user re-installs your application, you need to build a custom {@link
    258 android.app.backup.BackupAgent} that reads the appropriate data during a backup operation, then
    259 create your table and insert the data during a restore operation.</li>
    260 </ul>
    261 
    262 <p>If you don't need to perform any of the tasks above and want to back up complete files from
    263 {@link android.content.SharedPreferences} or <a
    264 href="{@docRoot}guide/topics/data/data-storage.html#filesInternal">internal storage</a>, you
    265 should skip to <a href="#BackupAgentHelper">Extending BackupAgentHelper</a>.</p>
    266 
    267 
    268 
    269 <h3 id="RequiredMethods">Required Methods</h3>
    270 
    271 <p>When you create a backup agent by extending {@link android.app.backup.BackupAgent}, you
    272 must implement the following callback methods:</p>
    273 
    274 <dl>
    275   <dt>{@link
    276 android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
    277 onBackup()}</dt>
    278     <dd>The Backup Manager calls this method after you <a href="#RequestBackup">request a
    279 backup</a>. In this method, you read your application data from the device and pass the data you
    280 want to back up to the Backup Manager, as described below in <a href="#PerformingBackup">Performing
    281 backup</a>.</dd>
    282 
    283   <dt>{@link
    284 android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor)
    285 onRestore()}</dt>
    286     <dd>The Backup Manager calls this method during a restore operation (you can <a
    287 href="#RequestRestore">request a restore</a>, but the system automatically performs restore when the
    288 user re-installs your application). When it calls this method, the Backup Manager delivers your
    289 backup data, which you then restore to the device, as described below in <a
    290 href="#PerformingRestore">Performing restore</a>.</dd>
    291 </dl>
    292 
    293 
    294 
    295 <h3 id="PerformingBackup">Performing backup</h3>
    296 
    297 
    298 <p>When it's time to back up your application data, the Backup Manager calls your {@link
    299 android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
    300 onBackup()} method. This is where you must provide your application data to the Backup Manager so
    301 it can be saved to cloud storage.</p>
    302 
    303 <p>Only the Backup Manager can call your backup agent's {@link
    304 android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
    305 onBackup()} method. Each time that your application data changes and you want to perform a backup,
    306 you must request a backup operation by calling {@link
    307 android.app.backup.BackupManager#dataChanged()} (see <a href="#RequestingBackup">Requesting
    308 Backup</a> for more information). A backup request does not result in an immediate call to your
    309 {@link
    310 android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
    311 onBackup()} method. Instead, the Backup Manager waits for an appropriate time, then performs
    312 backup for all applications that have requested a backup since the last backup was performed.</p>
    313 
    314 <p class="note"><strong>Tip:</strong> While developing your application, you can initiate an
    315 immediate backup operation from the Backup Manager with the <a
    316 href="{@docRoot}guide/developing/tools/bmgr.html">{@code bmgr} tool</a>.</p>
    317 
    318 <p>When the Backup Manager calls your {@link
    319 android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
    320 onBackup()} method, it passes three parameters:</p>
    321 
    322 <dl>
    323   <dt>{@code oldState}</dt>
    324     <dd>An open, read-only {@link android.os.ParcelFileDescriptor} pointing to the last backup
    325 state provided by your application. This is not the backup data from cloud storage, but a
    326 local representation of the data that was backed up the last time {@link
    327 android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
    328 onBackup()} was called (as defined by {@code newState}, below, or from {@link
    329 android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor)
    330 onRestore()}&mdash;more about this in the next section). Because {@link
    331 android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
    332 onBackup()} does not allow you to read existing backup data in
    333 the cloud storage, you can use this local representation to determine whether your data has changed
    334 since the last backup.</dd>
    335   <dt>{@code data}</dt>
    336     <dd>A {@link android.app.backup.BackupDataOutput} object, which you use to deliver your backup
    337 data to the Backup Manager.</dd>
    338   <dt>{@code newState}</dt>
    339     <dd>An open, read/write {@link android.os.ParcelFileDescriptor} pointing to a file in which
    340 you must write a representation of the data that you delivered to {@code data} (a representation
    341 can be as simple as the last-modified timestamp for your file). This object is
    342 returned as {@code oldState} the next time the Backup Manager calls your {@link
    343 android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
    344 onBackup()} method. If you do not write your backup data to {@code newState}, then {@code oldState}
    345 will point to an empty file next time Backup Manager calls {@link
    346 android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
    347 onBackup()}.</dd>
    348 </dl>
    349 
    350 <p>Using these parameters, you should implement your {@link
    351 android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
    352 onBackup()} method to do the following:</p>
    353 
    354 <ol>
    355   <li>Check whether your data has changed since the last backup by comparing {@code oldState} to
    356 your current data. How you read data in {@code oldState} depends on how you originally wrote it to
    357 {@code newState} (see step 3). The easiest way to record the state of a file is with its
    358 last-modified timestamp. For example, here's how you can read and compare a timestamp from {@code
    359 oldState}:
    360     <pre>
    361 // Get the oldState input stream
    362 FileInputStream instream = new FileInputStream(oldState.getFileDescriptor());
    363 DataInputStream in = new DataInputStream(instream);
    364 
    365 try {
    366     // Get the last modified timestamp from the state file and data file
    367     long stateModified = in.readLong();
    368     long fileModified = mDataFile.lastModified();
    369 
    370     if (stateModified != fileModified) {
    371         // The file has been modified, so do a backup
    372         // Or the time on the device changed, so be safe and do a backup
    373     } else {
    374         // Don't back up because the file hasn't changed
    375         return;
    376     }
    377 } catch (IOException e) {
    378     // Unable to read state file... be safe and do a backup
    379 }
    380 </pre>
    381     <p>If nothing has changed and you don't need to back up, skip to step 3.</p>
    382   </li>
    383   <li>If your data has changed, compared to {@code oldState}, write the current data to
    384 {@code data} to back it up to the cloud storage.
    385     <p>You must write each chunk of data as an "entity" in the {@link
    386 android.app.backup.BackupDataOutput}. An entity is a flattened binary data
    387 record that is identified by a unique key string. Thus, the data set that you back up is
    388 conceptually a set of key-value pairs.</p>
    389     <p>To add an entity to your backup data set, you must:</p>
    390     <ol>
    391       <li>Call {@link android.app.backup.BackupDataOutput#writeEntityHeader(String,int)
    392 writeEntityheader()}, passing a unique string key for the data you're about to write and the data
    393 size.</li>
    394       <li>Call {@link android.app.backup.BackupDataOutput#writeEntityData(byte[],int)
    395 writeEntityData()}, passing a byte buffer that contains your data and the number of bytes to write
    396 from the buffer (which should match the size passed to {@link
    397 android.app.backup.BackupDataOutput#writeEntityHeader(String,int) writeEntityHeader()}).</li>
    398     </ol>
    399     <p>For example, the following code flattens some data into a byte stream and writes it into a
    400 single entity:</p>
    401     <pre>
    402 // Create buffer stream and data output stream for our data
    403 ByteArrayOutputStream bufStream = new ByteArrayOutputStream();
    404 DataOutputStream outWriter = new DataOutputStream(bufStream);
    405 // Write structured data
    406 outWriter.writeString(playerName);
    407 outWriter.writeInt(playerScore);
    408 // Send the data to the Backup Manager via the BackupDataOutput
    409 byte[] buffer = bufStream.toByteArray();
    410 int len = buffer.length;
    411 data.writeEntityHeader(TOPSCORE_BACKUP_KEY, len);
    412 data.writeEntityData(buffer, len);
    413 </pre>
    414     <p>Perform this for each piece of data that you want to back up. How you divide your data into
    415 entities is up to you (and you might use just one entity).</p>
    416   </li>
    417   <li>Whether or not you perform a backup (in step 2), write a representation of the current data to
    418 the {@code newState} {@link android.os.ParcelFileDescriptor}. The Backup Manager retains this object
    419 locally as a representation of the data that is currently backed up. It passes this back to you as
    420 {@code oldState} the next time it calls {@link
    421 android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
    422 onBackup()} so you can determine whether another backup is necessary (as handled in step 1). If you
    423 do not write the current data state to this file, then
    424 {@code oldState} will be empty during the next callback.
    425     <p>Again, the following example saves a representation of the data using the file's
    426 last-modified timestamp:</p>
    427     <pre>
    428 FileOutputStream outstream = new FileOutputStream(stateFile.getFileDescriptor());
    429 DataOutputStream out = new DataOutputStream(outstream);
    430 
    431 long modified = mDataFile.lastModified();
    432 out.writeLong(modified);
    433 </pre>
    434   </li>
    435 </ol>
    436 
    437 <p class="caution"><strong>Caution:</strong> If your application data is saved to a file, make sure
    438 that you use synchronized statements while accessing the file so that your backup agent does not
    439 read the file while an Activity in your application is also writing the file.</p>
    440 
    441 
    442 
    443 
    444 <h3 id="PerformingRestore">Performing restore</h3>
    445 
    446 <p>When it's time to restore your application data, the Backup Manager calls your backup
    447 agent's {@link android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor)
    448 onRestore()} method. When it calls this method, the Backup Manager delivers your backup data so
    449 you can restore it onto the device.</p>
    450 
    451 <p>Only the Backup Manager can call {@link
    452 android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor)
    453 onRestore()}, which happens automatically when the system installs your application and
    454 finds existing backup data. However, you can request a restore operation for
    455 your application by calling {@link
    456 android.app.backup.BackupManager#requestRestore(RestoreObserver) requestRestore()} (see <a
    457 href="#RequestingRestore">Requesting restore</a> for more information).</p>
    458 
    459 <p class="note"><strong>Note:</strong> While developing your application, you can also request a
    460 restore operation with the <a href="{@docRoot}guide/developing/tools/bmgr.html">{@code bmgr}
    461 tool</a>.</p>
    462 
    463 <p>When the Backup Manager calls your {@link
    464 android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor)
    465 onRestore()} method, it passes three parameters:</p>
    466 
    467 <dl>
    468   <dt>{@code data}</dt>
    469     <dd>A {@link android.app.backup.BackupDataInput}, which allows you to read your backup
    470 data.</dd>
    471   <dt>{@code appVersionCode}</dt>
    472     <dd>An integer representing the value of your application's <a
    473 href="{@docRoot}guide/topics/manifest/manifest-element.html#vcode">{@code android:versionCode}</a>
    474 manifest attribute, as it was when this data was backed up. You can use this to cross-check the
    475 current application version and determine if the data format is compatible. For more
    476 information about using this to handle different versions of restore data, see the section
    477 below about <a href="#RestoreVersion">Checking the Restore Data Version</a>.</dd>
    478   <dt>{@code newState}</dt>
    479     <dd>An open, read/write {@link android.os.ParcelFileDescriptor} pointing to a file in which
    480 you must write the final backup state that was provided with {@code data}. This object is
    481 returned as {@code oldState} the next time {@link
    482 android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
    483 onBackup()} is called. Recall that you must also write the same {@code newState} object in the
    484 {@link
    485 android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
    486 onBackup()} callback&mdash;also doing it here ensures that the {@code oldState} object given to
    487 {@link
    488 android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
    489 onBackup()} is valid even the first time {@link
    490 android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
    491 onBackup()} is called after the device is restored.</dd>
    492 </dl>
    493 
    494 <p>In your implementation of {@link
    495 android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor)
    496 onRestore()}, you should call {@link android.app.backup.BackupDataInput#readNextHeader()} to iterate
    497 through all entities in the data set. For each entity found, do the following:</p>
    498 
    499 <ol>
    500   <li>Get the entity key with {@link android.app.backup.BackupDataInput#getKey()}.</li>
    501   <li>Compare the entity key to a list of known key values that you should have declared as static
    502 final strings inside your {@link android.app.backup.BackupAgent} class. When the key matches one of
    503 your known key strings, enter into a statement to extract the entity data and save it to the device:
    504     <ol>
    505       <li>Get the entity data size with {@link
    506 android.app.backup.BackupDataInput#getDataSize()} and create a byte array of that size.</li>
    507       <li>Call {@link android.app.backup.BackupDataInput#readEntityData(byte[],int,int)
    508 readEntityData()} and pass it the byte array, which is where the data will go, and specify the
    509 start offset and the size to read.</li>
    510       <li>Your byte array is now full and you can read the data and write it to the device
    511 however you like.</li>
    512     </ol>
    513   </li>
    514   <li>After you read and write your data back to the device, write the state of your data to the
    515 {@code newState} parameter the same as you do during {@link
    516 android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
    517 onBackup()}.
    518 </ol>
    519 
    520 <div class="special">
    521 <p>For an example implementation of {@link android.app.backup.BackupAgent}, see the <a
    522 href="{@docRoot}resources/samples/BackupRestore/src/com/example/android/backuprestore/ExampleAgent.html">{@code
    523 ExampleAgent}</a> class in the <a
    524 href="{@docRoot}resources/samples/BackupRestore/index.html">Backup and Restore</a> sample
    525 application.</p>
    526 </div>
    527 
    528 
    529 
    530 
    531 
    532 
    533 <h2 id="BackupAgentHelper">Extending BackupAgentHelper</h2>
    534 
    535 <p>You should build your backup agent using {@link android.app.backup.BackupAgentHelper} if you want
    536 to back up complete files (from either {@link android.content.SharedPreferences} or <a
    537 href="{@docRoot}guide/topics/data/data-storage.html#filesInternal">internal storage</a>).
    538 Building your backup agent with {@link android.app.backup.BackupAgentHelper} requires far less
    539 code than extending {@link android.app.backup.BackupAgent}, because you don't have to implement
    540 {@link
    541 android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
    542 onBackup()} and {@link
    543 android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor)
    544 onRestore()}.</p>
    545 
    546 <p>Your implementation of {@link android.app.backup.BackupAgentHelper} must
    547 use one or more backup helpers. A backup helper is a specialized
    548 component that {@link android.app.backup.BackupAgentHelper} summons to perform backup and
    549 restore operations for a particular type of data. The Android framework currently provides two
    550 different helpers:</p>
    551 <ul>
    552   <li>{@link android.app.backup.SharedPreferencesBackupHelper} to backup {@link
    553 android.content.SharedPreferences} files.</li>
    554   <li>{@link android.app.backup.FileBackupHelper} to backup files from <a
    555 href="{@docRoot}guide/topics/data/data-storage.html#filesInternal">internal storage</a>.</li>
    556 </ul>
    557 
    558 <p>You can include multiple helpers in your {@link android.app.backup.BackupAgentHelper}, but only
    559 one helper is needed for each data type. That is, if you have multiple {@link
    560 android.content.SharedPreferences} files, then you need only one {@link
    561 android.app.backup.SharedPreferencesBackupHelper}.</p>
    562 
    563 <p>For each helper you want to add to your {@link android.app.backup.BackupAgentHelper}, you must do
    564 the following during your {@link android.app.backup.BackupAgent#onCreate()} method:</p>
    565 <ol>
    566   <li>Instantiate in instance of the desired helper class. In the class constructor, you must
    567 specify the appropriate file(s) you want to backup.</li>
    568   <li>Call {@link android.app.backup.BackupAgentHelper#addHelper(String,BackupHelper) addHelper()}
    569 to add the helper to your {@link android.app.backup.BackupAgentHelper}.</li>
    570 </ol>
    571 
    572 <p>The following sections describe how to create a backup agent using each of the available
    573 helpers.</p>
    574 
    575 
    576 
    577 <h3 id="SharedPreferences">Backing up SharedPreferences</h3>
    578 
    579 <p>When you instantiate a {@link android.app.backup.SharedPreferencesBackupHelper}, you must
    580 include the name of one or more {@link android.content.SharedPreferences} files.</p>
    581 
    582 <p>For example, to back up a {@link android.content.SharedPreferences} file named
    583 "user_preferences", a complete backup agent using {@link android.app.backup.BackupAgentHelper} looks
    584 like this:</p>
    585 
    586 <pre>
    587 public class MyPrefsBackupAgent extends BackupAgentHelper {
    588     // The name of the SharedPreferences file
    589     static final String PREFS = "user_preferences";
    590 
    591     // A key to uniquely identify the set of backup data
    592     static final String PREFS_BACKUP_KEY = "prefs";
    593 
    594     // Allocate a helper and add it to the backup agent
    595     void onCreate() {
    596         SharedPreferencesBackupHelper helper = new SharedPreferencesBackupHelper(this, PREFS);
    597         addHelper(PREFS_BACKUP_KEY, helper);
    598     }
    599 }
    600 </pre>
    601 
    602 <p>That's it! That's your entire backup agent. The {@link
    603 android.app.backup.SharedPreferencesBackupHelper} includes all the code
    604 needed to backup and restore a {@link android.content.SharedPreferences} file.</p>
    605 
    606 <p>When the Backup Manager calls {@link
    607 android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
    608 onBackup()} and {@link
    609 android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor)
    610 onRestore()}, {@link android.app.backup.BackupAgentHelper} calls your backup helpers to perform
    611 backup and restore for your specified files.</p>
    612 
    613 <p class="note"><strong>Note:</strong> {@link android.content.SharedPreferences} are threadsafe, so
    614 you can safely read and write the shared preferences file from your backup agent and
    615 other activities.</p>
    616 
    617 
    618 
    619 <h3 id="Files">Backing up other files</h3>
    620 
    621 <p>When you instantiate a {@link android.app.backup.FileBackupHelper}, you must include the name of
    622 one or more files that are saved to your application's <a
    623 href="{@docRoot}guide/topics/data/data-storage.html#filesInternal">internal storage</a>
    624 (as specified by {@link android.content.ContextWrapper#getFilesDir()}, which is the same
    625 location where {@link android.content.Context#openFileOutput(String,int) openFileOutput()} writes
    626 files).</p>
    627 
    628 <p>For example, to backup two files named "scores" and "stats," a backup agent using {@link
    629 android.app.backup.BackupAgentHelper} looks like this:</p>
    630 
    631 <pre>
    632 public class MyFileBackupAgent extends BackupAgentHelper {
    633     // The name of the SharedPreferences file
    634     static final String TOP_SCORES = "scores";
    635     static final String PLAYER_STATS = "stats";
    636 
    637     // A key to uniquely identify the set of backup data
    638     static final String FILES_BACKUP_KEY = "myfiles";
    639 
    640     // Allocate a helper and add it to the backup agent
    641     void onCreate() {
    642         FileBackupHelper helper = new FileBackupHelper(this, TOP_SCORES, PLAYER_STATS);
    643         addHelper(FILES_BACKUP_KEY, helper);
    644     }
    645 }
    646 </pre>
    647 
    648 <p>The {@link android.app.backup.FileBackupHelper} includes all the code necessary to backup and
    649 restore files that are saved to your application's <a
    650 href="{@docRoot}guide/topics/data/data-storage.html#filesInternal">internal storage</a>..</p>
    651 
    652 <p>However, reading and writing to files on internal storage is <strong>not threadsafe</strong>. To
    653 ensure that your backup agent does not read or write your files at the same time as your activities,
    654 you must use synchronized statements each time you perform a read or write. For example,
    655 in any Activity where you read and write the file, you need an object to use as the intrinsic
    656 lock for the synchronized statements:</p>
    657 
    658 <div class="sidebox-wrapper">
    659 <div class="sidebox">
    660 <p><strong>Interesting Fact:</strong></p>
    661 <p>A zero-length array is lighter-weight than a normal Object, so it's great for an
    662 intrinsic lock.</p>
    663 </div>
    664 </div>
    665 
    666 <pre>
    667 // Object for intrinsic lock
    668 static final Object[] sDataLock = new Object[0];
    669 </pre>
    670 
    671 <p>Then create a synchronized statement with this lock each time you read or write the files. For
    672 example, here's a synchronized statement for writing the latest score in a game to a file:</p>
    673 
    674 <pre>
    675 try {
    676     synchronized (MyActivity.sDataLock) {
    677         File dataFile = new File({@link android.content.Context#getFilesDir()}, TOP_SCORES);
    678         RandomAccessFile raFile = new RandomAccessFile(dataFile, "rw");
    679         raFile.writeInt(score);
    680     }
    681 } catch (IOException e) {
    682     Log.e(TAG, "Unable to write to file");
    683 }
    684 </pre>
    685 
    686 <p>You should synchronize your read statements with the same lock.</p>
    687 
    688 <p>Then, in your {@link android.app.backup.BackupAgentHelper}, you must override {@link
    689 android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
    690 onBackup()} and {@link
    691 android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor)
    692 onRestore()} to synchronize the backup and restore operations with the same
    693 intrinsic lock. For example, the {@code MyFileBackupAgent} example from above needs the following
    694 methods:</p>
    695 
    696 <pre>
    697 &#64;Override
    698 public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
    699           ParcelFileDescriptor newState) throws IOException {
    700     // Hold the lock while the FileBackupHelper performs backup
    701     synchronized (MyActivity.sDataLock) {
    702         super.onBackup(oldState, data, newState);
    703     }
    704 }
    705 
    706 &#64;Override
    707 public void onRestore(BackupDataInput data, int appVersionCode,
    708         ParcelFileDescriptor newState) throws IOException {
    709     // Hold the lock while the FileBackupHelper restores the file
    710     synchronized (MyActivity.sDataLock) {
    711         super.onRestore(data, appVersionCode, newState);
    712     }
    713 }
    714 </pre>
    715 
    716 <p>That's it. All you need to do is add your {@link android.app.backup.FileBackupHelper} in the
    717 {@link android.app.backup.BackupAgent#onCreate()} method and override {@link
    718 android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
    719 onBackup()} and {@link
    720 android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor)
    721 onRestore()} to synchronize read and write operations.</p>
    722 
    723 <div class="special">
    724 <p>For an example implementation of {@link
    725 android.app.backup.BackupAgentHelper} with {@link android.app.backup.FileBackupHelper}, see the
    726 {@code FileHelperExampleAgent} class in the <a
    727 href="{@docRoot}resources/samples/BackupRestore/index.html">Backup and Restore</a> sample
    728 application.</p>
    729 </div>
    730 
    731 
    732 
    733 
    734 
    735 
    736 <h2 id="RestoreVersion">Checking the Restore Data Version</h2>
    737 
    738 <p>When the Backup Manager saves your data to cloud storage, it automatically includes the version
    739 of your application, as defined by your manifest file's <a
    740 href="{@docRoot}guide/topics/manifest/manifest-element.html#vcode">{@code android:versionCode}</a>
    741 attribute. Before the Backup Manager calls your backup agent to restore your data, it
    742 looks at the <a
    743 href="{@docRoot}guide/topics/manifest/manifest-element.html#vcode">{@code
    744 android:versionCode}</a> of the installed application and compares it to the value
    745 recorded in the restore data set. If the version recorded in the restore data set is
    746 <em>newer</em> than the application version on the device, then the user has downgraded their
    747 application. In this case, the Backup Manager will abort the restore operation for your application
    748 and not call your {@link
    749 android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) onRestore()}
    750 method, because the restore set is considered meaningless to an older version.</p>
    751 
    752 <p>You can override this behavior with the <a
    753 href="{@docRoot}guide/topics/manifest/application-element.html#restoreany">{@code
    754 android:restoreAnyVersion}</a> attribute. This attribute is either "{@code true}" or "{@code
    755 false}" to indicate whether you want to restore the application regardless of the restore set
    756 version. The default value is "{@code false}". If you define this to be "{@code true}" then the
    757 Backup Manager will ignore the <a
    758 href="{@docRoot}guide/topics/manifest/manifest-element.html#vcode">{@code android:versionCode}</a>
    759 and call your {@link
    760 android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) onRestore()}
    761 method in all cases. In doing so, you can manually check for the version difference in your {@link
    762 android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) onRestore()}
    763 method and take any steps necessary to make the data compatible if the versions conflict.</p>
    764 
    765 <p>To help you handle different versions during a restore operation, the {@link
    766 android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) onRestore()}
    767 method passes you the version code included with the restore data set as the {@code appVersionCode}
    768 parameter. You can then query the current application's version code with the {@link
    769 android.content.pm.PackageInfo#versionCode PackageInfo.versionCode} field. For example:</p>
    770 
    771 <pre>
    772 PackageInfo info;
    773 try {
    774     String name = {@link android.content.ContextWrapper#getPackageName() getPackageName}();
    775     info = {@link android.content.ContextWrapper#getPackageManager
    776 getPackageManager}().{@link android.content.pm.PackageManager#getPackageInfo(String,int)
    777 getPackageInfo}(name,0);
    778 } catch (NameNotFoundException nnfe) {
    779     info = null;
    780 }
    781 
    782 int version;
    783 if (info != null) {
    784     version = info.versionCode;
    785 }
    786 </pre>
    787 
    788 <p>Then simply compare the {@code version} acquired from {@link android.content.pm.PackageInfo}
    789 to the {@code appVersionCode} passed into {@link
    790 android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) onRestore()}.
    791 </p>
    792 
    793 <p class="caution"><strong>Caution:</strong> Be certain you understand the consequences of setting
    794 <a href="{@docRoot}guide/topics/manifest/application-element.html#restoreany">{@code
    795 android:restoreAnyVersion}</a> to "{@code true}" for your application. If each version of your
    796 application that supports backup does not properly account for variations in your data format during
    797 {@link
    798 android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) onRestore()},
    799 then the data on the device could be saved in a format incompatible with the version currently
    800 installed on the device.</p>
    801 
    802 
    803 
    804 <h2 id="RequestingBackup">Requesting Backup</h2>
    805 
    806 <p>You can request a backup operation at any time by calling {@link
    807 android.app.backup.BackupManager#dataChanged()}. This method notifies the Backup Manager that you'd
    808 like to backup your data using your backup agent. The Backup Manager then calls your backup
    809 agent's {@link
    810 android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
    811 onBackup()} method at an opportune time in the future. Typically, you should
    812 request a backup each time your data changes (such as when the user changes an application
    813 preference that you'd like to back up). If you call {@link
    814 android.app.backup.BackupManager#dataChanged()} several times consecutively, before the Backup
    815 Manager requests a backup from your agent, your agent still receives just one call to {@link
    816 android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor,BackupDataOutput,ParcelFileDescriptor)
    817 onBackup()}.</p>
    818 
    819 <p class="note"><strong>Note:</strong> While developing your application, you can request a
    820 backup and initiate an immediate backup operation with the <a
    821 href="{@docRoot}guide/developing/tools/bmgr.html">{@code bmgr}
    822 tool</a>.</p>
    823 
    824 
    825 <h2 id="RequestingRestore">Requesting Restore</h2>
    826 
    827 <p>During the normal life of your application, you shouldn't need to request a restore operation.
    828 They system automatically checks for backup data and performs a restore when your application is
    829 installed. However, you can manually request a restore operation by calling {@link
    830 android.app.backup.BackupManager#requestRestore(RestoreObserver) requestRestore()}, if necessary. In
    831 which case, the Backup Manager calls your {@link
    832 android.app.backup.BackupAgent#onRestore(BackupDataInput,int,ParcelFileDescriptor) onRestore()}
    833 implementation, passing the data from the current set of backup data.</p>
    834 
    835 <p class="note"><strong>Note:</strong> While developing your application, you can request a
    836 restore operation with the <a href="{@docRoot}guide/developing/tools/bmgr.html">{@code bmgr}
    837 tool</a>.</p>
    838 
    839 
    840 <h2 id="Testing">Testing Your Backup Agent</h2>
    841 
    842 <p>Once you've implemented your backup agent, you can test the backup and restore functionality
    843 with the following procedure, using <a
    844 href="{@docRoot}guide/developing/tools/bmgr.html">{@code bmgr}</a>.</p>
    845 
    846 <ol>
    847   <li>Install your application on a suitable Android system image
    848     <ul>
    849       <li>If using the emulator, create and use an AVD with Android 2.2 (API Level 8).</li>
    850       <li>If using a device, the device must be running Android 2.2 or greater and have Android
    851 Market built in.</li>
    852     </ul>
    853   </li>
    854   <li>Ensure that backup is enabled
    855     <ul>
    856       <li>If using the emulator, you can enable backup with the following command from your SDK
    857 {@code tools/} path:
    858 <pre class="no-pretty-print">adb shell bmgr enable true</pre>
    859       </li>
    860       <li>If using a device, open the system <b>Settings</b>, select <b>Privacy</b>, then enable
    861 <b>Back up my data</b> and <b>Automatic restore</b>.
    862     </ul>
    863   </li>
    864   <li>Open your application and initialize some data
    865     <p>If you've properly implemented backup in your application, then it should request a
    866 backup each time the data changes. For example, each time the user changes some data, your app
    867 should call {@link android.app.backup.BackupManager#dataChanged()}, which adds a backup request to
    868 the Backup Manager queue. For testing purposes, you can also make a request with the following
    869 {@code bmgr} command:</p>
    870 <pre class="no-pretty-print">adb shell bmgr backup <em>your.package.name</em></pre>
    871   </li>
    872   <li>Initiate a backup operation:
    873 <pre class="no-pretty-print">adb shell bmgr run</pre>
    874     <p>This forces the Backup Manager to perform all backup requests that are in its
    875 queue.</p>
    876   <li>Uninstall your application:
    877 <pre class="no-pretty-print">adb uninstall <em>your.package.name</em></pre>
    878   </li>
    879   <li>Re-install your application.</li>
    880 </ol>
    881 
    882 <p>If your backup agent is successful, all the data you initialized in step 4 is restored.</p>
    883 
    884 
    885