Android Backup of Shared Preferences to Google Backup Service not working - android

I've researched and followed how to get my android app to backup the data to google backup so if user loses phone or upgrades to a new phone, they don't lose their data. However, when I test it out (by using the app myself, then uninstalling and reinstalling), no data is restored. Here's what I've done. Perhaps someone can figure out what is wrong.
Applied for a backup key from google
Placed following code in Manifest File (in place of key I did add the key value and for packageName I used my app package name)
android:backupAgent="packageName.MyPrefsBackup">
<meta-data android:name="com.google.android.backup.api_key" android:value="key" />
Created class MyPrefsBackup with following code. The name of the sharedpreference file I want to backup is called UserDB. As far as the PREFS_BACKIP_KEY, I just called it prefs. From what I understand, this is not the same key as the one that goes in the manifest file.
Code:
package packageName;
import android.app.backup.BackupAgentHelper;
import android.app.backup.SharedPreferencesBackupHelper;
public class MyPrefsBackup extends BackupAgentHelper {
// The name of the SharedPreferences file
static final String PREFS = "UserDB";
// 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
public void onCreate() {
SharedPreferencesBackupHelper helper = new SharedPreferencesBackupHelper(this, PREFS);
addHelper(PREFS_BACKUP_KEY, helper);
}
}
Added BackupManager mBackupManager = new BackupManager(this); in my main class where I call the backup manager in next step
Lastly, in my main program I call the backupHelper when data is changed by the following line:
mBackupManager.dataChanged();
Any help is much appreciated.

try new BackupManager(this).dataChanged()

If you are testing this from AVD - you'll need to enable backups - AVD are disabled for backups by default.
adb shell bmgr enable true
Then you can actually debug it to see if the onCreate is called after running
adb shell bmgr run

Related

What is the proper way to implement SharedPreferencesBackupHelper?

initial use of sharedpreferences.
BackupManager bm = new BackupManager(getApplicationContext());
SharedPreferences sharedPreferences = getSharedPreferences("AppData", MODE_PRIVATE);
if(sharedPreferences.getBoolean("my_first_time", true)) {
sharedPreferences.edit().putBoolean("my_first_time", false).apply();
sharedPreferences.edit().putString("user_id", String.valueOf(dbh.insertUserId())).apply();
sharedPreferences.edit().putInt("noteIndex", -1).apply();
sharedPreferences.edit().putInt("checklistIndex", -1).apply();
bm.dataChanged();
}
Backing up data
public class MyPrfsBackupAgent extends BackupAgentHelper {
#Override
public void onCreate() {
SharedPreferencesBackupHelper helper = new SharedPreferencesBackupHelper(this, "AppData");
addHelper("sharedprefs_key", helper);
}
}
My goal is to backup the whole sharedpreferences file 'AppData' and restore it after re-installation of the feature is failing to complete its task. Ive tried it with allowbackup in manifest on both true and false, and running it on my actual device to test it but nothing seems to work accordingly.
items added to AndroidManifest.xml in attempt to fix this
android:backupAgent=".BackupData$MyPrfsBackupAgent"
<meta-data android:name="com.google.android.backup.api_key"
android:value="value" />
I followed the docs on this as well as other stackoverflow references but none have helped me solve the problem. I would be open to trying a different way of backup/restoring but cant find another and wont use autoBackup because it targets sdk 23 while my min is 21.
All the shared preferences data is stored in shared preferences .xml files in getFilesDir().getParentFile() directory in a folder named shared_prefs.
Simply copy all the files there to any place you want.
At reinstall do the reverse and reboot.

How to implement Android’s Data Backup Service

For my Android Project I tried to follow and implement Android Developers Data Backup Guidelines ( http://developer.android.com/guide/topics/data/backup.html ), but Data Backup and Restore doesn't work. Can someone help with examples?
With further investigation I figured out the steps to implement Android Data Backup and Restore. They are:
Add in Manifest xml file the following:
a. android:allowBackup="true" (This enables Android’s Data Backup Service)
b. meta-data android:name="com.google.android.backup.api_key"
android:value=”{Your unique Registration Key for Android Backup Service}” (You must register your application package name with a backup service. To generate a key, go to http://developer.android.com/google/backup/signup.html )
c. android:backupAgent=”.MyBackupAgent” (This is the name of class that implement’s your declared backup agent class). Note1: The first character of the name is a period for the purpose of a shorthand to locate your “com.example.project.MyBackupAgent”. Note2: If a run time Exception occurs (this may or may not happen depending on your project stucture) such as: java.lang.ClassNotFoundException: Didn’t find class “com.example.project.MyBackupAgent” then I suggest you Decompile your apk (Upload your apk package in http://www.decompileandroid.com/ ) and search for the absolute path to your MyBackupAgent and insert this path for android:backupAgent=”{absolute path}.MyBackupAgent”
Here’s an example of a Manifest xml file with Backup support:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.project">
<application android:allowBackup="true" android:backupAgent="md5f576d3976d691fac04b078d1718cab3.MyBackupAgent">
<meta-data android:name="com.google.android.backup.api_key" >android:value="{Your unique Registration Key}" />
</application>
Add in project your MyBackupAgent class. The BackupAgentHelper class provides a convenient wrapper around the BackupAgent class, which minimizes the amount of code you need to write. In your 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 onBackup() and onRestore().
Note: Android currently provides backup helpers that will backup and restore complete files from SharedPreferences and internal storage.
Here’s a Java SharedPreferenceBackupHelper example for MyBackupAgent class:
import android.app.backup.BackupAgentHelper;
import android.app.backup.SharedPreferencesBackupHelper;
import android.util.Log;
public class MyBackupAgent extends BackupAgentHelper{
static final String PREFS = "myprefs";
static final String PREFS_BACKUP_KEY = "myprefs";
#Override
public void onCreate() {
Log.i("MyFileBackupAgent", "****** Enter BACKUP CLASS *******");
SharedPreferencesBackupHelper helper = new SharedPreferencesBackupHelper(this, PREFS);
addHelper(PREFS_BACKUP_KEY, helper);
Log.i("MyFileBackupAgent", "****** Exit BACKUP CLASS ********");
}
}
Here’s a C# Xamarin FileBackupHelper example for MyBackupAgent class:
public class MyBackupAgent: BackupAgentHelper
{
string myProtectData = "File.bin";
string myPersistentData = "Data.bin";
string myDBase = "Database.db";
public override void OnCreate()
{
Console.WriteLine ("****** Enter Backup Files Helpers *********");
base.OnCreate ();
try
{
FileBackupHelper dbkh = new FileBackupHelper (this, myProtectData);
this.AddHelper ("PROTECT_backup", dbkh);
FileBackupHelper persisth = new FileBackupHelper (this, myPersistentData);
this.AddHelper ("PERSIST_backup", persisth);
FileBackupHelper dbh = new FileBackupHelper (this, myDBase);
this.AddHelper ("DATABASE_backup", dbh);
Console.WriteLine ("********* All 3 files backuped *********");
}
catch {
Console.WriteLine ("******* Backup AddHelper Exception ERROR *********");
}
Console.WriteLine ("******** Exit Backup Files Helpers ********");
}
public override void OnBackup(ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState)
{
Console.WriteLine ("****** Override OnBackup called ******");
base.OnBackup(oldState, data, newState);
}
public override void OnRestore (BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState)
{
Console.WriteLine ("****** Override OnRestore called ******");
base.OnRestore(data, appVersionCode, newState);
}
}
To perform a backup, your code should make a backup request by calling the dataChanged(). A backup request does not result in an immediate call to your 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. Note, The Backup Manager Service responds every hour as long as at least one DataChanged() was called in-between the hour since the last data backup request.
For test purposes, an immediate backup can be performed with the Android SDK Command Prompt Tool. Try these commands:
To ensure Data Backup Enabled:
adb shell bmgr enable true
To request a Data Backup:
adb shell bmgr backup
To initiate a Data Backup:
adb shell bmgr run
To uninstall your App:
adb uninstall
Then install your App:
adb install
What about your phone device Backup settings? Make sure a WiFi connection is established. Also, under device Settings, make sure "Back up my data" and "Automatic restore" are checked and you have entered in a valid Backup Account email id.
Lastly, to track your Backup upload time stamps, use www.google.com/settings/dashboard (this is your personal google account that matches your google account in your Android phone device Backup settings)

How to restore database from backup agent saved path android

I am using this code for saving database, using BackupAgent class
public class MyBackupAgent extends BackupAgentHelper {
String DATABASE_NAME = "mydb";
String DATABASE_FILE_NAME = "mydb.db";
#Override
public void onCreate() {
SharedPreferencesBackupHelper helper = new SharedPreferencesBackupHelper(this, PREFS);
addHelper(PREFS_BACKUP_KEY, helper);
FileBackupHelper dbs = new FileBackupHelper(this, DATABASE_FILE_NAME);
addHelper("dbs", dbs);
}
#Override
public File getFilesDir() {
File path = getDatabasePath(DATABASE_FILE_NAME);
return path.getParentFile();
}
}
Now after that i want to know how to restore database?
Please help me about this, Thanks in advance
In theory only with that code and changes on AndroidManifest the backup should work as per Android Google page inform.
Please take a look on this page: http://developer.android.com/guide/topics/data/backup.html
For summary from this above page:
To implement a backup agent, you must:
1 - Declare your backup agent in your manifest file with the android:backupAgent attribute.
2 - Register your application with a backup service. Google offers Android Backup Service as a backup service for most Android-powered devices, which requires that you register your application in order for it to work. Any other backup services available might also require you to register in order to store your data on their servers.
3 - Define a backup agent by either: Extending BackupAgent or Extending BackupAgentHelper;

Android BackupAgent not working

I am trying to get the BackupAgent working but I can't get it to work. Here is my sample code:
The layout is just a TextView and a Button.
MainActivity:
...
public static final String PREF_NAME = "TestPref";
private static final String TEST_KEY = "TEST";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final SharedPreferences pref = getApplicationContext()
.getSharedPreferences(PREF_NAME, MODE_PRIVATE);
if (pref.getString(TEST_KEY, "").length() == 0) {
pref.edit().putString(TEST_KEY, "new Date())
.commit();
new BackupManager(getApplicationContext()).dataChanged();
}
Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
TextView tv = (TextView) findViewById(R.id.textView1);
if ("START_VALUE".equalsIgnoreCase(tv.getText().toString())) {
tv.setText(pref.getString(TEST_KEY, ""));
}
}
});
}
The BackupHelper is just the ones I available here: http://developer.android.com/reference/android/app/backup/SharedPreferencesBackupHelper.html
I adjusted the name of the pref file with the one I used.
And in the Manifest I added
android:backupAgent="TheBackupAgent" (application tag)
and the backup-meta data
<meta-data android:name="com.google.android.backup.api_key"
android:value="{registered_key}" />
So its really a very simple app.
I am doing the following now:
1)Starting app
2) Textview is initialized with "START_VALUE" in xml file, so I press the Button and the pref-value is displayed
3) I run "adb shell bmgr run" from the console to run the backup immediately
4) I run "adb uninstall com.foo.backuptest"
5) I run "adb install com.foo.backuptest"
Now the value (timestamp) is not restored from the cloud. A new one is generated.
Where is my error??
Your Manifest file needs to include this to turn on Backup:
android:allowBackup="true"
android:backupAgent="TheBackupAgent"
What about your phone Backup settings? Make sure "Back up my data" and "Automatic restore" are checked and you have entered in a valid Backup Account email id.
To know when and how often data is backuped by Google, take a look at this link:
Android backup service - when and how often to backup?
According to this Tester (I also ran a backup frequency test just now): https://advancedweb.hu/2014/12/09/practical_measurement_of_the_android_backup_manager/
The Backup Manager Service responds every hour (I also proved this in my tests) as long as at least one DataChanged() was called in-between the hour since the last data backup request
For a quick test with command line, try these commands:
To ensure Data Backup Enabled: adb shell bmgr enable true
To request a Data Backup: adb shell bmgr backup your.package.name
To initiate a Data Backup: adb shell bmgr run
To uninstall your App: adb uninstall your.package.name
Then install your App: adb install your.package.name

BackupManager Not Calling Backup Transport

Alright, so I'm trying to implement Data Backup into my application, and have been following this guide. I've implemented my BackupAgentHelper using a SharedPreferencesBackupHelper. I don't get any errors, and I'm being sure to call dataChanged() after all preference changes, but when I test the backup (`adb shell bmgr run) I get this information in LogCat:
07-07 12:29:00.258: V/BackupManagerService(291): Scheduling immediate backup pass
07-07 12:29:00.258: V/BackupManagerService(291): Running a backup pass
07-07 12:29:00.258: V/BackupManagerService(291): clearing pending backups
07-07 12:29:00.258: V/PerformBackupTask(291): Beginning backup of 1 targets
07-07 12:29:00.289: V/BackupServiceBinder(291): doBackup() invoked
07-07 12:29:00.289: D/PerformBackupTask(291): invokeAgentForBackup on #pm#
07-07 12:29:00.297: I/PerformBackupTask(291): no backup data written; not calling transport
So for reference, in my manifest I've added:
<application
android:allowBackup="true"
android:backupAgent="com.kcoppock.sudoku.SudokuBackupAgent"
as well as
<meta-data
android:name="com.google.android.backup.api_key"
android:value="my_key_goes_here" />
and my BackupAgentHelper is implemented like so:
public class SudokuBackupAgent extends BackupAgentHelper {
static final String SCORES = "SCORES";
static final String BACKUP_ID = "sudoku_backup";
#Override
public void onCreate() {
SharedPreferencesBackupHelper backupHelper =
new SharedPreferencesBackupHelper(this, SCORES);
addHelper(BACKUP_ID, backupHelper);
}
}
and finally, in my main activity, I call for a data backup like this:
edit.putString(id + "_values", valueCache.toString());
edit.putString(id + "_hints", hintCache.toString());
edit.commit();
BackupManager backup = new BackupManager(this);
backup.dataChanged();
I've tried debugging, and it seems my onCreate() in SudokuBackupAgent is never called. Or at least it's never reached from the debugger. It seems it isn't finding any updated data, and I have double checked to ENSURE there is data to be backed up. Is there something I'm missing here?
EDIT: I should add, I'm testing on a device (Galaxy Nexus), and I've even tried using an exported release APK for testing purposes.
1) Put Log.i() into your onCreate, to see if it's called.
2) Logcat indicates that your function didn't write anything. Check if you have shared_prefs/SCORES file in your app's private folder (assumes using appropriate file manager on rooted device). This is the file you're attempting to have in backup.
Probably your preferences file is something else than this file, in such case fix your String SCORES to reflect real preferences file.
3) I tried to debug BackupAgentHelper.onCreate in my app, and it can be debugged after invoking adb shell bmgt... so it is possible to step here in debugger.
I had the same problem today with Android SDK 4.1. Using 2.3.3 versions, however, helped:
07-15 13:59:56.459: V/LocalTransport(61): performBackup() pkg=com........
07-15 13:59:56.469: V/LocalTransport(61): Got change set key=filehelper:../databases/database.db size=8208 key64=ZmlsZWhlbHBlcjouLi8kYXRhYmFzZXMvZXhwZW5zZXIuZGI=
07-15 13:59:56.469: V/LocalTransport(61): data size 8208
07-15 13:59:56.469: V/LocalTransport(61): finishBackup()
If you do not change your preferences data it will just back up once but not subsequently.
https://developer.android.com/reference/android/app/backup/SharedPreferencesBackupHelper.html
"Whenever a backup is performed, it will back up all named shared preferences that have changed since the last backup operation."
As other poster said make sure to have a log statement in your onCreate.
You can force a backup by:
// bmgr wipe TRANSPORT PACKAGE
bmgr wipe com.google.android.backup/.BackupTransportService com.kcoppock.sudoku
bmgr run
The default is com.google.android.backup/.BackupTransportService, but best to check for yourself with bmgr list transports.
You'll be much happier running against the local transport, not the default Google Transport. Check the dev docs on this.

Categories

Resources