Android备份完整的SharedPreferences文件

3

我一直在尝试让我Android应用程序中的sharedpreferences文件备份工作,但目前还没有成功。我正在使用开发人员指南中简单的Google代码。以下是MyPrefsBackup类的代码。

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);


    }

我认为我终于意识到了“PREFS_BACKUP_KEY”的实际含义,它必须是我存储数据的具体键。我一直在使用“prefs”,所以我想这就是为什么没有数据被备份的原因。然而,我将相当多的数据存储在“SharedPreferences”文件中,那么我怎么能够保存整个“SharedPreferences”文件而不指定每个单独的键呢? (有些键是由应用程序生成的,因此在用户输入其数据之前,我甚至不知道它们是否在使用中)。
我想知道是否有一种方法可以告诉“BackupHelper”类备份整个“SharedPreferences”文件?
4个回答

1

示例SharedPreferences

SharedPreferences preferences=getSharedPreferences("Test", getApplicationContext().MODE_MULTI_PROCESS)

备份文件夹的日期。
Calendar c = Calendar.getInstance();
            SimpleDateFormat sdf = new SimpleDateFormat("dd_MMMM_yyyy HH_mm_ss");
            String strDate = sdf.format(c.getTime());

导出SharedPreferences

exportSH("Test.xml", strDate);

将SharedPreferences .xml文件导出到下载目录中的文件夹
private void exportSH(String sh_name, String strDate){




        File sd = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + 
                File.separator + "Backup Folder "+strDate+ 
                File.separator );

          boolean success = true;
           if (!sd.exists()) {
               success = sd.mkdir();
           }
           if (success) {

        File data = Environment.getDataDirectory();
       FileChannel source=null;
       FileChannel destination=null;
       String currentDBPath = "/data/"+ context.getPackageName() +"/shared_prefs/"+ sh_name;
       String backupDBPath = sh_name;
       File currentDB = new File(data, currentDBPath);
       File backupDB = new File(sd, backupDBPath);
       try {
            source = new FileInputStream(currentDB).getChannel();
            destination = new FileOutputStream(backupDB).getChannel();
            destination.transferFrom(source, 0, source.size());
            source.close();
            destination.close();
            Toast.makeText(this, "Done", Toast.LENGTH_SHORT).show();
        } catch(IOException e) {
            e.printStackTrace();
Toast.makeText(this, "Failed", Toast.LENGTH_SHORT).show();
        }
           }}

你可以通过小幅更改导入文件。有些人说它不会那么容易,但实际上是可以的。只需确保在导入之前创建一个空的Sharedpreferences文件,否则它将无法正常工作。
例如,你可以这样做:
    SharedPreferences dummy = getSharedPreferences("dummy", getApplicationContext().MODE_MULTI_PROCESS);
                Editor editor = dummy.edit();
editor.putBoolean("asdf", true);

    editor.commit();

如果您将其导入到使用SharedPreferences的相同布局中,则可以使用此选项进行刷新。

                        finish();
                        startActivity(getIntent());

1
获取sharedpreference文件备份很容易。请查看以下示例以更好地理解:
SharedPreferences sharedPref = getSharedPreferences("EmpDetails", MODE_PRIVATE);
Editor prefEditor = sharedPref.edit();
prefEditor.putString("empName1", "valuelabs");
prefEditor.putString("empName2", "webmd");
prefEditor.commit();

如果您想检索共享偏好文件的备份,您需要使用以下逻辑。在此,如果需要值,可以根据您的键访问。

public class MyPrefsBackup extends BackupAgentHelper {

    // The name of the SharedPreferences file
    static final String PREFS = "EmpDetails";
   // A key to uniquely identify the set of backup data
    static final String PREFS_BACKUP_KEY = "PREF";

  public  void onCreate() {

        SharedPreferencesBackupHelper helper = new SharedPreferencesBackupHelper(this, PREFS);
        addHelper(PREFS_BACKUP_KEY, helper)

    }
}

1

addHelper 方法中传递的键名并不是在 SharedPreferences 中使用的键名。它用于标识此特定帮助程序与您添加的所有帮助程序区分开来。 SharedPreferencesBackupHelper 将备份您指定的每个SharedPreferences 文件中的每个值。

如果您的 SharedPreferences 没有被备份,原因可能不同。请检查 SharedPreferences 文件的名称是否正确,并确保在 AndroidManifest.xml 文件的 <meta-data> 标签中正确指定了键名。


我也遇到了同样的问题。这是我的代码链接http://pastebin.com/Y3Jismaq。我的代码有什么问题,或者在发布应用程序之前是否有任何不同的测试机制? - AndroidDev
@AndroidDev 如果你有新的问题,你知道该怎么做。但我相信你已经知道“我的代码有什么问题吗”不是这个网站上真正的问题。 - Dan Hulme
抱歉,我想知道在将备份功能实现后如何在发布到应用商店之前测试应用程序。 - AndroidDev

0

这对我来说是一个挑战,但我解决了它。希望对某人有用。~Ann :-)

ORY的答案可以工作,但您需要完全退出应用程序才能加载新设置。这是他方法的更新和导入Sharepreference的方法。通过此方法重新启动时不会显示Toast。**请记住,如果不存在,则需要创建.xml文件。此方法使用“transferFrom”。您还需要覆盖backpressed()以清除活动,因为这将创建活动层。

执行:

importSH(“App_settings.xml”,“/ TodoFolder / Backup /”);

方法:

    private void importSH(String sh_name, String location){


          File sd = new File(Environment.getExternalStorageDirectory().
                  getAbsolutePath() +location);


         File data = Environment.getDataDirectory();
         FileChannel source=null;
         FileChannel destination=null;
         String currentDBPath = "/data/"+ ToDoListActivity.this.getPackageName() +"/shared_prefs/"+ sh_name;
         String backupDBPath = sh_name;
         File currentDB = new File(sd, backupDBPath);
         File backupDB = new File(data, currentDBPath);



             try {
                  source = new FileInputStream(currentDB).getChannel();
                  destination = new FileOutputStream(backupDB).getChannel();

                  destination.transferFrom(source, 0, source.size());
                  source.close();
                  destination.close();

 // Toast.makeText(this, "App need to exit to load new setting", Toast.LENGTH_SHORT).show(); //will not show when rebooting. Not sure how to fix it.

                  String value =shared.getString("Demo List",null);
                     if (value != null) {

                         shared.edit().remove("Demo List").commit(); //remove the item created by dummy SharedPreferences, as mention. 
                     } 

 //restartin app to original activity.
                     Intent mStartActivity = new Intent(ToDoListActivity.this, ToDoListActivity.class);
                       int mPendingIntentId = 123456;
                       PendingIntent mPendingIntent = PendingIntent.getActivity(ToDoListActivity.this, mPendingIntentId,    mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT);
                       AlarmManager mgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
                       mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
                       System.exit(0);

              } catch(IOException e) {
                  e.printStackTrace();
                  Toast.makeText(this, "Failed", Toast.LENGTH_SHORT).show();
              }

           }  

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接