Depurando banco de dados sqlite no dispositivo

98

Atualmente estou trabalhando em um aplicativo WiFi para Android. Estou tendo problemas ao tentar acessar o banco de dados no dispositivo. Depurar no emulador não funciona para mim, porque não há suporte para WiFi no emulador. Tentei puxar o arquivo de banco de dados do dispositivo usando

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

Mas recebo o erro "Permissão negada". Nesta resposta Android: onde os arquivos de banco de dados são armazenados? , Commonsware sugeriu puxar o arquivo de banco de dados executando no modo de depuração. Mas também não funciona. Qualquer ajuda sobre como depurar o banco de dados sem fazer o root do dispositivo seria muito apreciada.

Pappachan Primal
fonte

Respostas:

142

Vou me repetir com outra resposta :

A partir da API de nível 8 (Android 2.2), se você construir o aplicativo como depurável, você pode usar o run-ascomando shell para executar um comando ou executável como um usuário / aplicativo específico ou apenas alternar para o UIDdo seu aplicativo para acessar seus dados diretório.

Portanto, se você deseja extrair o banco de dados do aplicativo do dispositivo, execute a compilação de depuração do aplicativo, conecte-se adb shelle execute o seguinte comando:

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

Isso irá copiá-lo db-filepara a raiz do seu cartão SD / armazenamento externo. Agora você pode obtê-lo facilmente usando o gerenciador de arquivos adb pullou qualquer outra coisa que desejar. Observe que, com essa abordagem, NÃO há necessidade de seu aplicativo ter WRITE_EXTERNAL_STORAGEpermissão, já que a cópia é feita pelo usuário do shell que sempre pode gravar no armazenamento externo.

Em sistemas Linux / Mac, existe a possibilidade de copiar um banco de dados diretamente para o seu computador com o seguinte comando que pode ser usado sem inserir o shell adb:

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

No entanto, isso não funcionará corretamente no Windows devido à conversão dos símbolos CR / LF. Use o método anterior aqui.

Idolon
fonte
1
@MikeIsrael Apenas no caso, você não usa SQLCipher em seu aplicativo, usa? Se não, para verificar se o banco de dados foi baixado corretamente, abra o arquivo DB em um visualizador (de preferência um visualizador hexadecimal) e verifique se ele começa com SQLite format 3string. Verifique também se você tem uma sqliteversão correta (ou seja, você não está tentando abrir o banco de dados sqlite3 com o executável sqlite2). E você também pode tentar outros clientes SQLite (por exemplo SQLiteStudio ). Espero que ajude.
Idolon
1
Estou tendo problemas com o único revestimento. Funciona bem se eu executar o comando em um shell, mas se eu colocar em um liner, obtenho: O sistema não pode encontrar o caminho especificado.
Rev Tyler,
2
pacote <meu pacote> é desconhecido ... alguém sabe por quê. Eu instalei via studio pressionando o botão de depuração.
Nathan Schwermann,
4
Estou recebendo no Android Lollipoppermission denied
Muhammad Babar
1
Puxei um banco de dados com duas tabelas e uma dúzia ou mais de linhas em cada uma, e fiz consultas de seleção completas em cada tabela. Um funcionou bem, o outro relatou um erro de dados no arquivo. Meu melhor palpite agora é uma incompatibilidade de codificação entre o Android e o shell local.
Mason
23

Eu uso este script de shell no meu MAC, que copia o banco de dados diretamente para minha pasta de início. Solução fácil com um clique, basta alterar o nome do pacote (com.example.app) e o nome do banco de dados (database.sqlite)

Script Simples

#!/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 aceita argumentos [nome_do_pacote] [banco de dados]

#!/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
fonte
O primeiro comando estava criando uma cópia de zero bytes do banco de dados, então fiz alguns ajustes em seu script: gist.github.com/romulof/6af8a8919660f395f975
romulof
14

A melhor maneira de visualizar e gerenciar o banco de dados do aplicativo Android é usar esta biblioteca https://github.com/sanathp/DatabaseManager_For_Android

Com esta biblioteca, você pode gerenciar o banco de dados SQLite do seu aplicativo a partir do próprio aplicativo. você pode ver as tabelas em seu banco de dados de aplicativo, atualizar, excluir, inserir linhas em suas tabelas. Tudo de seu aplicativo.

É um único arquivo de atividade java, basta adicionar o arquivo java à sua pasta de origem. Quando o desenvolvimento estiver concluído, remova o arquivo java da sua pasta src é isso.

Me ajudou muito. Espero que ajude você também.

Você pode ver a demonstração de 1 minuto aqui: http://youtu.be/P5vpaGoBlBY

sanath_p
fonte
11

Embora seja uma questão antiga, acho que ainda é relevante e merece uma resposta do estado atual. Existem ferramentas disponíveis que permitem inspecionar bancos de dados diretamente (sem a necessidade de extraí-los do dispositivo ou emulador).

A ferramenta que descobri mais recentemente (e prefiro a maioria) é o Android Debug Database .

Você só precisa adicionar esta dependência:

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

Nenhum código adicional é necessário. Depois de iniciar seu aplicativo, abra o logcat e filtre por "DebugDB" e você encontrará uma mensagem dizendo

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

Funciona com todos os navegadores e você pode inspecionar as tabelas do banco de dados e preferências compartilhadas.

insira a descrição da imagem aqui

Também funciona com o padrão e os emuladores Genymotion.


A ferramenta que usei antes é stetho .

Desvantagem: você precisa adicionar um pouco de código e está vinculado ao navegador Chrome.

Vantagem: você também tem a opção de inspecionar o tráfego de rede.

Peter F
fonte
5

Se você pegar

The system cannot find the path specified.

experimentar

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

Observe a aspa dupla!

Gerold Meisinger
fonte
3

Eu simplesmente fiz:

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

Então posso depurar um banco de dados sqlite ou o que quer que eu queira fazer do shell com as permissões corretas.

smichak
fonte
2

Se um apk puder ser depurado, existe uma maneira de usar um programa denominado run-as do shell adb (não root) para copiar o arquivo privado de um aplicativo.

Chris Stratton
fonte
2

Aqui estão as instruções passo a passo - principalmente tiradas de uma combinação de outras respostas. Isso funciona com dispositivos que não estão desbloqueados.

  1. Conecte seu dispositivo e inicie o aplicativo no modo de depuração.

  2. Copie o arquivo de banco de dados da pasta do aplicativo para o cartão SD: execute:

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

  3. Puxe os arquivos de banco de dados para sua máquina: execute:

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

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

  5. Abra o Firefox SQLLite Manager e abra o arquivo de banco de dados da etapa 3 acima.

  6. Aproveitar!

Andy Cochrane
fonte
2

Android Studio 4.1 Adicionado um novo recurso para visualizar / editar bancos de dados Android SQLite.

insira a descrição da imagem aqui

Como abrir o Database Inspector

Para abrir o Database Inspector no Android Studio, você precisa selecionar View > Tool Windows > Database Inspectorna barra de menu.

Além disso, você precisa executar o aplicativo em um dispositivo com API de nível 26 ou superior.

Usando esta ferramenta você pode

  • Consultar seus bancos de dados

  • Modifique e depure seu banco de dados

insira a descrição da imagem aqui

Darish
fonte
2

No novo Android Studio 4.1, há o novo Database Inspector .

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

Você pode selecionar as seguintes opções na barra de menu View > Tool Windows > Database Inspectorpara abri-lo. Instruções mais detalhadas podem ser encontradas neste blog .

Outra maneira é usar stetho para isso. Você adiciona a dependência e pode usar o Chrome DevTools (chrome: // inspect) para verificar o banco de dados quando o dispositivo é conectado.

jeprubio
fonte
1

Você precisa executar o adb como root ou usá-lo em um telefone com root.

Para executar o adb como root, use adb root

Consulte também: Por que obtenho acesso negado à pasta de dados ao usar o adb?

Malfist
fonte
Eu tentei isso. Mas me dá "adb não pode ser executado como root em compilações de produção"
Primal Pappachan
Você precisará executá-lo no modo de depuração.
Malfist
Veja isto: mydroidworld.com/forums/android-hacks/… Se você estiver executando em um telefone e não em um emulador, você terá que fazer o root.
Malfist
Eu executei o aplicativo no modo de depuração e tentei as etapas acima também. Não funciona.
Primal Pappachan
Isso só funciona para o emulador ou um dispositivo com acesso root.
Slott
1

Nenhuma das run-assoluções -and-cat-to-sdcard funcionou para mim no Android 4.4.2. Eu não tenho certeza, mas eu suspeito que pode ser devido à run-asferramenta não lidar corretamente o novo sdcard_re sdcard_rwpermissões.

Primeiro, tive que copiar o arquivo de banco de dados para /fileso armazenamento interno privado do meu aplicativo:

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

Em seguida, copiei /sdcard/Android/data/com.example.myapp/filesem Javaland (isso requer a WRITE_EXTERNAL_STORAGEpermissão):

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, copiei o arquivo para meu laptop:

$ adb pull /sdcard/Android/data/com.example.myapp/files/mydb
user167019
fonte
1
Existe uma solução mais simples. Se você fizer um chmod 777 em seu arquivo sqlite e sair do run-as, ele permitirá que você copie-o para / sdcard como o usuário normal.
zedix
1

Meu dispositivo não tinha sdcard

então a primeira solução não funcionou para mim.

Se você estiver tendo um problema semelhante, tente assim:

  adb shell "run-as package chmod 777 /data/data/package/databases/yourdb.sqlite";
  adb pull /data/data/package/databases/yourdb.sqlite
dsharew
fonte
/sdcardnão é necessariamente um cartão SD. No meu telefone, ele aponta para o armazenamento interno quando nenhum cartão SD físico está presente.
DearVolt
0

Experimente este aplicativo: SQLiteWeb ( https://play.google.com/store/apps/details?id=br.com.cm.sqliteweb ). Ele fornece acesso remoto ao seu banco de dados sem retirá-lo.

Na versão paga, ele tem acesso root para banco de dados privado (/ data / data / package-name ...) ou implementar um Provedor de Conteúdo para conectar usando SQLiteWeb (Instruções dentro do aplicativo)

Mas se quiser ficar com a versão gratuita, você pode criar seu banco de dados em um armazenamento externo:

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

No OSX, usando @Tadas responda com automator e sqllitebrowser ( https://github.com/sqlitebrowser/sqlitebrowser ):

  1. abra o Automator e crie um novo fluxo de trabalho.

  2. adicione a ação "Executar Shell Script".

  3. Cole isto:

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

  4. clique em executar para atualizar o banco de dados em sqlitebrowser.

Zaster
fonte
0
  1. Abra um terminal
  2. cd <ANDROID_SDK_PATH>(para mim no Windows cd C:\Users\Willi\AppData\Local\Android\sdk)
  3. cd platform-tools
  4. adb shell (isso funciona apenas se apenas um emulador estiver em execução)
  5. cd data/data
  6. su (ganhe privilégios de superusuário)
  7. cd <PACKAGE_NAME>/databases
  8. sqlite3 <DB_NAME>
  9. emitir instruções SQL ( importante: termine-as com ;, caso contrário, a instrução não será emitida e será interrompida para uma nova linha).

Nota: Use ls(Linux) ou dir(Windows) se precisar listar o conteúdo do diretório.

Willi Mentzel
fonte