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

4 回答 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 的同一个 Layout 上导入它,你可以使用它来刷新

                        finish();
                        startActivity(getIntent());
于 2016-05-12T07:33:56.647 回答
0

获取 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)

    }
}
于 2014-08-26T07:18:03.940 回答
0

您传递给的密钥addHelper 不是您在SharedPreferences. 它是从您添加的所有助手中识别此特定助手的键。SharedPreferencesBackupHelper备份SharedPreferences您告诉它的每个文件中的每个值。

如果您SharedPreferences没有得到备份,那是出于不同的原因。检查 SharedPreferences 文件的名称是否正确,并且您已<meta-data>在 AndroidManifest.xml 的标记中正确指定了密钥。

于 2013-03-21T16:44:29.240 回答
0

这对我来说是一个挑战,但我明白了。希望它对某人有用。〜安:-)

ORY 的回答会起作用,但您需要完全退出应用程序才能加载新设置。这是他方法的更新,也是导入 Sharepreference 的一种方式。通过此方法重新启动时,不会显示 Toasting。**请记住,如果不存在,您将需要创建一个 .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();
              }

           }  
于 2018-10-13T21:12:09.383 回答