Android Database Restore

Soldato
Joined
28 Apr 2011
Posts
15,210
Location
Barnet, London
I'm having a problem with my backup and restore of a database in my Android App.

I have a few different problems. The first is it won't create the directory, even though I have write permissions -

Code:
public static void exportDB() {
        Log.i("exportDB", "Starting");
        File sd = Environment.getExternalStorageDirectory();
        File data = Environment.getDataDirectory();
        FileChannel source = null;
        FileChannel destination = null;

        File dir = new File(Environment.getExternalStorageDirectory() + "/AutoBuddy/");
        Log.i("dir is ", "" + dir);

        try {
            if (dir.mkdir()) {
                System.out.println("Directory created");
            } else {
                System.out.println("Directory is not created");
            }
        } catch (Exception e) {
            e.printStackTrace();
            Log.i("Creating Dir Error", "" + e);
        }

        String currentDBPath = "/data/com.androidandyuk.autobuddy/databases/Vehicles";
        String backupDBPath = "AutoBuddy/Vehicles.db";
        File currentDB = new File(data, currentDBPath);
        File backupDB = new File(sd, backupDBPath);
        Context context = App.getContext();
        try {
            source = new FileInputStream(currentDB).getChannel();
            destination = new FileOutputStream(backupDB).getChannel();
            destination.transferFrom(source, 0, source.size());
            source.close();
            destination.close();
            Toast.makeText(context, "DB Exported!", Toast.LENGTH_LONG).show();
        } catch (IOException e) {
            Log.i("Export Failed", "Error");
            e.printStackTrace();
            Toast.makeText(context, "Export Failed!", Toast.LENGTH_LONG).show();
        }
    }

The logcat is -

Code:
2018-11-19 19:29:15.859 31659-31659/com.androidandyuk.autobuddy I/exportDB: Starting
2018-11-19 19:29:15.861 31659-31659/com.androidandyuk.autobuddy I/dir is: /storage/emulated/0/AutoBuddy
2018-11-19 19:29:15.861 31659-31659/com.androidandyuk.autobuddy I/System.out: Directory is not created
2018-11-19 19:29:15.861 31659-31659/com.androidandyuk.autobuddy I/Export Failed: Error
2018-11-19 19:29:15.862 31659-31659/com.androidandyuk.autobuddy W/System.err: java.io.FileNotFoundException: /storage/emulated/0/AutoBuddy/Vehicles.db (Permission denied)
2018-11-19 19:29:15.862 31659-31659/com.androidandyuk.autobuddy W/System.err:     at java.io.FileOutputStream.open0(Native Method)
2018-11-19 19:29:15.862 31659-31659/com.androidandyuk.autobuddy W/System.err:     at java.io.FileOutputStream.open(FileOutputStream.java:308)
2018-11-19 19:29:15.862 31659-31659/com.androidandyuk.autobuddy W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:238)
2018-11-19 19:29:15.862 31659-31659/com.androidandyuk.autobuddy W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:180)
2018-11-19 19:29:15.862 31659-31659/com.androidandyuk.autobuddy W/System.err:     at com.androidandyuk.autobuddy.Settings.exportDB(Settings.java:311)
2018-11-19 19:29:15.862 31659-31659/com.androidandyuk.autobuddy W/System.err:     at com.androidandyuk.autobuddy.Garage.onNavigationItemSelected(Garage.java:1238)
2018-11-19 19:29:15.862 31659-31659/com.androidandyuk.autobuddy W/System.err:     at android.support.design.widget.NavigationView$1.onMenuItemSelected(NavigationView.java:170)
2018-11-19 19:29:15.862 31659-31659/com.androidandyuk.autobuddy W/System.err:     at android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:840)
2018-11-19 19:29:15.862 31659-31659/com.androidandyuk.autobuddy W/System.err:     at android.support.v7.view.menu.SubMenuBuilder.dispatchMenuItemSelected(SubMenuBuilder.java:90)
2018-11-19 19:29:15.862 31659-31659/com.androidandyuk.autobuddy W/System.err:     at android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:158)
2018-11-19 19:29:15.862 31659-31659/com.androidandyuk.autobuddy W/System.err:     at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:991)
2018-11-19 19:29:15.862 31659-31659/com.androidandyuk.autobuddy W/System.err:     at android.support.design.internal.NavigationMenuPresenter$1.onClick(NavigationMenuPresenter.java:352)
2018-11-19 19:29:15.862 31659-31659/com.androidandyuk.autobuddy W/System.err:     at android.view.View.performClick(View.java:6653)
2018-11-19 19:29:15.862 31659-31659/com.androidandyuk.autobuddy W/System.err:     at android.view.View.performClickInternal(View.java:6625)
2018-11-19 19:29:15.862 31659-31659/com.androidandyuk.autobuddy W/System.err:     at android.view.View.access$3100(View.java:786)
2018-11-19 19:29:15.862 31659-31659/com.androidandyuk.autobuddy W/System.err:     at android.view.View$PerformClick.run(View.java:26223)
2018-11-19 19:29:15.862 31659-31659/com.androidandyuk.autobuddy W/System.err:     at android.os.Handler.handleCallback(Handler.java:891)
2018-11-19 19:29:15.862 31659-31659/com.androidandyuk.autobuddy W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:102)
2018-11-19 19:29:15.862 31659-31659/com.androidandyuk.autobuddy W/System.err:     at android.os.Looper.loop(Looper.java:207)
2018-11-19 19:29:15.862 31659-31659/com.androidandyuk.autobuddy W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:7470)
2018-11-19 19:29:15.862 31659-31659/com.androidandyuk.autobuddy W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
2018-11-19 19:29:15.862 31659-31659/com.androidandyuk.autobuddy W/System.err:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
2018-11-19 19:29:15.862 31659-31659/com.androidandyuk.autobuddy W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:958)

Then, with a backed up database that works fine on other phones, the import wont work either -

Code:
public static void importDB() {
        Log.i("ImportDB", "Started");
        try {
            String DB_PATH = "/data/data/com.androidandyuk.autobuddy/databases/Vehicles";

            File sdcard = Environment.getExternalStorageDirectory();
            String yourDbFileNamePresentInSDCard = sdcard.getAbsolutePath() + File.separator + "AutoBuddy/Vehicles.db";

            Log.i("ImportDB", "SDCard File " + yourDbFileNamePresentInSDCard);

            File file = new File(yourDbFileNamePresentInSDCard);
            // Open your local db as the input stream
            InputStream myInput = new FileInputStream(file);

            // Path to created empty db
            String outFileName = DB_PATH;

            // Opened assets database structure
            OutputStream myOutput = new FileOutputStream(outFileName);

            // transfer bytes from the inputfile to the outputfile
            byte[] buffer = new byte[1024];
            int length;
            while ((length = myInput.read(buffer)) > 0) {
                myOutput.write(buffer, 0, length);
            }

            // Close the streams
            myOutput.flush();
            myOutput.close();
            myInput.close();
        } catch (Exception e) {
            Log.i("ImportDB", "Exception Caught" + e);
        }
        loadBikes();
        Fuelling.loadFuels();
        Maintenance.loadLogs();
        ToDo.loadToDos();
        Context context = App.getContext();
        Toast.makeText(context, "Data Imported. Close app and reopen", Toast.LENGTH_LONG).show();
        if (bikes.size() > 0) {
            activeBike = 0;
        }
    }

public void importDB2() {

        Uri selectedUri = Uri.parse(Environment.getExternalStorageDirectory().getPath() + "/AutoBuddy/");
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
//        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setDataAndType(selectedUri, "*/*");
        Intent i = Intent.createChooser(intent, "File");
        startActivityForResult(i, CHOOSE_FILE_REQUESTCODE);
    }

 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        switch(requestCode){
            case CHOOSE_FILE_REQUESTCODE:
                if(resultCode==-1){
                    Uri uri = data.getData();
                    String yourDbFileNamePresentInSDCard = uri.getPath();

                    //int index = yourDbFileNamePresentInSDCard.indexOf(":");
                    //if(index > 0) {
                    //    yourDbFileNamePresentInSDCard = yourDbFileNamePresentInSDCard.substring(index+1);
                    //}

                    Log.i("ImportDB", "Started");
                    try {
                        String DB_PATH = "/data/data/com.androidandyuk.autobuddy/databases/sessions";

//                        File sdcard = Environment.getExternalStorageDirectory();
//                        yourDbFileNamePresentInSDCard = sdcard.getAbsolutePath() + File.separator + "LapTimerBuddy/LapTimer.db";

                        Log.i("ImportDB", "SDCard File " + yourDbFileNamePresentInSDCard);

                        File file = new File(yourDbFileNamePresentInSDCard);
                        // Open your local db as the input stream
                        InputStream myInput = new FileInputStream(file);

                        // Path to created empty db
                        String outFileName = DB_PATH;

                        // Opened assets database structure
                        OutputStream myOutput = new FileOutputStream(outFileName);

                        // transfer bytes from the inputfile to the outputfile
                        byte[] buffer = new byte[1024];
                        int length;
                        while ((length = myInput.read(buffer)) > 0) {
                            myOutput.write(buffer, 0, length);
                        }

                        // Close the streams
                        myOutput.flush();
                        myOutput.close();
                        myInput.close();
                    } catch (Exception e) {
                        Log.i("ImportDB", "Exception Caught" + e);
                    }
                    loadBikes();
                    Fuelling.loadFuels();
                    Maintenance.loadLogs();
                    ToDo.loadToDos();
                    Context context = App.getContext();
                    Toast.makeText(context, "Data Imported. Close app and reopen", Toast.LENGTH_LONG).show();
                    if (bikes.size() > 0) {
                        activeBike = 0;
                    }
                }
                break;
        }


        super.onActivityResult(requestCode, resultCode, data);
    }

The logcat looks like this -

Code:
2018-11-19 19:39:04.036 3348-3348/com.androidandyuk.autobuddy I/ImportDB: Started
2018-11-19 19:39:04.037 3348-3348/com.androidandyuk.autobuddy I/ImportDB: SDCard File /storage/emulated/0/AutoBuddy/Vehicles.db
2018-11-19 19:39:04.039 3348-3348/com.androidandyuk.autobuddy I/Main Activity: New Bikes Loading
2018-11-19 19:39:04.039 3348-3348/com.androidandyuk.autobuddy I/Bikes Size: 0
2018-11-19 19:39:04.044 3348-3348/com.androidandyuk.autobuddy I/Bikes Restored: Count :0
2018-11-19 19:39:04.044 3348-3348/com.androidandyuk.autobuddy I/Retrieved info: Log count :0
2018-11-19 19:39:04.124 3348-3348/com.androidandyuk.autobuddy D/HwAppInnerBoostImpl: asyncReportData com.androidandyuk.autobuddy,2,2,1,4 interval=206
2018-11-19 19:39:04.124 3348-3348/com.androidandyuk.autobuddy I/ViewRootImpl: jank_removeInvalidNode all the node in jank list is out of time

So no errors. It doesn't say it can't find or access the file, it just seems to ignore the contents of it?

Any ideas?
 
Last edited:
I use Android Studio. The logcat is what I would usually use to see where it's failing, but I don't see why, hence I post them here.

The + File.separator + puts the correct file separator. I should probably change out other / for it too actually.
 
Fantastic, thanks. That did it. It doesn't actually ask for permissions again, but I guess it's the fact it checks it still has them at run time.

I can export and import on the Mi A2 Lite now (running stock) but the Huawei still wont import the perfectly fine database. The logcat is -

Code:
2018-11-22 09:43:07.358 13024-13024/com.androidandyuk.autobuddy I/ViewRootImpl: jank_removeInvalidNode all the node in jank list is out of time
2018-11-22 09:43:07.362 13024-13024/com.androidandyuk.autobuddy V/AudioManager: playSoundEffect   effectType: 0
2018-11-22 09:43:07.362 13024-13024/com.androidandyuk.autobuddy V/AudioManager: querySoundEffectsEnabled...
2018-11-22 09:43:07.363 13024-13024/com.androidandyuk.autobuddy I/ImportDB: Started
2018-11-22 09:43:07.364 13024-13024/com.androidandyuk.autobuddy I/ImportDB: SDCard File /storage/emulated/0/AutoBuddy/Vehicles.db
2018-11-22 09:43:07.366 13024-13024/com.androidandyuk.autobuddy I/Main Activity: New Bikes Loading
2018-11-22 09:43:07.366 13024-13024/com.androidandyuk.autobuddy I/Bikes Size: 0
2018-11-22 09:43:07.378 13024-13024/com.androidandyuk.autobuddy I/Bikes Restored: Count :0
2018-11-22 09:43:07.378 13024-13024/com.androidandyuk.autobuddy I/Retrieved info: Log count :0
2018-11-22 09:43:07.397 13024-13024/com.androidandyuk.autobuddy D/HwAppInnerBoostImpl: asyncReportData com.androidandyuk.autobuddy,2,1,1,0 interval=159
2018-11-22 09:43:07.469 13024-13024/com.androidandyuk.autobuddy D/HwAppInnerBoostImpl: asyncReportData com.androidandyuk.autobuddy,2,2,1,6 interval=231
2018-11-22 09:43:07.472 13024-13089/com.androidandyuk.autobuddy D/OpenGLRenderer:   HWUI Binary is  enabled
   
    --------- beginning of system
2018-11-22 09:43:07.485 13024-13089/com.androidandyuk.autobuddy D/mali_winsys: EGLint new_window_surface(egl_winsys_display *, void *, EGLSurface, EGLConfig, egl_winsys_surface **, EGLBoolean) returns 0x3000
2018-11-22 09:43:07.485 13024-13089/com.androidandyuk.autobuddy D/OpenGLRenderer:   HWUI Binary is  enabled
2018-11-22 09:43:07.654 13024-13024/com.androidandyuk.autobuddy D/HwAppInnerBoostImpl: asyncReportData com.androidandyuk.autobuddy,2,1,2,0 interval=416
2018-11-22 09:43:10.914 13024-13089/com.androidandyuk.autobuddy W/libEGL: EGLNativeWindowType 0x76f41cf010 disconnect failed
2018-11-22 09:43:10.928 1235-2380/? W/NotificationService: Toast already killed. pkg=com.androidandyuk.autobuddy callback=android.app.ITransientNotification$Stub$Proxy@2031e32
2018-11-22 09:43:15.404 1235-1659/? D/hw_netstat: total/5999/1982,com.google.android.keep/1891/1686,com.google.uid.shared:10015/2250/52,unknown:0/1570/0,com.android.vending/208/192,com.androidandyuk.autobuddy/80/52
2018-11-22 09:43:30.423 1235-1659/? D/hw_netstat: total/3866/1426,unknown:0/2252/80,com.google.uid.shared:10015/999/413,com.whatsapp/40/457,unknown:1051/341/67,com.huawei.appmarket/182/222,com.teslacoilsw.launcher/0/135,com.androidandyuk.autobuddy/52/52

Anyone with any ideas?
 
Last edited:
That's actually really interesting thanks, but no, I don't think it applies. That is about the really aggressive RAM management and how it shuts apps down dead when they are no longer in focus.
 
Hmm, I don't think that's it... I really appreciate your efforts to find the solution though!

For one, I don't have an option to change my default location like they show in the thread.

Also, it seems to find the file no problem. I can backup and it creates a file in the correct folder. I guess the only issue could be if it's trying to store the database in a different internal folder, but I'm not sure how I check that when I'm not rooted? In fact, backing up the Huawei database and trying to restore that on the Android One device doesn't seem to work, so I guess the issue is it having problems storing the database internally, not the reading and writing of it during backup and restore.
 
Everything looks to be okay when reading and writing the database internally. How can I check this line is correct -

Code:
String DB_PATH = "/data/data/com.androidandyuk.autobuddy/databases/Vehicles";

If I don't have root? Can I use ADB to snoop round and check that is where the Huawei stores the app data?
 
So I thought it was a Huawei thing, but now I find it wont restore on any device. This is a concern as I've been using this app for a year or so, recording fuel and maintenance on my vehicles. I don't really want to lose that info.

I decided to try fiverr.com to see if I could just pay someone to fix this and got into a conversation with a guy. He basically said my code was too messy to understand, which I do get. The app was only a few months in to my learning, I sometimes now struggle to understand what I was doing, but then in discussion I'm not sure if they guy was actually trolling me. He couldn't seem to understand the concept of backing up app data to move it to a new phone?!

Anyway, I'm now thinking I might have to simply re-write the app to backup and restore from Firebase on a users account. I guess the beauty of programming, I only really need to replace the backup and restore elements. It does annoy me though that I had it working and now it doesn't and I can't see why :(
 
You're not going to find a competent coder to fix it for a few quid.

No, I was thinking somewhere between £50-£100. I don't think they need to understand my code really. 'Here is the database, please write code to back it up and put it back again.' The code I had that worked before could basically be plugged in to any app with a database, it didn't matter what the structure of it was.

I've just thought, the phone it worked on last was on Android 8.1. I think the ones I've tried recently have all been 9.0, so I guess that's where it broke :(
 
Thanks for the offer but I've spent the evening working out Cloud Firestore and I think I'm ready to just implement that. It will kill two birds with one stone as it means you can log in and data will be stored in the cloud... which was kind of what I wanted anyway!

For now I'll just setup and export and import, I guess clearing the Store and writing info from the device each time in full. Very inefficient but the quickest way to get a backup/restore working again. Then I might look to record everything using the Firestore... but this might be too much work tbh.
 
Interesting, thanks. It could have been that, I've pulled all that code now. My new code using Cloud Firestore works better anyway, one button backup to the cloud is preferable I think and seems to work great.

Mind you, I might be the only person that cares. I just checked, just me and a mate that I know uses it have backed up. Still, it was mainly for me that I wanted it working anyway! I have years of data in this app now!
 
Back
Top Bottom