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

AndroidDatabaseAndroid SqliteAdbInternal Storage

Android Problem Overview


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

Android Solutions


Solution 1 - Android

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

Solution 2 - Android

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 .

Solution 3 - Android

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

> 2. Select your handset and then browse to data/data directory

go to data/data directory

> 3. 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

Solution 4 - Android

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.

Solution 5 - Android

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.

Solution 6 - Android

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.

Solution 7 - Android

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>

Solution 8 - Android

#!/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.

Solution 9 - Android

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:

https://giphy.com/gifs/KZYnGwVh8ICN73jXod">via GIPHY

Here is how to call close on the RoomDatabase instance.

Solution 10 - Android

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

Solution 11 - Android

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.

Solution 12 - Android

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCQMView Question on Stackoverflow
Solution 1 - AndroidAlex P.View Answer on Stackoverflow
Solution 2 - AndroidmarmorView Answer on Stackoverflow
Solution 3 - AndroidIftaView Answer on Stackoverflow
Solution 4 - AndroidPaul LammertsmaView Answer on Stackoverflow
Solution 5 - AndroidTriplee121View Answer on Stackoverflow
Solution 6 - AndroidalijandroView Answer on Stackoverflow
Solution 7 - AndroidEmreView Answer on Stackoverflow
Solution 8 - AndroiddralexnumberView Answer on Stackoverflow
Solution 9 - AndroidEimertView Answer on Stackoverflow
Solution 10 - AndroidSuchithView Answer on Stackoverflow
Solution 11 - AndroidtreesAreEverywhereView Answer on Stackoverflow
Solution 12 - AndroidPradeep Kumar KushwahaView Answer on Stackoverflow