Tuesday, February 24, 2009

Code : Backup and restore data using SyncItem


SyncItem (net.rim.device.api.synchronization.SyncItem) provides an easy method of backing up and restoring small amounts of data such as application configuration information. Allowing data to be backed up and restored ensures that the same information will be reloaded onto a user’s BlackBerry device when they upgrade the OS on their device. It can also allow configuration information to be transferred from one device to another.

It is not recommended to use this method to backup and restore a large amount of data. For more information on backing up and restoring a large amount of data see Chapter 6, Backing up and restoring persistent data in the BlackBerry Developer's Guide, Volume 2, Advanced Topics.

Procedure

In order for the SyncItem to register when the device starts, a separate project will have to be created that acts as an alternate entry point to your main application. This passes an argument to your application the first time that the device starts so that your application registers only once.

  1. In the BlackBerry JDE, create a project.
  2. Right-click the project and click Properties. The Properties window appears.
  3. Click the Application tab.
  4. From the Project type drop-down list, select Alternate CLDC Application Entry Point.
  5. From the Alternate entry point for drop-down list, select the main project that implements synchronization.
  6. In the Arguments passed to field, type init.
  7. Select the Auto-run on startup option.
  8. Select the System module option.
  9. Click OK.

/**
* SyncItemSample.java
*
* Allows a small list of names and ages that are stored in persistant
* store to be backed up and restored by the Desktop Manager.
*
*/
package com.samples.syncItemSample;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.system.*;
import net.rim.device.api.util.*;
import net.rim.device.api.synchronization.*;
import java.util.*;
public class SyncItemSample extends UiApplication
{
private String[] names
= {"Homer", "Marge", "Bart", "Lisa", "Maggie"};
private int ages[] = {36, 34, 10, 8, 3};
private static PersistentObject store;
private static UserList userList;
//This store is static so that all instances of this class
//use the same Persistent Store
static
{
//Unique identifier for the persistent store object.
//Long value = com.samples.syncItemSample.SyncItemSample
store = PersistentStore.getPersistentObject(0x677bb65afc4a6814L);
}
public static void main(String[] args)
{
boolean startup = false;
//Check parameters to see if the application was entered
//through the alternate application entry point.
for (int i=0; i<args.length; ++i)
{
if (args[i].startsWith("init"))
{
startup = true;
}
}
if (startup)
{
//Entered through the alternate application entry point.
//Enable application for synchronization on startup.
SerialSyncManager.getInstance().enableSynchronization
(new UserListSync());
} else
{
//Entered by selecting the application icon on the ribbon.
SyncItemSample app = new SyncItemSample();
app.enterEventDispatcher();
}
}
public SyncItemSample()
{
UserListScreen userListScreen;
//Check to see if the store exists on the BlackBerry.
synchronized (store)
{
if (store.getContents() == null)
{
//Store does not exist, create it with default values
userList = new UserList(names, ages);
store.setContents(userList);
store.commit();
}
else
{
//Store exists, retrieve data from store.
userList = (UserList)store.getContents();
names = userList.getNames();
ages = userList.getAges();
}
}
//Create and push the UserListScreen.
userListScreen = new UserListScreen(names, ages);
pushScreen(userListScreen);
}
/**
* UserListSync.java
*
* Handles the backup and restore of persistent data.
*
*/
package com.samples.syncItemSample;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.system.*;
import net.rim.device.api.util.*;
import net.rim.device.api.synchronization.*;
import java.util.*;
import net.rim.device.api.i18n.Locale;
public final class UserListSync extends SyncItem
{
private String[] permNames = new String[5];
private int permAges[] = new int[5];
private static UserList permUserList;
private static final int FIELDTAG_NAME = 1;
private static final int FIELDTAG_AGE = 2;
private static PersistentObject store;
//This store is static so that all instances of this class
//use the same Persistent Store
static
{
//Unique identifier for the persistent store object.
//Long value = com.samples.syncItemSample.SyncItemSample
store = PersistentStore.getPersistentObject(0x677bb65afc4a6814L);
}
public UserListSync()
{
}
//The name that will be used to reference this SyncItem.
//It is shown in the Desktop Manager under backup/restore advanced.
public String getSyncName()
{
return "Sync Item Sample";
}
//Localization is not supported in this example.
public String getSyncName(Locale locale)
{
return null;
}
//The version of this SyncItem.
public int getSyncVersion()
{
return 1;
}
//Formats the data to the specification required
//by the Desktop Manager.
public boolean getSyncData(DataBuffer db, int version)
{
int count;
boolean retVal = true;
String tempString;
synchronized (store)
{
//Check to see if the persistent store object
//exists on the BlackBerry.
if (store.getContents() != null)
{
//Store exists, retrieve data from store.
permUserList = (UserList)store.getContents();
permNames = permUserList.getNames();
permAges = permUserList.getAges();
}
}
//Format data that will be interpreted by the Desktop Manager.
//Format is Length Type Data
//Length is a short, type is a byte and data is the length
// specified by Length.
//Data must be structured in this format to be understood
// by the Desktop Manager.
try
{
for (count = 0; count < 5; ++count)
{
//Write the name.
db.writeShort(permNames[count].length() + 1);
db.writeByte(FIELDTAG_NAME);
db.write(permNames[count].getBytes());
db.writeByte(0);
//Write the age.
tempString = permAges[count] + "";
db.writeShort(tempString.length() + 1);
db.writeByte(FIELDTAG_AGE);
db.write(tempString.getBytes());
db.writeByte(0);
}
} catch (Exception e)
{
retVal = false;
}
//Return true if all data was processed.
return retVal;
}
//Interprets and stores the data sent from the Desktop Manager.
public boolean setSyncData(DataBuffer db, int version)
{
int length, nameCount = 0, ageCount = 0;
boolean retVal = true;
try
{
//Read until the end of the Databuffer.
while (db.available() > 0)
{
//Read the length of the data.
length = db.readShort();
//Set the byte array to the length of the data.
byte[] bytes = new byte[length];
//Determine the type of data to be read (name or age).
switch (db.readByte())
{
case FIELDTAG_NAME:
//Read the name from the Databuffer.
//Convert and store it in the String array.
db.readFully(bytes);
permNames[nameCount] = new String(bytes).trim();
++nameCount;
break;
case FIELDTAG_AGE:
//Read the age from the Databuffer.
//Convert and store it in the int array.
db.readFully(bytes);
permAges[ageCount]
= (int)(Integer.parseInt(new String(bytes).trim()));
++ageCount;
break;
}
}
} catch (Exception e)
{
retVal = false;
}
try
{
//Store the new data in the persistent store object.
permUserList = new UserList(permNames, permAges);
store.setContents(permUserList);
store.commit();
} catch (Exception e)
{
retVal = false;
}
//Return true if the data was successfully restored,
//or false if it was not.
return retVal;
}
}
/**
* UserList.java
*
* UserList is persistable and holds the list of names and ages.
*
*/
package com.samples.syncItemSample;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.system.*;
import net.rim.device.api.util.*;
import net.rim.device.api.synchronization.*;
import java.util.*;
import net.rim.device.api.i18n.Locale;
public final class UserList implements Persistable
{
//The persistable objects.
private String[] permNames = new String[5];
private int permAges[] = new int[5];
//Initialize the class with empty values.
public UserList()
{
}
//Initialize the class with the specified values.
public UserList(String[] names, int ages[])
{
permNames = names;
permAges = ages;
}
//Get/set methods.
public String[] getNames()
{
return permNames;
}
public void setNames(String[] names)
{
permNames = names;
}
public int[] getAges()
{
return permAges;
}
public void setAges(int[] ages)
{
permAges = ages;
}
}
/**
* UserListScreen.java
*
* This screen displays the list of names and ages.
*
*/
package com.samples.syncItemSample;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.system.*;
import java.util.*;
public final class UserListScreen extends MainScreen
{
public UserListScreen(String[] names, int[] ages)
{
super();
//Create a horizontal field manager to hold the two vertical field
//managers to display the names and ages in two columns.
HorizontalFieldManager backGround = new HorizontalFieldManager();
VerticalFieldManager leftColumn = new VerticalFieldManager();
VerticalFieldManager rightColumn = new VerticalFieldManager();
//Array of fields to display the names and ages.
LabelField displayNames[] = new LabelField[5];
LabelField displayAges[] = new LabelField[5];
int count;
//Set the screen title.
LabelField title = new LabelField("User List",
LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);
setTitle(title);
//Add the column titles and a blank field to create a space.
LabelField leftTitle = new LabelField("User ");
leftColumn.add(leftTitle);
LabelField rightTitle = new LabelField("Age");
rightColumn.add(rightTitle);
leftColumn.add(new LabelField(""));
rightColumn.add(new LabelField(""));
//Populate and add the name and age fields.
for (count = 0; count < 5; count++)
{
displayNames[count] = new LabelField(names[count]);
displayAges[count] = new LabelField(String.valueOf(ages[count]));
leftColumn.add(displayNames[count]);
rightColumn.add(displayAges[count]);
}
//Add the two vertical columns to the horizontal field manager.
backGround.add(leftColumn);
backGround.add(rightColumn);
//Add the horizontal field manager to the screen.
add(backGround);
}
public boolean onClose()
{
System.exit(0);
return true;
}
//Close the screen whenever a key is pressed.
public boolean keyChar(char key, int status, int time)
{
this.close();
return true;
}
//Close the screen if the trackwheel is clicked.
public boolean trackwheelClick(int status, int time)
{
this.close();
return true;
}
}

No comments:

Post a Comment

Place your comments here...