【问题标题】:How can I backup SharedPreferences to SD card?如何将 SharedPreferences 备份到 SD 卡?
【发布时间】:2012-06-07 12:46:04
【问题描述】:

我在很多地方看到将 SharedPreferences 文件复制到 sd 卡是一个问题,因为每个制造商都将它放在其他地方。

无论文件在哪里,我都想备份到 sd 卡上。 有没有办法做到这一点?

【问题讨论】:

    标签: android sharedpreferences android-preferences


    【解决方案1】:

    SharedPreferences 接口包含一个名为getAll() 的方法,该方法返回一个包含键值对的映射。因此,我没有复制文件本身,而是序列化从该方法返回的映射,然后再将其取回。

    一些代码:

    private boolean saveSharedPreferencesToFile(File dst) {
        boolean res = false;
        ObjectOutputStream output = null;
        try {
            output = new ObjectOutputStream(new FileOutputStream(dst));
            SharedPreferences pref = 
                                getSharedPreferences(prefName, MODE_PRIVATE);
            output.writeObject(pref.getAll());
    
            res = true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if (output != null) {
                    output.flush();
                    output.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return res;
    }
    
    @SuppressWarnings({ "unchecked" })
    private boolean loadSharedPreferencesFromFile(File src) {
        boolean res = false;
        ObjectInputStream input = null;
        try {
            input = new ObjectInputStream(new FileInputStream(src));
                Editor prefEdit = getSharedPreferences(prefName, MODE_PRIVATE).edit();
                prefEdit.clear();
                Map<String, ?> entries = (Map<String, ?>) input.readObject();
                for (Entry<String, ?> entry : entries.entrySet()) {
                    Object v = entry.getValue();
                    String key = entry.getKey();
    
                    if (v instanceof Boolean)
                        prefEdit.putBoolean(key, ((Boolean) v).booleanValue());
                    else if (v instanceof Float)
                        prefEdit.putFloat(key, ((Float) v).floatValue());
                    else if (v instanceof Integer)
                        prefEdit.putInt(key, ((Integer) v).intValue());
                    else if (v instanceof Long)
                        prefEdit.putLong(key, ((Long) v).longValue());
                    else if (v instanceof String)
                        prefEdit.putString(key, ((String) v));
                }
                prefEdit.commit();
            res = true;         
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }finally {
            try {
                if (input != null) {
                    input.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return res;
    }
    

    我希望我帮助了某人,如果这里有什么问题,请告诉我。

    埃拉德

    【讨论】:

    • 你能告诉我为什么在使用你的代码时会出现这个问题:stackoverflow.com/questions/23535545/…
    • Entry 条目给我:“DropBoxManager.Entry 类型不是通用的;它不能用参数参数化
    • 谢谢,这比我预想的要难得多。这个解决方案是最好的。我不得不对其进行一些修改以进行文件处理,但它就像一个魅力。
    • 如果您也发布您的工作代码以帮助他人而不是为自己保留它会很好。
    【解决方案2】:
    File ff = new File("/data/data/"
                                + MainActivity.this.getPackageName()
                                + "/shared_prefs/pref file name.xml");
    
                        Log.i("ddddddddddddd", ff.getPath() + "");
    
                        copyFile(ff.getPath().toString(), sdcard path/save file name.xml");
    
    private void copyFile(String filepath, String storefilepath) {
        try {
            File f1 = new File(filepath);
            File f2 = new File(storefilepath);
            InputStream in = new FileInputStream(f1);
    
            OutputStream out = new FileOutputStream(f2);
    
            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
            in.close();
            out.close();
            System.out.println("File copied.");
        } catch (FileNotFoundException ex) {
            System.out.println(ex.getMessage());
    
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    
    }
    

    【讨论】:

    • 这是获取 xml 文件的精确副本的好方法,但可能是不硬编码 /data 路径的更好方法,请使用 Context.getFilesDir().getPath()
    【解决方案3】:

    使用 ObjectOutputStream/ObjectInputStream 的替代方法是将 Android 源代码中的 XmlUtils.java 和 FastXmlSerializer.java 文件添加到您的项目中,然后使用 XmlUtils.writeMapXml() 和 XmlUtils.readMapXml():

    boolean res = false;
    FileOutputStream output = null;
    try {
        output = new FileOutputStream(dst);
        SharedPreferences pref = 
                            getSharedPreferences(prefName, MODE_PRIVATE);
        XmlUtils.writeMapXml(pref.getAll(), output);
    
        res = true;
        }
    

    .....

    FileInputStream input = null;
    try {
        input = new FileInputStream(src);
            Editor prefEdit = getSharedPreferences(prefName, MODE_PRIVATE).edit();
            prefEdit.clear();
            Map<String, ?> entries = XmlUtils.readMapXml(input);
            for (Entry<String, ?> entry : entries.entrySet()) {
                putObject(prefEdit, entry.getKey(), entry.getValue());
            }
        }
    

    .....

    static SharedPreferences.Editor putObject(final SharedPreferences.Editor edit,
                                              final String key, final Object val) {
        if (val instanceof Boolean)
            return edit.putBoolean(key, ((Boolean)val).booleanValue());
        else if (val instanceof Float)
            return edit.putFloat(key, ((Float)val).floatValue());
        else if (val instanceof Integer)
            return edit.putInt(key, ((Integer)val).intValue());
        else if (val instanceof Long)
            return edit.putLong(key, ((Long)val).longValue());
        else if (val instanceof String)
            return edit.putString(key, ((String)val));
    
        return edit;
    }
    

    然后,存储格式将与用于存储 SharedPreferences 的 XML 相同。

    【讨论】:

    • 你能发布完整的第二组代码吗?它似乎不完整。
    【解决方案4】:
    try {
        input = new FileInputStream(src1);
        SharedPreferences.Editor prefEdit =   getSharedPreferences("prueba100", MODE_PRIVATE).edit();
        prefEdit.clear();
        Map<String, ?> entries = XmlUtils.readMapXml(input);
        for (Map.Entry<String, ?> entry : entries.entrySet()) {
            putObject(prefEdit, entry.getKey(), entry.getValue());
        }
        prefEdit.apply();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (XmlPullParserException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    

    【讨论】:

    • 在 SO 中不赞成纯代码答案。请说明您的代码如何回答问题。另外,请在每个代码行的开头放置 4 个空格来格式化代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-01
    • 1970-01-01
    • 2011-01-11
    • 1970-01-01
    • 1970-01-01
    • 2014-09-16
    • 1970-01-01
    相关资源
    最近更新 更多