How to check database on not rooted android device
Asked Answered
T

11

19

I am developing an app where i am using sqllite3 database to store values. I have Nexus S and Nexus 7 both are unrooted devices. How can i get the database for my app for debugging purpose.

I have tried (1) I have tried all approach mentioned here

adb shell
run-as app.package.name \
cp /data/data/package.name/databases/application.sqlite /sdcard/
exit
adb pull /sdcard/application.sqlite ~/

This says cp not found..

(2) http://developer.android.com/tools/help/adb.html#sqlite

adb -s emulator-5554 shell
# sqlite3 /data/data/com.example.google.rss.rssexample/databases/rssitems.db
SQLite version 3.3.12
Enter ".help" for instructions
.... enter commands, then quit...
sqlite> .exit 
Tan answered 26/7, 2013 at 14:3 Comment(2)
https://mcmap.net/q/87735/-retrieve-database-or-any-other-file-from-the-internal-storage-using-run-asDisserve
https://mcmap.net/q/103729/-android-pulling-sqlite-database-android-device check my answer here it will solve your problem.Joshuajoshuah
P
30

You can write your database to the external memory with the following:

private void writeToSD() throws IOException {
    File sd = Environment.getExternalStorageDirectory();

    if (sd.canWrite()) {
        String currentDBPath = DB_NAME;
        String backupDBPath = "backupname.db";
        File currentDB = new File(DB_PATH, currentDBPath);
        File backupDB = new File(sd, backupDBPath);

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

Where DB_NAME is the name of my database and DB_PATH is defined as follows:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        DB_PATH = context.getFilesDir().getAbsolutePath().replace("files", "databases") + File.separator;
    }
    else {
        DB_PATH = context.getFilesDir().getPath() + context.getPackageName() + "/databases/";
    }

And add the following permission (Thanks to @Sathesh for pointing this out):

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

I call this method anytime I have a database write so that my most current database file is in the external memory and I can view it and debug from there.

Then you can use the X-Plore app to view the database from the external memory right on the Android device.

Prosecution answered 26/7, 2013 at 14:8 Comment(9)
You need to add the external storage permission <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />. You can use the "context.getDatabasePath(dbName).toString()" to get the dbpath programaticallyGessner
I am getting a FILE NOT FOUND exception for the original DB file. I have a unrooted nexus 4. I have cross-checked the path.Transcurrent
@Transcurrent Are you sure that the database name and path are correct in your calls?Prosecution
pretty sure. I even checked it by browsing the app directory through run-as command on ADB shell. I also changed the permissions for the original db fileTranscurrent
@Transcurrent That is odd... Sounds like the file is somewhere other than where you think or it is not created which seems unlikely...Prosecution
@Prosecution when I step through the code in the debugger, the if currentDb.exists() is false and so the block is never executed. I even closed the db after creating it.Inefficient
@likejiujitsu you may want to double check the path to the data base then.Prosecution
@Prosecution It worked after I changed it to String currentDBPath = m_Context.getDatabasePath(DATABASE_NAME).toString(); File currentDB = new File(currentDBPath); and, I found it in /sdcard!Inefficient
@likejiujitsu great! I was going to say that there are a few ways to define how you get the database path. glad it worked.Prosecution
C
36

The following solution works only for apps that are debuggable. It may not work well on all devices, since ​​run-as command doesn't work on some devices, especially with Jelly Bean.

  1. ​Create a *.bat file and copy the following scripts ​​

    adb shell run-as [package] chmod 777 /data/data/[package]/databases/

    adb shell run-as [package] chmod 777 /data/data/[package]/databases/[db_file_name]

    adb shell run-as [package] cp /data/data/[package]/databases/[db_file_name] /sdcard/

    adb pull /sdcard/[db_file_name]

  2. ​Change [package] to the desired application package

  3. Change [db_file_name] to the desired db name Run the bat file and you should see the copied database in the same folder as the bat file

The above solution assumes:

  • You are working on Windows
  • The device is connected and visible under "adb devices"
Cicatrize answered 25/3, 2015 at 14:1 Comment(3)
How do I find db_file_name. It sais No such file or directorySynopsis
@SergeyDirin you need to change the name to the actual file name that you set up in your appCicatrize
No in my case the database was located in /data/Users/[package]/databases/ if I remember it coreclty. You can find the exact location with getApplicationContext().getDatabasePath(DATABASE_NAME)Synopsis
P
30

You can write your database to the external memory with the following:

private void writeToSD() throws IOException {
    File sd = Environment.getExternalStorageDirectory();

    if (sd.canWrite()) {
        String currentDBPath = DB_NAME;
        String backupDBPath = "backupname.db";
        File currentDB = new File(DB_PATH, currentDBPath);
        File backupDB = new File(sd, backupDBPath);

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

Where DB_NAME is the name of my database and DB_PATH is defined as follows:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        DB_PATH = context.getFilesDir().getAbsolutePath().replace("files", "databases") + File.separator;
    }
    else {
        DB_PATH = context.getFilesDir().getPath() + context.getPackageName() + "/databases/";
    }

And add the following permission (Thanks to @Sathesh for pointing this out):

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

I call this method anytime I have a database write so that my most current database file is in the external memory and I can view it and debug from there.

Then you can use the X-Plore app to view the database from the external memory right on the Android device.

Prosecution answered 26/7, 2013 at 14:8 Comment(9)
You need to add the external storage permission <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />. You can use the "context.getDatabasePath(dbName).toString()" to get the dbpath programaticallyGessner
I am getting a FILE NOT FOUND exception for the original DB file. I have a unrooted nexus 4. I have cross-checked the path.Transcurrent
@Transcurrent Are you sure that the database name and path are correct in your calls?Prosecution
pretty sure. I even checked it by browsing the app directory through run-as command on ADB shell. I also changed the permissions for the original db fileTranscurrent
@Transcurrent That is odd... Sounds like the file is somewhere other than where you think or it is not created which seems unlikely...Prosecution
@Prosecution when I step through the code in the debugger, the if currentDb.exists() is false and so the block is never executed. I even closed the db after creating it.Inefficient
@likejiujitsu you may want to double check the path to the data base then.Prosecution
@Prosecution It worked after I changed it to String currentDBPath = m_Context.getDatabasePath(DATABASE_NAME).toString(); File currentDB = new File(currentDBPath); and, I found it in /sdcard!Inefficient
@likejiujitsu great! I was going to say that there are a few ways to define how you get the database path. glad it worked.Prosecution
A
11

Here's a much simple and straightforward answer: (Tested on Android one: unrooted)

adb -d shell 
$ run-as my.package.name
$ cp databases/mydatabase.db /sdcard/mydatabase.db
$ exit
$ exit

now pull your database to the default adb path

adb -d pull /sdcard/mydatabase.db

or, to your Desktop for e.g.

adb -d pull /sdcard/mydatabase.db C:\Users\user\Desktop

you may want to remove the copy with a command below:

adb -d shell "rm /sdcard/mydatabase.db"

-d option chooses the default device if having more than one emulator.

Agoraphobia answered 2/10, 2016 at 4:12 Comment(1)
Thanks. I had use the command cp files/mydatabase.db /sdcard/mydatabase.dbMillican
C
10

If you don't know your application path then you can use this:

public void copyAppDbToExternalStorage() throws IOException {
    File sd = Environment.getExternalStorageDirectory();
    File currentDB = getApplicationContext().getDatabasePath("databaseName"); //databaseName=your current application database name, for example "my_data.db"
    if (sd.canWrite()) {
        File backupDB = new File(sd, "toDatabaseName"); // for example "my_data_backup.db"
        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();
        }
    }
}

Or if you need copy database to public "Download" folder then you can use this:

public void copyAppDbToDownloadFolder() throws IOException {
    File backupDB = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "toDatabaseName"); // for example "my_data_backup.db"
    File currentDB = getApplicationContext().getDatabasePath("databaseName"); //databaseName=your current application database name, for example "my_data.db"
    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();
    }
}

This is working perfectly on my Nexus 4 device.

Coenobite answered 27/12, 2013 at 4:37 Comment(0)
E
3

I just had to do something like this and there is a way to do it, although it's a pain. You need to cat the file as the application's user account, and then pipe it to a writable location. This worked for me on my Nexus 4 running 4.3.3:

adb shell "run-as org.your.application cat /data/data/org.your.application/your-file > /mnt/sdcard/your-file"
adb pull /mnt/sdcard/your-file
Emblazonment answered 28/5, 2014 at 18:21 Comment(5)
Database files are stored in /data/data/<your-app-package>/ databases /<your-db-filename>Perfumer
Also using cat, wrote a blank file. I used cp <src> <dest> to get it worked.Perfumer
This also only works with a debug build. Trying to run-as a release build gives run-as: Package '<packagename>' is not debuggableWaltman
this is a working solution if you follow all 3 comments, works for me on Nexus 5X today! too bad OP does not update answer or I would +1 it ... thanks to first 3 commentors, @Ted Mielczarek, if you update answer you will get well deserved up votesWorthwhile
Not sure if there has been increased security changes but this results in the sdcard file being zero bytes for some reason when I tried it on android OJuneberry
V
3

Try using stetho Library developed by facebook , it enables you to view the db via the web browser https://facebook.github.io/stetho/

Venus answered 16/2, 2016 at 12:11 Comment(0)
N
0
adb shell "run-as CHR.Droid chmod 666 /data/data/CHR.Droid/files/CHR.db"
adb shell cp /data/data/CHR.Droid/files/CHR.db /sdcard/

In Xamrin.forms I had to replace databases to files

Nimrod answered 20/6, 2016 at 14:54 Comment(0)
M
0

If after running

adb shell "run-as your.package.name"

you receive "run-as: Package 'your.package.name' is unknown", then try to get a database from emulator. See here: https://mcmap.net/q/103729/-android-pulling-sqlite-database-android-device

In Android Studio 3.0 click View > Tool Windows > Device File Explorer. Expand /data/data/[package-name] nodes.

Monosyllable answered 25/12, 2017 at 16:47 Comment(0)
D
0

I think that this is the easiest way. Add this dependency to your gradle file: debugImplementation 'com.amitshekhar.android:debug-db:1.0.0'

After this when you will start your application in your console you can see the message: D/DebugDB: Open http://192.168.1.114:8080 in your browser

And there is your database.

Doorn answered 10/12, 2018 at 15:29 Comment(0)
T
-2

You cannot access /data folder on not-rooted device

There is no way to do that. Android has great security mechanisms. Only your app can access its own files.

Tahr answered 26/7, 2013 at 14:9 Comment(2)
You can still copy the database to somewhere outside of /data and view it there...Prosecution
+1 it's hard to get the app data when the device is unrooted and the application is in non debug mode... even using run-as its will fail...Trapezoid
B
-2

It isn't possible from a non-rooted phone. You cannot access the /data directory, so you can't copy the database or use sqlite app as in (2). If you need to debug, use the simulator, or from your app run queries to inspect the database.

Behind answered 26/7, 2013 at 14:9 Comment(3)
You can still copy the database to somewhere outside of /data and view it there...Prosecution
@Prosecution True you can do that from your app, but there are times when you aren't able to modify the source. Since OP is able to modify the source, your answer is best.Behind
Right, if it were someone else's app then no way you could view the database.Prosecution

© 2022 - 2024 — McMap. All rights reserved.