Search code examples
androidandroid-sqlitesharedpreferencesdatabase-backupsandroid-sharedpreferences

How to restore Android Sharedpreferences from XML file after making its backup in sd card?


I have searched for this but i didn't get an answer. I am working on Budget app and in that there are two type of databases(Sqlite and Shared-preferences). As i can BACKUP/RESTORE of sqlite database in sdcard but I don't know how to backup and restore shared preferences database.

I am able to backup shared-preferences database but don't know how to restore it from sd card.
Databases names: 1.magicbox_database.db is sqlite database, 2.magicbox_database_sf.db is sharedpreferences database

This is a code for Backup for both database.

if (isStoragePermissionGranted() == true) {
                    try {
                        File sd = Environment.getExternalStorageDirectory();
                        if (sd.canWrite()) {
                            String currentDBPath = "/data/data/" + getPackageName() + "/databases/OLBE_DEMO";
                            String backupDBPath = "magicbox_database.db";
                            File currentDB = new File(currentDBPath);
                            File backupDB = new File(sd, backupDBPath);
                            Toast.makeText(MainActivity.this, "backup creating....", Toast.LENGTH_SHORT).show();
                            if (currentDB.exists()) {
                                FileChannel src = new FileInputStream(currentDB).getChannel();
                                FileChannel dst = new FileOutputStream(backupDB).getChannel();
                                dst.transferFrom(src, 0, src.size());
                                src.close();
                                dst.close();
                                Toast.makeText(MainActivity.this, "Bckup Created !", Toast.LENGTH_SHORT).show();
                                Toast.makeText(MainActivity.this, "magicbox_database.db  in External Storage", Toast.LENGTH_SHORT).show();
                            }


                            String currentDBPath1 = "/data/data/" + getPackageName() + "/shared_prefs/DATABASE.xml";
                            String backupDBPath1 = "magicbox_database_sf.xml";
                            File currentDB1 = new File(currentDBPath1);
                            File backupDB1 = new File(sd, backupDBPath1);
                           // Toast.makeText(MainActivity.this, "backup creating....", Toast.LENGTH_SHORT).show();
                            if (currentDB1.exists()) {
                                FileChannel src1 = new FileInputStream(currentDB1).getChannel();
                                FileChannel dst1 = new FileOutputStream(backupDB1).getChannel();
                                dst1.transferFrom(src1, 0, src1.size());
                                src1.close();
                                dst1.close();
                                //Toast.makeText(MainActivity.this, "Bckup Created !", Toast.LENGTH_SHORT).show();
                                Toast.makeText(MainActivity.this, "magicbox_database_sf.db  in External Storage", Toast.LENGTH_SHORT).show();
                            }

                        }
                    } catch (Exception e) {
                        Toast.makeText(MainActivity.this, "ERROR! backup not created", Toast.LENGTH_SHORT).show();
                    }
                }

This code for Restore for both

 if (isStoragePermissionGranted() == true) {
                    try {
                        File sd = Environment.getExternalStorageDirectory();
                        if (sd.canWrite()) {
                            String currentDBPath = "/data/data/" + getPackageName() + "/databases/OLBE_DEMO";
                            String backupDBPath = "magicbox_database.db";
                            File currentDB = new File(currentDBPath);
                            File backupDB = new File(sd, backupDBPath);
                            Toast.makeText(MainActivity.this, "restoring......", Toast.LENGTH_SHORT).show();
                            if (currentDB.exists()) {
                                FileChannel src = new FileInputStream(backupDB).getChannel();
                                FileChannel dst = new FileOutputStream(currentDB).getChannel();
                                dst.transferFrom(src, 0, src.size());
                                src.close();
                                dst.close();
                                Toast.makeText(MainActivity.this, "Your data Restored !", Toast.LENGTH_SHORT).show();
                            }
                            String currentDBPath1 = "/data/data/" + getPackageName() + "/shared_prefs/DATABASE.xml";
                            String backupDBPath1 = "magicbox_database_sf.xml";
                            File currentDB1 = new File(currentDBPath1);
                            File backupDB1 = new File(sd, backupDBPath1);
                            if (currentDB1.exists()) {
                                FileChannel src1 = new FileInputStream(backupDB1).getChannel();
                                FileChannel dst1 = new FileOutputStream(currentDB1).getChannel();
                                dst1.transferFrom(src1, 0, src1.size());
                                src1.close();
                                dst1.close();
                                Toast.makeText(MainActivity.this, "magicbox_database_sf.db  in External Storage", Toast.LENGTH_SHORT).show();
                            }
                        }

                    } catch (Exception e) {
                        Toast.makeText(MainActivity.this, "ERROR! data not restored", Toast.LENGTH_SHORT).show();
                    }
                }

changes are in this code

 FileChannel src1 = new FileInputStream(backupDB1).getChannel();
 FileChannel dst1 = new FileOutputStream(currentDB1).getChannel();

Solution

  • Yeah just followed this to get the path and XML file can be easily extracted with all your preferences - then you can use this xml content(By parsing it) to create Preferences or extract values

    XML will look something like this:

    <?xml version='1.0' encoding='utf-8' standalone='yes' ?>
    <map>
        <int name="Key2" value="100" />
        <long name="Key1" value="99" />
        <string name="Key">Vikesh Dass</string>
    </map>
    

    Just parse the xml to get your Data this should be easy :)

    For Parsing Xml you can use this class:

    public class XMLParser {
    
    private static final String ns = null;
    
    public void parse(InputStream in) throws XmlPullParserException, IOException {
        try {
            XmlPullParser parser = Xml.newPullParser();
            parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
            parser.setInput(in, null);
            parser.nextTag();
            readPreferences(parser);
        } finally {
            in.close();
        }
    }
    
    private void readPreferences(XmlPullParser parser) throws XmlPullParserException, IOException {
        parser.require(XmlPullParser.START_TAG, ns, "map");
        while (parser.next() != XmlPullParser.END_TAG) {
            if (parser.getEventType() != XmlPullParser.START_TAG) {
                continue;
            }
            String node = parser.getName();
            if (node.equals("string")) {
                readName(parser);
            } else if (node.equals("int")) {
                readValueint(parser);
            } else if (node.equals("long")) {
                readValuelong(parser);
            } else {
                skip(parser);
            }
        }
    }
    
    private void readName(XmlPullParser parser) throws IOException, XmlPullParserException {
        parser.require(XmlPullParser.START_TAG, ns, "string");
        String name = readText(parser);
        parser.require(XmlPullParser.END_TAG, ns, "string");
        //Set the Preference again after it is fetched
    }
    
    private String readText(XmlPullParser parser) throws IOException, XmlPullParserException {
        String result = "";
        if (parser.next() == XmlPullParser.TEXT) {
            result = parser.getText();
            parser.nextTag();
        }
        return result;
    }
    
    private void readValueint(XmlPullParser parser) throws IOException, XmlPullParserException {
        parser.require(XmlPullParser.START_TAG, ns, "int");
        String ValueData = parser.getAttributeValue(null, "value");
        String ValueKey = parser.getAttributeValue(null, "name");
        //Set the Preference again after it is fetched
    }
    
    private void readValuelong(XmlPullParser parser) throws IOException, XmlPullParserException {
        parser.require(XmlPullParser.START_TAG, ns, "long");
        String ValueData = parser.getAttributeValue(null, "value");
        String ValueKey = parser.getAttributeValue(null, "name");
        //Set the Preference again after it is fetched
    }
    
    private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            throw new IllegalStateException();
        }
        int depth = 1;
        while (depth != 0) {
            switch (parser.next()) {
                case XmlPullParser.END_TAG:
                    depth--;
                    break;
                case XmlPullParser.START_TAG:
                    depth++;
                    break;
            }
        }
    }
    
    }
    

    And from your class call this:

    File sd = Environment.getExternalStorageDirectory();
            String backupDBPath1 = "your_backedUpPrefDb.xml";
            File backupDB1 = new File(sd, backupDBPath1);
            InputStream is = new BufferedInputStream(new FileInputStream(backupDB1));
            XMLParser myXMLParser = new XMLParser();
            myXMLParser.parse(is);
            is.close();