Introduction

We already know how to do a data backup on the cloud using an Android device. Let us analyze a case where the user resets his phone using a factory reset. All the third-party applications must be uninstalled and the user data might be lost and the settings as well. Although when the user reinstalls that application all the settings and saved content will be successfully retrieved. This process is completely transparent to the user and does not affect the functionality or user experience in an application.
Note: The retrieval of data doesn't mean that it is an automatic process when the user reinstalls applications, he would get all the saved settings. However, in the present scenario, this doesn't make any sense.

Client-Side Component

The backup transport procedure purely is a client-side component of Android's backup framework, but the functionality lies in the fact that it could be customizable by the device manufacturer and service provider. The backup transport might differ from a wide range of devices and which backup transport is available on any given device is transparent to your application.
The Backup Manager APIs isolate the application from the actual backup transport available on a given device. An Android application communicates with the Backup Manager using a fixed set of APIs, regardless of the underlying transport as specified above.

Backup Agent

To enable the backup in the application we must implement a backup agent. The backup agent is solely responsible for the data backup on the cloud using the backup transport. The calling of the backup transport by the agent is to call the restore point.
The following points must be taken care of:

Define a Backup Agent by Either

Declaring Backup Agent in Manifest File
Now it is the very first step to declare an agent in the manifest file but before that you must declare the class name. Declare it as an android:backupAgent attribute in the <application> tag.
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.example.fragment"
  4. android:versionCode="1"
  5. android:versionName="1.0" >
  6. <uses-sdk
  7. android:minSdkVersion="16"
  8. android:targetSdkVersion="21" />
  9. <application
  10. android:allowBackup="true"
  11. android:icon="@drawable/ic_launcher"
  12. android:label="@string/app_name"
  13. android:theme="@style/AppTheme"
  14. android:label="MyApplication"
  15. android:backupAgent="MyBackupAgent">
  16. <activity
  17. android:name=".MainActivity"
  18. android:label="@string/app_name" >
  19. <intent-filter>
  20. <action android:name="android.intent.action.MAIN" />
  21. <category android:name="android.intent.category.LAUNCHER" />
  22. </intent-filter>
  23. </activity>
  24. </application>
  25. </manifest>
    Another attribute you might want to use is android : restoreAnyVersion. it takes a Boolean value.

    Registering the Android Backup Service

    When there is a question of the registration of a backup then Google provides a backup transport that reduces the overhead of managing the transport with the Android Backup service for most Android-powered devices running Android 2.2 or greater. For getting a Backup Service Key, register for the Android Backup Service. When you register, you will be provided a Backup Service Key and the appropriate <meta-data> XML code for your Android manifest file that you must include as a child of the <application> element. For example:
    1. <application android:label="MyApplication"
    2. android:backupAgent="MyBackupAgent">
    3. ...
    4. <meta-data android:name="com.google.android.backup.api_key"
    5. android:value="AEdPqrEAAAAIDaYEVgU6DJnyJdBmU7KLH3kszDXLv_4DIsEIyQ" />
    6. </application>

      Extending BackupAgent

      However we can extend the BackupAgent class but it is said from various sources for the greater functionality that we must extend BackupAgentHelper to use helper classes directly. However there are certain methods as shown below but instead we must extend the BackupAgent class.

      Parameters es by onBackup() method

      Get old state input stream

      Code
      1. // Get the oldState input stream
      2. FileInputStream instream = new FileInputStream(oldState.getFileDescriptor());
      3. DataInputStream in = new DataInputStream(instream);
      4. try {
      5. // Get the last modified timestamp from the state file and data file
      6. long stateModified = in.readLong();
      7. long fileModified = mDataFile.lastModified();
      8. if (stateModified != fileModified) {
      9. // The file has been modified, so do a backup
      10. // Or the time on the device changed, so be safe and do a backup
      11. } else {
      12. // Don't back up because the file hasn't changed
      13. return;
      14. }
      15. } catch (IOException e) {
      16. // Unable to read state file... be safe and do a backup
      17. }

      Restoring the Data

      During the implementation of onRestore() it must use readNextHeader() on the data to iterate through all entities in the data set. Let us have a look at the implementation of these points as shown below.
      Code
      1. @Override
      2. public void onRestore(BackupDataInput data, int appVersionCode,
      3. ParcelFileDescriptor newState) throws IOException {
      4. // There should be only one entity, but the safest
      5. // way to consume it is using a while loop
      6. while (data.readNextHeader()) {
      7. String key = data.getKey();
      8. int dataSize = data.getDataSize();
      9. // If the key is ours (for saving top score). Note this key was used when
      10. // we wrote the backup entity header
      11. if (TOPSCORE_BACKUP_KEY.equals(key)) {
      12. // Create an input stream for the BackupDataInput
      13. byte[] dataBuf = new byte[dataSize];
      14. data.readEntityData(dataBuf, 0, dataSize);
      15. ByteArrayInputStream baStream = new ByteArrayInputStream(dataBuf);
      16. DataInputStream in = new DataInputStream(baStream);
      17. // Read the player name and score from the backup data
      18. mPlayerName = in.readUTF();
      19. mPlayerScore = in.readInt();
      20. // Record the score on the device (to a file or something)
      21. recordScore(mPlayerName, mPlayerScore);
      22. } else {
      23. // We don't know this entity key. Skip it. (Shouldn't happen.)
      24. data.skipEntityData();
      25. }
      26. }
      27. // Finally, write to the state blob (newState) that describes the restored data
      28. FileOutputStream outstream = new FileOutputStream(newState.getFileDescriptor());
      29. DataOutputStream out = new DataOutputStream(outstream);
      30. out.writeUTF(mPlayerName);
      31. out.writeInt(mPlayerScore);
      32. }

        Summary

        This article explained the basics of the data backup and the classes used in the operation, like creating a restore and managing the backup data. Although this is very much transparent to the user, the complexities of the code is hidden and present lucid steps in the device.