Monday, June 18, 2012

How To Implement Backup Manager For Saving The current State Of Your Android Application



The project describes how to implement BackupManager for your application so that you can save the current state of your game/application.
Underlying Algorithm:
Basic description of algorithm in step by step form:
1.) Create a Project BackupManager
2.) Open and insert following in layout/backup_restore.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical"
   android:layout_width="match_parent"
   android:layout_height="wrap_content">

    <ScrollView
       android:orientation="vertical"
       android:layout_width="fill_parent"
       android:layout_height="fill_parent"
       android:layout_weight="1">
        <LinearLayout
           android:orientation="vertical"
           android:layout_width="match_parent"
           android:layout_height="wrap_content">
            <TextView android:text="@string/filling_text"
               android:textSize="20dp"
               android:layout_marginTop="20dp"
               android:layout_marginBottom="10dp"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"/>
            <RadioGroup android:id="@+id/filling_group"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:layout_marginLeft="20dp"
               android:orientation="vertical">
                <RadioButton android:id="@+id/bacon"
                   android:text="@string/bacon_label"/>
                <RadioButton android:id="@+id/pastrami"
                   android:text="@string/pastrami_label"/>
                <RadioButton android:id="@+id/hummus"
                   android:text="@string/hummus_label"/>
            </RadioGroup>
            <TextView android:text="@string/extras_text"
               android:textSize="20dp"
               android:layout_marginTop="20dp"
               android:layout_marginBottom="10dp"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"/>
            <CheckBox android:id="@+id/mayo"
               android:text="@string/mayo_text"
               android:layout_marginLeft="20dp"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"/>
            <CheckBox android:id="@+id/tomato"
               android:text="@string/tomato_text"
               android:layout_marginLeft="20dp"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"/>
        </LinearLayout>
    </ScrollView>
    <Button android:id="@+id/restore_button"
       android:text="@string/restore_text"
       android:onClick="onRestoreButtonClick"
       android:layout_height="wrap_content"
       android:layout_width="wrap_content"
       android:layout_weight="0" />
</LinearLayout>
3.) Open and insert following in string.xml:
<resources>
  <string name="hello">Hello World, BackupManager!</string>
  <string name="app_name">BackupManager</string>
  <string name="filling_text">Choose Settings for your game:</string>
  <string name="bacon_label">Sound On</string>
  <string name="pastrami_label">Vibration On</string>
  <string name="hummus_label">Backlight On</string>
  <string name="extras_text">Extras:</string>
  <string name="mayo_text">Use Orientation?</string>
  <string name="tomato_text">Use Camera?</string>
  <string name="restore_text">Restore last data</string>
</resources>
4.) Your manifest file will look like:
<application android:label="Backup/Restore" android:icon="@drawable/icon"
        android:backupAgent="ExampleAgent">
        <!– Some backup transports may require API keys or other metadata –>
        <meta-data android:name="com.google.android.backup.api_key"
                android:value="INSERT YOUR API KEY HERE" />
        <activity android:name=".BackupManagerExample">
                <intent-filter>
                        <action android:name="android.intent.action.MAIN" />
                        <category android:name="android.intent.category.LAUNCHER"/>
                </intent-filter>
        </activity> </application>
5.) Run the application.
Steps to Create:
1.) Open Eclipse. Use the New Project Wizard and select Android Project Give the respective project name i.e. BackupManager. Enter following information:
Project name: BackupManager
Build Target: Android 2.3.3
Application name: BackupManager
Package name: org.example.BackupManager
Create Activity: BackupManager
On Clicking Finish BackupManager code structure is generated with the necessary Android Packages being imported along with BackupManager.java. BackupManager class will look like following:
package org.example.BackupManagerExample;
import android.app.Activity;
import android.app.backup.BackupManager;
import android.app.backup.RestoreObserver;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.RadioGroup;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
public class BackupManagerExample extends Activity {
        static final String TAG = "BRActivity";
    static final Object[] sDataLock = new Object[0];
    static final String DATA_FILE_NAME = "saved_data";
    RadioGroup mFillingGroup;
    CheckBox mAddMayoCheckbox;
    CheckBox mAddTomatoCheckbox;
    File mDataFile;
    BackupManager mBackupManager;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.backup_restore);
        mFillingGroup = (RadioGroup) findViewById(R.id.filling_group);
        mAddMayoCheckbox = (CheckBox) findViewById(R.id.mayo);
        mAddTomatoCheckbox = (CheckBox) findViewById(R.id.tomato);
         mDataFile = new File(getFilesDir(), BackupManagerExample.DATA_FILE_NAME);
         mBackupManager = new BackupManager(this);
        populateUI();
    }
    void populateUI() {
        RandomAccessFile file;
        int whichFilling = R.id.pastrami;
        boolean addMayo = false;
        boolean addTomato = false;
        synchronized (BackupManagerExample.sDataLock) {
            boolean exists = mDataFile.exists();
            try {
                file = new RandomAccessFile(mDataFile, "rw");
                if (exists) {
                    Log.v(TAG, "datafile exists");
                    whichFilling = file.readInt();
                    addMayo = file.readBoolean();
                    addTomato = file.readBoolean();
                    Log.v(TAG, "  mayo=" + addMayo
                            + " tomato=" + addTomato
                            + " filling=" + whichFilling);
                } else {
                    Log.v(TAG, "creating default datafile");
                    writeDataToFileLocked(file,
                            addMayo, addTomato, whichFilling);
                    mBackupManager.dataChanged();
                }
            } catch (IOException ioe) {
            }
        }
        mFillingGroup.check(whichFilling);
        mAddMayoCheckbox.setChecked(addMayo);
        mAddTomatoCheckbox.setChecked(addTomato);
        mFillingGroup.setOnCheckedChangeListener(
                new RadioGroup.OnCheckedChangeListener() {
                    public void onCheckedChanged(RadioGroup group,
                            int checkedId) {
                        Log.v(TAG, "New radio item selected: " + checkedId);
                        recordNewUIState();
                    }
                });
        CompoundButton.OnCheckedChangeListener checkListener
                = new CompoundButton.OnCheckedChangeListener() {
            public void onCheckedChanged(CompoundButton buttonView,
                    boolean isChecked) {
                Log.v(TAG, "Checkbox toggled: " + buttonView);
                recordNewUIState();
            }
        };
        mAddMayoCheckbox.setOnCheckedChangeListener(checkListener);
        mAddTomatoCheckbox.setOnCheckedChangeListener(checkListener);
    }
    void writeDataToFileLocked(RandomAccessFile file,
            boolean addMayo, boolean addTomato, int whichFilling)
        throws IOException {
            file.setLength(0L);
            file.writeInt(whichFilling);
            file.writeBoolean(addMayo);
            file.writeBoolean(addTomato);
            Log.v(TAG, "NEW STATE: mayo=" + addMayo
                    + " tomato=" + addTomato
                    + " filling=" + whichFilling);
    }
    void recordNewUIState() {
        boolean addMayo = mAddMayoCheckbox.isChecked();
        boolean addTomato = mAddTomatoCheckbox.isChecked();
        int whichFilling = mFillingGroup.getCheckedRadioButtonId();
        try {
            synchronized (BackupManagerExample.sDataLock) {
                RandomAccessFile file = new RandomAccessFile(mDataFile, "rw");
                writeDataToFileLocked(file, addMayo, addTomato, whichFilling);
            }
        } catch (IOException e) {
            Log.e(TAG, "Unable to record new UI state");
        }
        mBackupManager.dataChanged();
    }
    public void onRestoreButtonClick(View v) {
        Log.v(TAG, "Requesting restore of our most recent data");
        mBackupManager.requestRestore(
                new RestoreObserver() {
                    public void restoreFinished(int error) {
                        Log.v(TAG, "Restore finished, error = " + error);
                        populateUI();
                    }
                }
        );
    }
}
Output – The final output:

No comments:

Post a Comment