Débogage de la base de données sqlite sur l'appareil

98

Je travaille actuellement sur une application WiFi pour Android. J'ai du mal à accéder à la base de données sur l'appareil. Le débogage dans l'émulateur ne fonctionne pas pour moi, car il n'y a pas de support WiFi dans l'émulateur. J'ai essayé d'extraire le fichier de base de données de l'appareil en utilisant

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

Mais j'obtiens l'erreur "Autorisation refusée.". Dans cette réponse Android: Où sont stockés les fichiers de base de données? , Commonsware a suggéré d'extraire le fichier de base de données en s'exécutant en mode débogage. Mais ça ne marche pas trop. Toute aide sur la façon de déboguer la base de données sans rooter le périphérique serait très appréciée.

Primal Pappachan
la source

Réponses:

142

Je vais me répéter d' une autre réponse :

À partir du niveau d'API 8 (Android 2.2), si vous créez l'application en tant que déboguable, vous pouvez utiliser la run-ascommande shell pour exécuter une commande ou un exécutable en tant qu'utilisateur / application spécifique ou simplement basculer vers le UIDde votre application afin d'accéder à ses données annuaire.

Donc, si vous souhaitez extraire votre base de données d'application de l'appareil, vous devez exécuter la version de débogage de l'application, connectez-vous adb shellet exécutez la commande suivante:

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

Cela copiera votre db-fileà la racine de votre carte SD / stockage externe. Maintenant, vous pouvez facilement l'obtenir à partir de là en utilisant le gestionnaire de fichiers, adb pullou tout ce que vous voulez. Notez qu'avec cette approche, il n'est PAS nécessaire que votre application ait l' WRITE_EXTERNAL_STORAGEautorisation, car la copie est effectuée par l'utilisateur du shell qui peut toujours écrire sur le stockage externe.

Sur les systèmes Linux / Mac, il est possible de copier une base de données directement sur votre ordinateur avec la commande suivante que l'on peut utiliser sans entrer dans le shell adb:

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

Cependant, cela ne fonctionnera pas correctement sous Windows en raison de la conversion des symboles CR / LF. Utilisez la première méthode là-bas.

Idolon
la source
1
@MikeIsrael Juste au cas où vous n'utilisez pas SQLCipher dans votre application, n'est-ce pas? Sinon, pour vérifier grossièrement si la base de données a été téléchargée correctement, ouvrez le fichier DB dans une visionneuse (de préférence une visionneuse hexadécimale) et vérifiez si elle commence par une SQLite format 3chaîne. Assurez-vous également que vous avez une sqliteversion correcte (c'est-à-dire que vous n'essayez pas d'ouvrir la base de données sqlite3 avec l'exécutable sqlite2). Et vous pouvez également essayer d'autres clients SQLite (par exemple SQLiteStudio ). J'espère que ça aide.
Idolon
1
J'ai des problèmes avec l'unique doublure. Cela fonctionne très bien si j'exécute la commande dans un shell mais si je mets la seule ligne que j'obtiens: Le système ne peut pas trouver le chemin spécifié.
Rev Tyler
2
package <mon package> est inconnu ... tout le monde sait pourquoi. J'ai installé via studio en appuyant sur le bouton de débogage.
Nathan Schwermann
4
Sur Android Lollipop, je reçoispermission denied
Muhammad Babar
1
J'ai extrait une base de données avec deux tables et une douzaine de lignes dans chacune, et j'ai effectué des requêtes de sélection complètes sur chaque table. L'un a bien fonctionné, l'autre a signalé une erreur de données dans le fichier. Ma meilleure estimation pour le moment est une incompatibilité de codage entre le shell Android et local.
Mason
23

J'utilise ce script shell sur mon MAC, qui copie la base de données directement dans mon dossier personnel. Solution simple en un clic, changez simplement le nom du package (com.example.app) et le nom de la base de données (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 qui accepte les arguments [nom_package] [base de données]

#!/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
la source
La première commande créait une copie zéro octet de la base de données, j'ai donc fait quelques ajustements dans votre script: gist.github.com/romulof/6af8a8919660f395f975
romulof
14

La meilleure façon d'afficher et de gérer votre base de données d'applications Android est d'utiliser cette bibliothèque https://github.com/sanathp/DatabaseManager_For_Android

Avec cette bibliothèque, vous pouvez gérer la base de données SQLite de votre application à partir de votre application elle-même. vous pouvez afficher les tables dans la base de données de votre application, mettre à jour, supprimer, insérer des lignes dans vos tables .Tout à partir de votre application.

C'est un seul fichier d'activité java, ajoutez simplement le fichier java à votre dossier source.Lorsque le développement est terminé, supprimez le fichier java de votre dossier src c'est tout.

Cela m'a beaucoup aidé. J'espère que cela vous aidera aussi.

Vous pouvez voir la démo d'une minute ici: http://youtu.be/P5vpaGoBlBY

sanath_p
la source
11

Bien que ce soit une vieille question, je pense qu'elle est toujours d'actualité et mérite une réponse de l'état actuel. Il existe des outils disponibles, qui vous permettent d'inspecter directement les bases de données (sans avoir besoin de les extraire de l'appareil ou de l'émulateur).

L'outil que j'ai découvert le plus récemment (et que je préfère le plus) est la base de données de débogage Android .

Il vous suffit d'ajouter cette dépendance:

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

Aucun autre code n'est requis. Après avoir démarré votre application, ouvrez logcat et filtrez pour "DebugDB" et vous trouverez un message disant

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

Il fonctionne avec tous les navigateurs et vous pouvez inspecter vos tables de base de données et vos préférences partagées.

entrez la description de l'image ici

Il fonctionne également avec les émulateurs par défaut et Genymotion.


L'outil que j'ai utilisé avant est stetho .

Inconvénient: vous devez ajouter un peu de code et vous êtes lié au navigateur Chrome.

Avantage: vous avez également la possibilité d'inspecter le trafic réseau.

Peter F
la source
5

Si vous obtenez

The system cannot find the path specified.

essayer

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

Notez la double citation!

Gerold Meisinger
la source
3

J'ai simplement fait:

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

Ensuite, je peux déboguer une base de données sqlite ou tout ce que je veux faire à partir du shell avec les bonnes autorisations.

smichak
la source
2

Il existe un moyen si un apk est déboguable d'utiliser un programme appelé run-as à partir du shell adb (non root) pour copier le fichier privé d'une application.

Chris Stratton
la source
2

Voici des instructions étape par étape - principalement tirées d'une combinaison des autres réponses. Cela fonctionne avec les appareils qui ne sont pas déverrouillés.

  1. Connectez votre appareil et lancez l'application en mode débogage.

  2. Copiez le fichier de base de données de votre dossier d'application sur votre carte SD: exécutez:

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

  3. Tirez les fichiers de la base de données sur votre machine: exécutez:

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

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

  5. Ouvrez Firefox SQLLite Manager et ouvrez votre fichier de base de données à partir de l'étape 3 ci-dessus.

  6. Prendre plaisir!

Andy Cochrane
la source
2

Android Studio 4.1 Ajout d'une nouvelle fonctionnalité pour afficher / modifier les bases de données Android SQLite.

entrez la description de l'image ici

Comment ouvrir l'inspecteur de base de données

Pour ouvrir l'inspecteur de base de données dans Android Studio, vous devez sélectionner View > Tool Windows > Database Inspectordans la barre de menus.

Vous devez également exécuter l'application sur un appareil exécutant le niveau d'API 26 ou supérieur.

En utilisant cet outil, vous pouvez

  • Interrogez vos bases de données

  • Modifiez et déboguez votre base de données

entrez la description de l'image ici

Darish
la source
2

Dans le nouvel Android Studio 4.1, il y a le nouvel inspecteur de base de données .

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

Vous pouvez sélectionner les options suivantes dans la barre de menus View > Tool Windows > Database Inspectorpour l'ouvrir. Des instructions plus détaillées peuvent être trouvées dans ce blog .

Une autre façon est d'utiliser stetho pour cela. Vous ajoutez la dépendance et pouvez ensuite utiliser Chrome DevTools (chrome: // inspect) pour vérifier la base de données lorsque l'appareil est branché.

jeprubio
la source
1

Vous devez exécuter adb en tant que root ou l'utiliser sur un téléphone rooté.

Pour exécuter adb en tant que root, utilisez adb root

Voir aussi: Pourquoi mon accès au dossier de données est-il refusé lorsque j'utilise adb?

Malfist
la source
J'avais essayé ça. Mais cela me donne "adb ne peut pas fonctionner en tant que root dans les versions de production"
Primal Pappachan
Vous devrez l'exécuter en mode débogage.
Malfist
Voir ceci: mydroidworld.com/forums/android-hacks / ... Si vous l'exécutez sur un téléphone et non sur un émulateur, vous devrez le rooter.
Malfist
J'ai exécuté l'application en mode débogage et j'ai également essayé les étapes ci-dessus. Ça ne marche pas.
Primal Pappachan
Cela ne fonctionne que pour l'émulateur ou un appareil enraciné.
slott
1

Aucune des run-assolutions -et-chat-à-sdcard ne fonctionnait pour moi sur Android 4.4.2. Je ne suis pas sûr, mais je soupçonne que cela peut être dû au fait que l' run-asoutil ne gère pas correctement le nouveau sdcard_ret les sdcard_rwautorisations.

J'ai d'abord dû copier le fichier de base de données /filesdans le stockage interne privé de mon application:

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

Ensuite, j'ai copié /sdcard/Android/data/com.example.myapp/filesdans Javaland (cela nécessite l' WRITE_EXTERNAL_STORAGEautorisation):

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

Enfin, j'ai copié le fichier sur mon ordinateur portable:

$ adb pull /sdcard/Android/data/com.example.myapp/files/mydb
user167019
la source
1
Il existe une solution plus simple. Si vous chmodez 777 votre fichier sqlite, puis quittez run-as, cela vous permettra de le copier dans / sdcard en tant qu'utilisateur normal.
zedix
1

Mon appareil n'avait pas de carte SD

donc la première solution n'a pas fonctionné pour moi.

Si vous rencontrez un problème similaire, essayez comme ceci:

  adb shell "run-as package chmod 777 /data/data/package/databases/yourdb.sqlite";
  adb pull /data/data/package/databases/yourdb.sqlite
dessiné
la source
/sdcardn'est pas nécessairement une carte SD. Sur mon téléphone, il pointe vers le stockage interne lorsqu'aucune carte SD physique n'est présente.
DearVolt
0

Essayez cette application: SQLiteWeb ( https://play.google.com/store/apps/details?id=br.com.cm.sqliteweb ). Il fournit un accès à distance à votre base de données sans la retirer.

En version payante, il dispose d'un accès root pour la base de données privée (/ data / data / package-name ...) ou implémente un fournisseur de contenu pour se connecter à l'aide de SQLiteWeb (Instructions dans l'application)

Mais si vous souhaitez rester avec la version gratuite, vous pouvez créer votre base de données dans un stockage externe:

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

Sous OSX, en utilisant @Tadas answer avec automator et sqllitebrowser ( https://github.com/sqlitebrowser/sqlitebrowser ):

  1. ouvrez Automator et créez un nouveau flux de travail.

  2. ajoutez l'action "Exécuter le script Shell".

  3. Collez ceci:

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

  4. cliquez sur exécuter pour actualiser la base de données sur sqlitebrowser.

Zaster
la source
0
  1. Ouvrir un terminal
  2. cd <ANDROID_SDK_PATH>(pour moi sur Windows cd C:\Users\Willi\AppData\Local\Android\sdk)
  3. cd platform-tools
  4. adb shell (cela ne fonctionne que si un seul émulateur est en cours d'exécution)
  5. cd data/data
  6. su (obtenir les privilèges de super utilisateur)
  7. cd <PACKAGE_NAME>/databases
  8. sqlite3 <DB_NAME>
  9. émettez des instructions SQL ( important: terminez-les par ;, sinon l'instruction n'est pas émise et elle passe à une nouvelle ligne à la place.)

Remarque: utilisez ls(Linux) ou dir(Windows) si vous devez répertorier le contenu du répertoire.

Willi Mentzel
la source