Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Debugging sqlite database on the device

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.

like image 702
Primal Pappachan Avatar asked Aug 03 '11 15:08

Primal Pappachan


People also ask

How do I debug SQLite?

To find this easily, run the script in a debugger. Set a breakpoint on the "test_addoptrace" routine. Then run the "PRAGMA vdbe_addoptrace=ON;" followed by the SQL statement in question. Each opcode will be displayed as it is appended to the VDBE program, and the breakpoint will fire immediately thereafter.

Can you access your database of SQLite database for debugging?

In Android Studio 4.1 and higher, the Database Inspector allows you to inspect, query, and modify your app's databases while your app is running. This is especially useful for database debugging. The Database Inspector works with plain SQLite and with libraries built on top of SQLite, such as Room.


2 Answers

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.

like image 84
Idolon Avatar answered Oct 10 '22 14:10

Idolon


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
like image 23
Tadas Valaitis Avatar answered Oct 10 '22 14:10

Tadas Valaitis