Depurando la base de datos sqlite en el dispositivo

98

Actualmente estoy trabajando en una aplicación WiFi para Android. Tengo problemas al intentar acceder a la base de datos en el dispositivo. La depuración en el emulador no me funciona, porque no hay soporte WiFi en el emulador. Intenté sacar el archivo de la base de datos del dispositivo usando

adb pull data/data/package-name/databases/database-name

Pero aparece el error "Permiso denegado". En esta respuesta Android: ¿Dónde se almacenan los archivos de la base de datos? , Commonsware ha sugerido extraer el archivo de la base de datos ejecutándolo en modo de depuración. Pero tampoco funciona. Cualquier ayuda sobre cómo depurar la base de datos sin rootear el dispositivo será muy apreciada.

Pappachan primigenio
fuente

Respuestas:

142

Me repetiré de otra respuesta :

A partir del nivel de API 8 (Android 2.2), si crea la aplicación como depurable, puede usar el run-ascomando de shell para ejecutar un comando o un ejecutable como un usuario / aplicación específico o simplemente cambiar al UIDde su aplicación para poder acceder a sus datos directorio.

Entonces, si desea extraer la base de datos de su aplicación del dispositivo, debe ejecutar la compilación de depuración de la aplicación, conectarse adb shelly ejecutar el siguiente comando:

run-as com.yourpackage sh -c "cat ~/databases/db-file" > /sdcard/db-file.sqlite

Esto lo copiará db-filea la raíz de su tarjeta SD / almacenamiento externo. Ahora puede obtenerlo fácilmente desde allí utilizando el administrador de archivos adb pullo cualquier otra cosa que desee. Tenga en cuenta que con este enfoque, NO es necesario que su aplicación tenga WRITE_EXTERNAL_STORAGEpermiso, ya que la copia la realiza el usuario de shell, que siempre puede escribir en el almacenamiento externo.

En los sistemas Linux / Mac, existe la posibilidad de copiar una base de datos directamente a su computadora con el siguiente comando que se puede usar sin ingresar al shell adb:

adb shell 'run-as com.yourpackage sh -c "cat ~/databases/db-file"' > db-file.sqlite

Sin embargo, esto no funcionará correctamente en Windows debido a la conversión de símbolos CR / LF. Use el método anterior allí.

Ídolo
fuente
1
@MikeIsrael Por si acaso, no usas SQLCipher en tu aplicación, ¿verdad? De lo contrario, para verificar aproximadamente si la base de datos se descargó correctamente, abra el archivo DB en un visor (preferiblemente un visor hexadecimal) y verifique si comienza con una SQLite format 3cadena. También asegúrese de tener una sqliteversión correcta (es decir, no está intentando abrir la base de datos sqlite3 con el ejecutable sqlite2). Y también puede probar otros clientes de SQLite (por ejemplo, SQLiteStudio ). Espero eso ayude.
Idolon
1
Tengo problemas con la única línea. Funciona bien si ejecuto el comando en un shell, pero si coloco el único revestimiento que obtengo: el sistema no puede encontrar la ruta especificada.
Rev Tyler
2
el paquete <mi paquete> es desconocido ... alguien sabe por qué. Lo instalé a través de Studio presionando el botón de depuración.
Nathan Schwermann
4
En Android Lollipop estoy recibiendopermission denied
Muhammad Babar
1
Saqué una base de datos con dos tablas y una docena de filas en cada una, e hice consultas de selección completa en cada tabla. Uno funcionó bien, el otro informó un error de datos en el archivo. Mi mejor suposición en este momento es una falta de coincidencia de codificación entre Android y el shell local.
Mason
23

Utilizo este script de shell en mi MAC, que copia la base de datos directamente en mi carpeta de inicio. Solución fácil de un clic, simplemente cambie el nombre del paquete (com.example.app) y el nombre de la base de datos (database.sqlite)

Script simple

#!/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 que acepta argumentos [nombre_paquete] [base de datos]

#!/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
Tadas Valaitis
fuente
El primer comando fue crear una copia de cero bytes de la base de datos, así que hice algunos ajustes en su script: gist.github.com/romulof/6af8a8919660f395f975
romulof
14

La mejor manera de ver y administrar la base de datos de su aplicación de Android es usar esta biblioteca https://github.com/sanathp/DatabaseManager_For_Android

Con esta biblioteca puede administrar la base de datos SQLite de su aplicación desde su propia aplicación. puede ver las tablas en la base de datos de su aplicación, actualizar, eliminar, insertar filas en sus tablas. Todo desde su aplicación.

Es un solo archivo de actividad java, simplemente agregue el archivo java a su carpeta de origen. Cuando el desarrollo haya terminado, elimine el archivo java de su carpeta src, eso es todo.

Me ayudó mucho. Espero que te ayude a ti también.

Puede ver la demostración de 1 minuto aquí: http://youtu.be/P5vpaGoBlBY

sanath_p
fuente
11

Aunque es una pregunta antigua, creo que sigue siendo relevante y merece una respuesta de estado actual. Hay herramientas disponibles que le permiten inspeccionar bases de datos directamente (sin la necesidad de extraerlas del dispositivo o emulador).

La herramienta que descubrí más recientemente (y la que más me gusta ) es la base de datos de depuración de Android .

Solo necesita agregar esta dependencia:

debugImplementation 'com.amitshekhar.android:debug-db:1.0.3'

No se requiere más código. Después de iniciar su aplicación, abra logcat y filtre por "DebugDB" y encontrará un mensaje que dice

D/DebugDB: Open http://192.168.178.XXX:8080 in your browser

Funciona con todos los navegadores y puede inspeccionar las tablas de su base de datos y las preferencias compartidas.

ingrese la descripción de la imagen aquí

También funciona con los emuladores predeterminados y Genymotion.


La herramienta que usé antes es stetho .

Desventaja: debe agregar un poco de código y está vinculado al navegador Chrome.

Ventaja: tiene la opción de inspeccionar también el tráfico de la red.

Peter F
fuente
5

Si lo consigues

The system cannot find the path specified.

tratar

adb -d shell "run-as com.yourpackage cat /data/data/com.yourpackage/databases/dbname.sqlite > /sdcard/dbname.sqlite"

¡Tenga en cuenta las comillas dobles!

Gerold Meisinger
fuente
3

Simplemente hice:

$ adb shell
shell@android:/ $ run-as myapp.package.name sh
shell@android:/data/data/myapp.package.name $

Entonces puedo depurar una base de datos sqlite o lo que quiera hacer desde el shell con los permisos adecuados.

smichak
fuente
2

Hay una manera si un apk se puede depurar para usar un programa llamado run-as desde el shell adb (no root) para copiar el archivo privado de una aplicación.

Chris Stratton
fuente
2

Aquí hay instrucciones paso a paso, en su mayoría tomadas de una combinación de las otras respuestas. Esto funciona con dispositivos que no están desbloqueados.

  1. Conecte su dispositivo e inicie la aplicación en modo de depuración.

  2. Copie el archivo de la base de datos de la carpeta de su aplicación a su tarjeta sd: ejecute:

    ./adb -d shell 'ejecutar-como com.yourpackge.name cat /data/data/com.yourpackge.name/databases/filename.sqlite> /sdcard/filename.sqlite'

  3. Extraiga los archivos de la base de datos a su máquina: ejecute:

    ./adb pull / sdcard / execute: ./adb

  4. Instale Firefox SQLLite Manager: https://addons.mozilla.org/en-US/firefox/addon/sqlite-manager/

  5. Abra Firefox SQLLite Manager y abra su archivo de base de datos desde el paso 3 anterior.

  6. ¡Disfrutar!

Andy Cochrane
fuente
2

Android Studio 4.1 Se agregó una nueva función para ver / editar bases de datos SQLite de Android.

ingrese la descripción de la imagen aquí

Cómo abrir el Inspector de base de datos

Para abrir el Inspector de base de datos en Android Studio, debe seleccionar View > Tool Windows > Database Inspectoren la barra de menú.

Además, debe ejecutar la aplicación en un dispositivo que ejecute API nivel 26 o superior.

Con esta herramienta puede

  • Consulta tus bases de datos

  • Modifica y depura tu base de datos

ingrese la descripción de la imagen aquí

Darish
fuente
2

En el nuevo Android Studio 4.1 existe el nuevo Inspector de base de datos .

https://developer.android.com/studio/preview/features/images/database-inspector.gif

Puede seleccionar las siguientes opciones de la barra de menú View > Tool Windows > Database Inspectorpara abrirlo. En este blog se pueden encontrar instrucciones más detalladas .

Otra forma es usar stetho para esto. Agrega la dependencia y luego puede usar Chrome DevTools (chrome: // inspeccionar) para verificar la base de datos cuando el dispositivo está conectado.

jeprubio
fuente
1

Debe ejecutar adb como root o usarlo en un teléfono rooteado.

Para ejecutar adb como root, use adb root

Consulte también: ¿Por qué se me niega el acceso a la carpeta de datos cuando uso adb?

Malfist
fuente
Yo había probado esto. Pero me da "adb no se puede ejecutar como root en las compilaciones de producción"
Primal Pappachan
Deberá ejecutarlo en modo de depuración.
Malfist
Vea esto: mydroidworld.com/forums/android-hacks/… Si lo está ejecutando en un teléfono y no en un emulador, tendrá que rootearlo .
Malfist
Ejecuté la aplicación en modo de depuración y también probé los pasos anteriores. No funciona.
Primal Pappachan
Esto solo funciona para el emulador o un dispositivo rooteado.
slott
1

Ninguna de las run-assoluciones -and-cat-to-sdcard funcionó para mí en Android 4.4.2. No estoy seguro, pero sospecho que puede ser debido a la run-asherramienta no manejar correctamente el nuevo sdcard_ry sdcard_rwpermisos.

Primero tuve que copiar el archivo de la base de datos /filesen el almacenamiento interno privado de mi aplicación:

shell@hammerhead:/ $ run-as com.example.myapp   
shell@hammerhead:/data/data/com.example.myapp $ cp databases/mydb files/mydb

Luego copié /sdcard/Android/data/com.example.myapp/filesen Javaland (esto requiere el WRITE_EXTERNAL_STORAGEpermiso):

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

Finalmente, copié el archivo a mi computadora portátil:

$ adb pull /sdcard/Android/data/com.example.myapp/files/mydb
user167019
fuente
1
Hay una solución más sencilla. Si modifica 777 su archivo sqlite, luego sale de ejecutar como, le permitirá copiarlo en / sdcard como el usuario habitual.
zedix
1

Mi dispositivo no tenía sdcard

así que la primera solución no funcionó para mí.

Si tiene un problema similar, intente así:

  adb shell "run-as package chmod 777 /data/data/package/databases/yourdb.sqlite";
  adb pull /data/data/package/databases/yourdb.sqlite
dsharew
fuente
/sdcardno es necesariamente una tarjeta SD. En mi teléfono, apunta al almacenamiento interno cuando no hay una tarjeta SD física.
DearVolt
0

Pruebe esta aplicación: SQLiteWeb ( https://play.google.com/store/apps/details?id=br.com.cm.sqliteweb ). Proporciona acceso remoto a su base de datos sin tener que extraerla.

En la versión paga, tiene acceso de root para la base de datos privada (/ data / data / package-name ...) o implementa un proveedor de contenido para conectarse usando SQLiteWeb (instrucciones dentro de la aplicación)

Pero si desea quedarse con la versión gratuita, puede crear su base de datos en un almacenamiento externo:

database = SQLiteDatabase.openDatabase(Environment.getExternalStorageDirectory()
        + "/" + DATABASE_NAME, null, DATABASE_VERSION);
Cesar Morigaki
fuente
0

En OSX, usando @Tadas responde con automator y sqllitebrowser ( https://github.com/sqlitebrowser/sqlitebrowser ):

  1. abra Automator y cree un nuevo flujo de trabajo.

  2. agregue la acción "Ejecutar Shell Script".

  3. Pega esto:

    source ~ / .bash_profile adb shell 'ejecutar-as cat /data/data/your_app_uid/databases/db.name> /tmp/db.name' adb pull /tmp/db.name ~ / open -a sqlitebrowser ~ / db. nombre

  4. haga clic en ejecutar para actualizar la base de datos en sqlitebrowser.

Zaster
fuente
0
  1. Abre una terminal
  2. cd <ANDROID_SDK_PATH>(para mí en Windows cd C:\Users\Willi\AppData\Local\Android\sdk)
  3. cd platform-tools
  4. adb shell (esto solo funciona si solo se está ejecutando un emulador)
  5. cd data/data
  6. su (obtenga privilegios de superusuario)
  7. cd <PACKAGE_NAME>/databases
  8. sqlite3 <DB_NAME>
  9. emita sentencias SQL ( importante: ciérrelas con ;, de lo contrario, la sentencia no se emite y se rompe a una nueva línea).

Nota: Utilice ls(Linux) o dir(Windows) si necesita enumerar el contenido del directorio.

Willi Mentzel
fuente