Debugging sqlite database on the device - android

I am presently working on an WiFi application for Android. I am having trouble trying to access the database on the device. Debugging in the emulator doesn't work for me, because there is no WiFi support in the emulator. I tried pulling the database file out of the device by using
adb pull data/data/package-name/databases/database-name
But I get the error "Permission denied.".
In this answer Android: Where are database files stored?, Commonsware has suggested to pull database file by running in debug mode. But it doesn't work too. Any help on how to debug the database without rooting the device would be much appreciated.

I'll repeat myself from another answer:
Starting from API level 8 (Android 2.2), if you build the application as debuggable, you can use the shell run-as command to run a command or executable as a specific user/application or just switch to the UID of your application so you can access its data directory.
So if you wish to pull your application database from the device you should run the debug build of the application, connect with adb shell and run the following command:
run-as com.yourpackage sh -c "cat ~/databases/db-file" > /sdcard/db-file.sqlite
This will copy your db-file to the root of your SD card / external storage. Now you can easily get it from there by using file manager, adb pull or whatever else you like. Note that with this approach, there is NO need for your app to have WRITE_EXTERNAL_STORAGE permission, as the copying is done by the shell user who can always write to the external storage.
On Linux/Mac systems there is a possibility to copy a database directly to your computer with the following command one can use without entering the adb shell:
adb shell 'run-as com.yourpackage sh -c "cat ~/databases/db-file"' > db-file.sqlite
This however will not work correctly on Windows because of CR/LF symbols conversion. Use the former method there.

I use this shell script on my MAC, that copies database directly to my home folder. Easy one click solution, just change package name (com.example.app) and database name (database.sqlite)
Simple Script
#!/bin/bash
adb -d shell 'run-as com.example.app cat /data/data/com.example.app/databases/database.sqlite > /sdcard/database.sqlite'
adb pull /sdcard/database.sqlite ~/
Script which accepts arguments [package_name] [database]
#!/bin/bash
REQUIRED_ARGS=2
ADB_PATH=/Users/Tadas/Library/sdk/platform-tools/adb
PULL_DIR="~/"
if [ $# -ne $REQUIRED_ARGS ]
then
echo ""
echo "Usage:"
echo "android_db_move.sh [package_name] [db_name]"
echo "eg. android_db_move.sh lt.appcamp.impuls impuls.db"
echo ""
exit 1
fi;
echo""
cmd1="$ADB_PATH -d shell 'run-as $1 cat /data/data/$1/databases/$2 > /sdcard/$2' "
cmd2="$ADB_PATH pull /sdcard/$2 $PULL_DIR"
echo $cmd1
eval $cmd1
if [ $? -eq 0 ]
then
echo ".........OK"
fi;
echo $cmd2
eval $cmd2
if [ $? -eq 0 ]
then
echo ".........OK"
fi;
exit 0

The best way to view and manage you android app database is to use this library https://github.com/sanathp/DatabaseManager_For_Android
With this library you can manage your app SQLite database from you app itself.
you can view the tables in your app database , update ,delete, insert rows to your tables .Everything from your app.
Its a single java activity file ,just add the java file to your source folder.When the development is done remove the java file from your src folder thats it .
It helped me a lot .Hope it helps you too .
You can view the 1 minute demo here : http://youtu.be/P5vpaGoBlBY

Although, it's an old question I think it's still relevant and deserves a current state answer. There are tools available, which allow you to inspect databases directly (without the need to pull them from the device or emulator).
The tool, I most recently discovered (and favor most) is Android Debug Database.
You only need to add this dependency:
debugImplementation 'com.amitshekhar.android:debug-db:1.0.3'
No further code is required.
After you started your app, open logcat and filter for "DebugDB" and you will find a message saying
D/DebugDB: Open http://192.168.178.XXX:8080 in your browser
It works with every browser and you can inspect your database tables and shared preferences.
It also works with the default and the Genymotion emulators.
The tool I used before is stetho.
Downside: You need to add a bit of code and you are bound to the Chrome browser.
Advantage: You have the option to also inspect network traffic.

In the new Android Studio 4.1 there is the new Database Inspector.
You can select the following options from the menu bar View > Tool Windows > Database Inspector to open it (App Inspector in Android Studio 4.2). More detailed instructions can be found in this blog and in Exploring the Database Inspector in Android Studio medium article.
Another way is to use stetho for this. You add the dependency and then can use the Chrome DevTools ( chrome://inspect ) to check the database when the device is plugged in.

In my application I export the database to the SD card. Once the database is on the SD card it can be accessed by plugging the device into your computer.
Look at this post: Making a database backup to SDCard on Android

If you get
The system cannot find the path specified.
try
adb -d shell "run-as com.yourpackage cat /data/data/com.yourpackage/databases/dbname.sqlite > /sdcard/dbname.sqlite"
Note the double quote!

I simply did:
$ adb shell
shell#android:/ $ run-as myapp.package.name sh
shell#android:/data/data/myapp.package.name $
Then I can debug an sqlite database or whatever I wanna do from shell with the right permissions.

Android Studio 4.1 Added a new feature to view/ edit Android SQLite databases.
How to open Database Inspector
To open the Database Inspector in Android Studio, you need to select View > Tool Windows > Database Inspector from the menu bar.
Also you need to run the app to a device running API level 26 or higher.
Using this tool you can
Query your databases
Modify and debug your database

There is a way if an apk is debuggable to use a program called run-as from the (non-root) adb shell to copy an application's private file.

Here is step by step instructions - mostly taken from a combination of the other answers. This works with devices that are not unlocked.
Connect your device and launch the application in debug mode.
Copy the database file from your application folder to your sd card: execute:
./adb -d shell 'run-as com.yourpackge.name cat /data/data/com.yourpackge.name/databases/filename.sqlite > /sdcard/filename.sqlite'
Pull the database files to your machine: execute:
./adb pull /sdcard/ execute: ./adb
Install Firefox SQLLite Manager: https://addons.mozilla.org/en-US/firefox/addon/sqlite-manager/
Open Firefox SQLLite Manager and open your database file from step 3 above.
Enjoy!

You need to be running adb as root, or be using it on a rooted phone.
To run adb as root, use adb root
See also: Why do I get access denied to data folder when using adb?

None of the run-as-and-cat-to-sdcard solutions worked for me on Android 4.4.2. I'm not sure, but I suspect it may be due to the run-as tool not correctly handling the new sdcard_r and sdcard_rw permissions.
I first had to copy the database file to /files in my application's private internal storage:
shell#hammerhead:/ $ run-as com.example.myapp
shell#hammerhead:/data/data/com.example.myapp $ cp databases/mydb files/mydb
Then I copied to /sdcard/Android/data/com.example.myapp/files in Javaland (this requires the WRITE_EXTERNAL_STORAGE permission):
public class MainActivity extends BaseActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
...
if (isExternalStorageWritable()) {
final FileInputStream input;
try {
input = openFileInput("mydb");
File output = new File(getExternalFilesDir(null), "mydb");
copy(input, output);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void copy(FileInputStream in, File dst) throws IOException {
OutputStream out = new FileOutputStream(dst);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
return Environment.MEDIA_MOUNTED.equals(state);
}
}
Finally, I copied the file to my laptop:
$ adb pull /sdcard/Android/data/com.example.myapp/files/mydb

My Device was not having sdcard so the first solution did not work for me.
If you are having similar issue try like this:
adb shell "run-as package chmod 777 /data/data/package/databases/yourdb.sqlite";
adb pull /data/data/package/databases/yourdb.sqlite

Try this app: SQLiteWeb (https://play.google.com/store/apps/details?id=br.com.cm.sqliteweb). It provides remote access to your database without pulling it out.
In paid version, it has root access for private database (/data/data/package-name...) or implement a Content Provider to connect using SQLiteWeb (Instructions inside app)
But if want to stay with the free version, you may create your database in external storage:
database = SQLiteDatabase.openDatabase(Environment.getExternalStorageDirectory()
+ "/" + DATABASE_NAME, null, DATABASE_VERSION);

On OSX,using #Tadas answer with automator and sqllitebrowser(https://github.com/sqlitebrowser/sqlitebrowser):
open Automator and create new workflow.
add "Run Shell Script" action.
Paste this :
source ~/.bash_profile
adb shell 'run-as cat /data/data/your_app_uid/databases/db.name > /tmp/db.name'
adb pull /tmp/db.name ~/
open -a sqlitebrowser ~/db.name
click run to refresh the database on sqlitebrowser.

Open up a terminal
cd <ANDROID_SDK_PATH> (for me on Windows cd C:\Users\Willi\AppData\Local\Android\sdk)
cd platform-tools
adb shell (this works only if only one emulator is running)
cd data/data
su (gain super user privileges)
cd <PACKAGE_NAME>/databases
sqlite3 <DB_NAME>
issue SQL statements (important: terminate them with ;, otherwise the statement is not issued and it breaks to a new line instead.)
Note: Use ls (Linux) or dir (Windows) if you need to list directory contents.

Related

Where does android studio save sqlite db on Linux dev machine?

I'd like to insert data directly into the sqlite database of my app but I cannot find it anywhere on android studio path, even on my root path:
$sudo find / -type f -name 'myapp.db'
I know several similar questions have been asked before but the answers for Windows did not help me on Ubuntu Linux. So appreciate your help.
Android Studio does not store the database locally in your computer. The databases only exist in the devices & every time you deploy to a new device, your database will be created new in that new device. That is why you can't find it in your computer. Here is where the database is located in the device:
/data/data/full_qualified_java_package_name/databases/database_name.db
Now if you would like to insert data directly, you can use the terminal in Android Studio & use ADB to pull the database off the emulator, modify it, and push it back in. Heck I am sure that if you know enough Linux you could probably insert what you need into it without pulling it from the device. Here are some sample commands for the Android Studio terminal for that:
~/Android/Sdk/platform-tools/adb devices
Get the device number, then:
~/Android/Sdk/platform-tools/adb -s emulator-#### pull /data/data/full_qualified_java_package_name/databases/database_name.db <local-filepath>
And to send it back in, it is just:
~/Android/Sdk/platform-tools/adb -s emulator-#### push <local-filepath> /data/data/full_qualified_java_package_name/databases/database_name.db
Example:
~/Android/Sdk/platform-tools/adb -s emulator-5554 pull /data/data/com.danielkaparunakis.stackoverflowquestions/databases/Questiondatabase.db /Users/DanielKaparunakis/Desktop
Additional tip: If you leave the blank when you pull like this:
~/Android/Sdk/platform-tools/adb -s emulator-5554 pull /data/data/com.danielkaparunakis.stackoverflowquestions/databases/Questiondatabase.db
It will automatically pull it to your project's root folder.
It will save it in the internal storage of every device, if you don't have a rooted device it will not allow you to pull it, but, if you are using an emulator you will be able to pull it.
https://developer.android.com/training/basics/data-storage/databases.html
You app's db is only on the device. You can pull it from any connected device – non-rooted physical devices as well. This script pulls it from the first device.
This trick is run-as <package name> which runs a shell the app's directory with full access to the app's data.
Replace $package with your app's package name and replace $db with the name of you app's db.
$ LC_ALL=C adb exec-out run-as $package cat databases/$db >db.sqlite
LC_ALL=C is to avoid some strange locale behavior on some systems.
adb is by default installed by Android Studio to ~/Android/Sdk/platform-tools/adb.
Update
The program 'adb' is currently not installed. To run 'adb' please ask your administrator to install the package 'android-tools-adb'
This is Ubuntu telling you that you can install it from the Ubuntu package manager.
Normally you would already have it as a part of Android Studio.
Update 2
I don't have a script yet for pushing it back since push and run-as don't work together. You would have to do something like this (untested).
$ adb push db.sqlite /sdcard/temp.sqlite
$ cat <<EOF | adb shell
run-as $package
cat /sdcard/temp.sqlite >databases/$db
exit
exit
EOF

displaying SQLite database as application is running in android

i have created a database using SQliteCursor in android. but non of my queries work and it always give me no such table exception.so i want to see the database to check if it is even created?!
so here is my question:how can i see my created database with code as the program is running???
I saw so many answers but they all assume there is a database in DDMS perspective.
is there any tool I can use? what can I do?
besides I am using cursor to enter queries.
thanks.
You can pull the database from the device to your local disk by executing following commands:
First make your database file accessible by running chmod using run-as command of adb
adb shell "run-as package.name chmod 666 /data/data/package.name/databases/file"
Then try to pull that file in your local disk
adb pull /data/data/package.name/databases/file
Just make sure that you have marked the application to debuggable=true in the manifest.
To view this database you can download a mozilla plugin i.e SqliteManager and can view the full schema of DB. I always use this and it is really good.
I made a executable file for this process please add below lines in a file with .exe or sh extension depending on your system OS:
adb shell "run-as yourpackagename chmod 666 databases/yourdbname.db"
adb shell "cp /data/data/yourpackagename/databases/yourdbname.db /sdcard/"
adb shell "run-as yourpackagename chmod 600 databases/yourdbname.db"
adb pull /sdcard/yourdbname.db
Replace yourdbname with your Db name and yourpackagename with the package name of your app.
Please post if you got stuck somewhere in the steps.
Please paste some code for better understanding.
or try this
Go to DDMS => data => data => here you have to find your project like com.example.example. In this you will easily get database file and you can save it or check whether it is created or not.

Can not find sqlite localstorage file on Android device (motorola tc 55)

Lately I am testing a synchronization framework, called sqlite-sync.com.
It runs smoothly, the only question for me so far is that, I can not find where the Android app stores the local sqlite file.
I noticed the android client is using sencha touch framework, the underlying proxy for data storage is called "sqlitestorageproxy".
I checked, my data/data folder is empty.
I am using Motorola Tc55.
Code responsible for opening database is like this:
if (!window.openDatabase) {
alert('Error creating database.');
} else {
this.dbConn = openDatabase(shortName, version, displayName, maxSize);
}
Please help me find the file. THank you.
OK. I found the answer. The device was rooted and I was using "root
browser" app the check the data/data folder, it says it's empty.
However it was misleading, because when I logged in from command
line using adb, it says "permission denied".
Then I realized that I have to do the following to see and copy the content of my data folder:
adb shell "run-as com.sqlitesync.demo ls -l /data/data/com.sqlitesync.demo/app_database"
adb shell "run-as com.sqlitesync.demo chmod 666 /data/data/com.sqlitesync.demo/app_database/Databases.db"
adb pull /data/data/app_database/Databases.db C:\Users\Public
adb shell "run-as com.sqlitesync.demo chmod 600 /data/data/com.sqlitesync.demo/app_database/Databases.db"

Get SQLite database from Android app

I need get SQLite database from Android app from Genesis device where user has populated by hand.
How I can create another app or any other way to get this db and save in place where I can get?
obs.: the device has root
Thanks
Steps from .../platform-tools of Android on cmd:
1) type adb shell
2) run-as com.your.package
3) type ls
cache
databases
lib
You can find Your Database Here...Also You didn't even have to root the Device
Hope this could helpful for you...
Provided you have the device attached to a box with adb on the PATH you can use this command:
adb -d shell 'run-as your.package.name.here cat /data/data/your.package.name.here/databases/your_db_name_here.sqlite > /sdcard/recovered_db.sqlite'
Or you can use Ecliplse DDMS file explorer.
VERY EASY WAY TO DO IT
In the latest releases of Android Studio (I am using AS v3.1.2) the Google team has made it really straight forward. You just have to open the Device File Explorer window which should be at the bottom of the right vertical toolbar, if you cannot find it you can also open it this way:
View -> Tool Windows -> Device File Explorer
Once you have Device File Explorer window open, use your mouse to navigate to the following path:
data -> data -> your.package.name -> databases
Inside the databases folder you should see the database you want to explore, do a right click and Save As... select your desired computer destination folder and voila!!
You can either include the Stetho library on your app,
http://facebook.github.io/stetho/
which will allow you to access your DB using Chrome's Web Debug tools
or use the following shell script:
#!/bin/bash
echo "Requesting data from Android"
adb backup -f data.ab -noapk YOUR.APK.NAME
echo "Decoding...."
dd if=data.ab skip=24 iflag=skip_bytes | python -c "import zlib,sys;sys.stdout.write(zlib.decompress(sys.stdin.read()))" | tar -xvf -
rm data.ab
echo "Done"
```
None of the methods above require your device to be rooted and the latter works even on apps that you did not write yourself, as long as the ApplicationManifest.xml does not contain "backup=false"
After trying dozens of commands that didn't work for me on Marshmallow, I've found this one that works (for debuggable apps at least):
adb shell "run-as your.package.name cp /data/data/your.package.name/databases/you-db-name /sdcard/file_to_write"
Then you simply can view the DB with aSQLiteManager for instance.
You can use this script.
humpty.sh
You should know the application package name and sqlite database name.
You can check the available databases.
$ adb shell
$ run-as <package-name>
$ ls databases/
To dump database or other file.
./humpty.sh -d <package-name> databases/<db-name>

pull a database from genymotion emulator on to local disk

I am using genymotion for my dev and when I create a database I can't see it in DDMS folder of genymotion emulator.
When searched on google I am able to see the database on adb shell but don't know how to pull the database to my local disk to view the data.
Can anyone please let me know the process.
Thanks in advance
Try on Genymotion 2.3:
adb shell su -c cp /data/data/<package.name>/databases/<database.name> /sdcard/
and on other version :
adb shell su 0 cp /data/data/<package.name>/databases/<database.name> /sdcard/
And pull it from the device
adb pull /sdcard/<database.name>
(edited, not the same comportment of su in 2.3 and 4.3)
You can (also) pull the data from your device to your host by copying it to a shared folder:
adb shell su 0 cp /data/data/<package.name>/databases/<database.name> /mnt/shared/
Here is how to setup the shared folder:
Go to your VirtualBox VM setting / Shared folder tab
Add a shared folder with the folder you want to shared, and check the "auto mount" option
Start your VM as usual from the Genymotion software
Your shared folder is available in the /mnt/shared directory (multiple shared folders are supported)
pull database using adb commands
adb pull /data/data/com.android.packagename/databases.datebase.db
the db will be pulled to current location where terminal is pointing to
then open db using sqliteman

Categories

Resources