Retrieve database or any other file from the Internal Storage using run-as
Asked Answered
R

12

124

On a non-rooted android device, I can navigate to the data folder containing the database using the run-as command with my package name. Most files types I am content with just viewing, but with the database I would like to pull if from the android device.

Is there a download copy or move command from this part of adb shell? I would like to download the database file and view its content using a database browser.

One answer here involves turning entire application package into a compressed archive, but there is no further answer on how to extract that archive once this is done and moved to the machine, leaving me very sidetracked when there might be a more direct solution to begin with

Ricoricochet answered 27/8, 2013 at 17:19 Comment(2)
Try adb pull #8650907Colettecoleus
stackoverflow.com/questions/13006315 Pull database without rooting deviceHinduism
A
253

By design user build of Android (that's what you have on your phone until you unlock the bootloader and flash the phone with userdebug or eng software) restricts access to the Internal Storage - every app can only access its own files. Fortunately for software developers not willing to root their phones Google provides a way to access the Internal Storage of debuggable versions of their packages using run-as command.

To download the /data/data/debuggable.app.package.name/databases/file from an Android 5.1+ device run the following command:

adb exec-out run-as debuggable.app.package.name cat databases/file > file

To download multiple files in a folder under the /data/data/debuggable.app.package.name/ at once - use tar:

adb exec-out run-as debuggable.app.package.name tar c databases/ > databases.tar
adb exec-out run-as debuggable.app.package.name tar c shared_prefs/ > shared_prefs.tar
Agile answered 27/8, 2013 at 17:41 Comment(22)
Or, just use run-as to copy the file to a spot on external storage, and pull the database file from there, rather than messing around with file permissions.Heddie
The run-as has no permission to write to the sdcard - there is something new added with the latest update... :(Scholar
When I run adb shell "run-as package.name chmod 666 /data/data/package.name/databases/file" adb ends me error -->run-as: exec failed for chmod666 Error:Permission denied . I'm in Nexus 7 without rootBusinesslike
Write access to external sd card is no longer possible with adb.Scholar
Did you check if this depends on the permissions of the app you run as?Squad
When transferring my database using "adb exec-out run-as package.name cat databases/file > file", I'm getting extra line-breaks (CR LF), making the file unreadable by sqliteman. Looks like the file is being copied as text rather than binary. Is there any way to fix it?Feldspar
@GyumFox, double check Android version of your device. The whole purpose of adb exec-out is to run a shell command without tty so it would not mangle the output.Agile
in case anyone else is confused about the "exec out" command: exec out makes the adb command running on your computer return whatever it is that the shell on Android "returns". That means that the pipe ( "> file" ) happens on your computer, not the Android device. "file" will then be a file in the current dir from where you ran the adb command on your computer.Complain
So this seems to work for me, but the file that I get, is a few hundred bytes different in size. This is if I cat the output to my local shell. If I redirect the output of cat to a file on the device (e.g. "/sdcard/out.db", I get just a 0-byte-sized file.Complain
@AlexP., I think the issue is with the cat command, which copies the content of the file as text, rather than binaryFeldspar
The only solution that worked for me. I mean the one for Android 5.0+Filler
This doesn't work for me because the cmd output is: File is in use by a different process. Is there a way around this? I'm running a service that constantly writes to the DB. But even if I deactivate the app, it does not work. Any help?Semiautomatic
@Semiautomatic You might want to try going to Developer Options (on the phone) then Running Services, find your app/service and kill it from there.Irradiant
@AlexP. The 5.0+ worked like a charm for me, but what if we have reverse situation and want to put db from our pc to application? I tried: adb exec-in run-as my.application cat mydbname.db > databases/intouchDatabase with no luck it just says 'The system cannot find the path specified.' I coulnd't find much about exec-in tbh, also i suspect it cannot find the mydbname.db location.Dubenko
@AlexP. I've already seen that post, it's not exactly reverse as you just move files from sdcard not the pc, when I'm trying following: adb shell run-as my.application cp mydbname.db databases/mydb I am getting following response: cp mydbname.db: No such file or directoryDubenko
@AlexP. I tried moving the db to sdcard with adb push mydbname.db /sdcard/mydbname.db and then using cp and now I am getting /sdcard/mydbname.db: Permission denied. I checked the permissions on sdcard and its -rwxrwx--- root (my phone is not rooted). I remember when I had older phone android 4.2.2 there were absolutely no problems with accessing stuff on sdcard. But when adb pull /sdcard/mydbname mydbname it works without any problems.Dubenko
I am having trouble with the execution of the exec-out command on an Samsung device running 6.0. I get a plain text document file which a can't view with sqlitebrowser for example. Can anyone help?Circumspect
If you are finding that you are getting back a blank or nearly blank file, you may find that the file is simply an error from the console that has been redirected to this file that you have created. A frequent issue here is that you are trying to copy a DB from the Release variant of your app. You can only copy DBs from the Debug variant of your app. If this happens, just install the debug variant and try the command again. Hope this helps someone.Lights
In my case Marshamallow it does not show any error, but file not found anywhere in internal sd card. where does it pull the file. Please help me out !!!Fenella
Not work for Windows 10 (64 bit), Android 6.0. File db pull from device but it's empty.Wilsey
Note run-as is broken on recent Samsung phones. Works great on pixel, LG, HTC, Sony, etcIdonah
Note that adb exec-out seems to capture stderr on the device and prints it to stdout locally. That means that if tar prints error messages (e.g. if you give it an absolute path), they'll end up in the generated .tar file and make it malformed.Animal
W
75

The accepted answer doesn't work anymore for me (blocked by Android?)

So instead I did this:

> adb shell
shell $ run-as com.example.package
shell $ chmod 666 databases/file
shell $ exit                                               ## exit out of 'run-as'
shell $ cp /data/data/package.name/databases/file /sdcard/
shell $ run-as com.example.package
shell $ chmod 600 databases/file
> adb pull /sdcard/file .
Win answered 17/2, 2015 at 9:24 Comment(10)
This should be the new correct answer OR @Alex P. you should add this answer for newer Android versions. Also in my case I had to use 777 and apply it to the database-directory first/as-well before I could access the db file.Millisent
My device is rooted, but I found I still need to run su to get the run-as command working.Request
What if you don't have SD card?Feldspar
if you don't have an SD card, there's still a "sdcard" directory anyways.Complain
This is the new answer for 5.0+ Android Devices. If I could I would upvote this answer 5 times.Irreligious
Another solution that helps even for non-debuggable applications is described there: android.stackexchange.com/a/50411/96640.Haemal
Can I create a db file outside a device, manually create 'databases' directory inside the device, and copy the db file into the directory?Fatshan
you can, just use run-as <package> when you need to act in behalf of the appWin
Great!. it worked for me too. Can we make a batch/shell file? just passing db file name as param and we have the db file.Pentheam
By following these step i got the db file. But after that my app is getting crashed after some time in same device only. App is working perfectly in other devices.Pernickety
S
32

If anyone looking for pulling database from debug application may use the procedure below:

  1. search and open device file explorer

search and open device file explorer

  1. Select your handset and then browse to data/data directory

go to data/data directory

  1. Now find your application package and go to databases folder. You can see the databases there and upon right click, you will get option to save this in your drive.

enter image description here

Sondrasone answered 30/7, 2018 at 5:22 Comment(6)
Wow, so much easier and safer compared to using adb-shellDanndanna
In Android Studio 4.1.3 View->Tool Windows->Device File ExplorerMeeker
Easiest way! Thank you!Nae
Best easiest working way !Houston
Hi, this is nice way to get a file from device. But can I do this without opening or creating a project?Resigned
You can do it with any debug application.Sondrasone
H
9

I've published a simple shell script for dumping databases:

https://github.com/Pixplicity/humpty-dumpty-android

It performs two distinct methods described here:

  1. First, it tries to make the file accessible for other users, and attempting to pull it from the device.
  2. If that fails, it streams the contents of the file over the terminal to the local machine. It performs an additional trick to remove \r characters that some devices output to the shell.

From here you can use a variety of CLI or GUI SQLite applications, such as sqlite3 or sqlitebrowser, to browse the contents of the database.

Herefordshire answered 8/4, 2015 at 19:16 Comment(2)
This script is for debuggable applications, how about if app is not debuggable?Floreneflorentia
Your only options are likely to use backup tools, if the app in question exposes that data as part of a backup. Beyond that, I'm afraid it would require elevated permissions.Herefordshire
A
7

I couldn't get anything else to work for me but this:

adb shell
run-as package.name
cat /databases/databaseFileName.db > /sdcard/copiedDatabaseFileName.db
exit
exit
adb pull /sdcard/copiedDatabaseFileName.db /file/location/on/computer/

The first exit is to exit out of the run-as, the second exit is to exit out of adb shell to do the pull.

Admonitory answered 27/6, 2017 at 15:46 Comment(0)
P
5

For app's debug version, it's very convenient to use command adb exec-out run-as xxx.yyy.zzz cat somefile > somefile to extract a single file. But you have to do multiple times for multiple files. Here is a simple script I use to extract the directory.

#!/bin/bash
P=
F=
D=

function usage()
{
    echo "$(basename $0) [-f file] [-d directory] -p package"
    exit 1
}

while getopts ":p:f:d:" opt
do
    case $opt in
        p)
            P=$OPTARG
            echo package is $OPTARG
            ;;
        f)
            F=$OPTARG
            echo file is $OPTARG
            ;;
        d)
            D=$OPTARG
            echo directory is $OPTARG
            ;;
        \?)
            echo Unknown option -$OPTARG
            usage
            ;;
        \:)
            echo Required argument not found -$OPTARG
            usage
            ;;
    esac
done

[ x$P == x ] && {
    echo "package can not be empty"
    usage
    exit 1
}

[[ x$F == x  &&  x$D == x ]] && {
    echo "file or directory can not be empty"
    usage
    exit 1
}

function file_type()
{
    # use printf to avoid carriage return
    __t=$(adb shell run-as $P "sh -c \"[ -f $1 ] && printf f || printf d\"")
    echo $__t
}

function list_and_pull()
{
    t=$(file_type $1)
    if [ $t == d ]; then
        for f in $(adb shell run-as $P ls $1)
        do
            # the carriage return output from adb shell should
            # be removed
            mkdir -p $(echo -e $1 |sed $'s/\r//')
            list_and_pull $(echo -e $1/$f |sed $'s/\r//')
        done
    else
        echo pull file $1
        [ ! -e $(dirname $1) ] && mkdir -p $(dirname $1)
        $(adb exec-out run-as $P cat $1 > $1)
    fi
}

[ ! -z $D ] && list_and_pull $D
[ ! -z $F ] && list_and_pull $F

Hope it would be helpful. This script is also available at gist.

Typical usage is

$ ./exec_out.sh -p com.example.myapplication -d databases

then it will extract all files under your apps databases directory, which is /data/data/com.example.myapplication/databases, into current directory.

Polymeric answered 12/4, 2016 at 6:21 Comment(1)
even for multiple files it is still just a single command. check the update https://mcmap.net/q/87735/-retrieve-database-or-any-other-file-from-the-internal-storage-using-run-as if you would prefer you could also add another pipe on the host side to unpack the filesAgile
M
3

Much much simpler approach to download the file onto your local computer:

In your PC shell run:

adb -d shell 'run-as <package_name> cat /data/data/<package_name>/databases/<db_name>' > <local_file_name>
Mahaliamahan answered 8/11, 2017 at 21:26 Comment(2)
Pretty close but this pulls out a malformed db for me.Vagrancy
I had to skip the -d in my case, otherwise this is the way I always look for (i.e. google for) when trying to pull a file.Lawhorn
K
1
#!/bin/bash
#export for adb
export PATH=$PATH:/Users/userMe/Library/Android/sdk/platform-tools
export PATH=$PATH:/Users/userMe/Library/Android/sdk/tools

adb -d shell 'run-as com.android.app  cp /data/data/com.android.app/files/db.realm /sdcard'
adb pull sdcard/db.realm /Users/userMe/Desktop/db

You can use this script for get Realm database.

Kerrison answered 26/10, 2018 at 6:48 Comment(0)
N
1

The database file is emtpy when using adb run-as. This can be resolved by calling close() on the RoomDatabase instance. Call close() to let SQLite write its journal to disk. I've created this button that closes the database connection on request:

via GIPHY

Here is how to call close on the RoomDatabase instance.

Nomen answered 12/5, 2019 at 7:54 Comment(1)
I was facing the issue : DB copied but not with the latest data. Closing the db connection before db file copy fixed my problem.Askwith
A
1

Steps to pull app db(installed in debug mode) from device

Close DB connection if opened

Open cmd (command prompt) (Change dir to your adb path)

cd C:\Program Files (x86)\Android\android-sdk\platform-tools

(list the app files)

adb -d shell "run-as com.xyz.name ls /data/data/com.xyz.name/files/"

(copy required file to sdcard)

adb -d shell "run-as com.xyz.name cp /data/data/com.xyz.name/files/abc.db /sdcard/abc.db"

(copy from sdcard to machine adb folder)

adb pull /sdcard/abc.db

Open DB connection

Destination file path in my case C:\Users{userName}\AppData\Local\VirtualStore\Program Files (x86)\Android\android-sdk\platform-tools Or Device storage

Askwith answered 29/10, 2020 at 11:16 Comment(0)
C
0

Here's a solution that works on a device running Android 5.1. The following example is for Windows.

You need sed (or sed.exe on windows, e.g. from cygwin.) ( On Unix, it'll just be there ;) ). To remove bad '\r' characters, at least on windows.

Now just run the following command:

adb exec-out "run-as com.yourcompany.yourapp /data/data/com.yourcompany.yourapp/databases/YourDatabaseName" | c:\cygwin\bin\sed.exe 's/\x0D\x0A/\x0A/'>YourDatabaseName.db

The sed command strips out trailing /r characters.

Of course you should replace "com.yourcompany.yourapp" with the package name of the app and "YourDatabaseName" with the name of the database in the app.

Complain answered 23/9, 2015 at 22:25 Comment(0)
B
0

If someone is looking for another answer that can be used to retrieve Database as well as Shared Preferences then follow this step:

In your build.gradle file of your app add line

debugCompile 'com.amitshekhar.android:debug-db:1.0.0'

now when you run your app in non-release mode then your app will automatically open 8080 port from your device IP address make sure your device is connected via wifi and your laptop is sharing the same network. Now simply visit the url

http://your_mobile_device_ip:8080/

to watch all data of database along with shared preferences.

Borchert answered 26/6, 2018 at 6:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.