Recupere o banco de dados ou qualquer outro arquivo do armazenamento interno usando run-as

113

Em um dispositivo Android sem acesso root, posso navegar até a pasta de dados que contém o banco de dados usando o run-ascomando com meu nome de pacote. A maioria dos tipos de arquivos fico contente apenas com a visualização, mas com o banco de dados que gostaria de extrair do dispositivo Android.

Existe um comando download copyou movedesta parte do shell adb? Eu gostaria de baixar o arquivo de banco de dados e visualizar seu conteúdo usando um navegador de banco de dados.

Uma resposta aqui envolve transformar o pacote de aplicativo inteiro em um arquivo compactado, mas não há mais nenhuma resposta sobre como extrair esse arquivo uma vez que isso seja feito e movido para a máquina, deixando-me muito desviado quando pode haver uma solução mais direta para começar

CQM
fonte
Experimente adb pull stackoverflow.com/questions/8650407/…
Painless
stackoverflow.com/questions/13006315 Extrair banco de dados sem dispositivo de enraizamento
Naveen Prince P

Respostas:

230

Por design, a userconstrução do Android (isso é o que você tem em seu telefone até desbloquear o bootloader e atualizar o telefone com userdebugou engsoftware) restringe o acesso ao armazenamento interno - cada aplicativo pode acessar apenas seus próprios arquivos. Felizmente para os desenvolvedores de software que não desejam fazer o root em seus telefones, o Google oferece uma maneira de acessar o armazenamento interno de versões depuráveis de seus pacotes usandorun-as comando.

Para fazer o download /data/data/debuggable.app.package.name/databases/filede um dispositivo Android 5.1+, execute o seguinte comando:

adb exec-out run-as debuggable.app.package.name cat databases/file > file

Para baixar vários arquivos em uma pasta /data/data/debuggable.app.package.name/no de uma vez - use tar:

adb exec-out run-as debuggable.app.package.name tar c databases/ > databases.tar
adb exec-out run-as debuggable.app.package.name tar c shared_prefs/ > shared_prefs.tar
Alex P.
fonte
8
Ou apenas use run-aspara copiar o arquivo para um local no armazenamento externo e extrair o arquivo de banco de dados de lá, em vez de mexer nas permissões do arquivo.
CommonsWare
5
O run-as não tem permissão para gravar no sdcard - há algo novo adicionado com a atualização mais recente ... :(
slott
4
Quando executo adb shell "run-as package.name chmod 666 /data/data/package.name/databases/file" adb termina-me o erro -> run-as: exec falhou para chmod666 Erro: Permissão negada. Estou no Nexus 7 sem raiz
Shudy
2
O acesso de gravação ao cartão SD externo não é mais possível com o adb.
Slott
3
Se você descobrir que está recebendo de volta um arquivo em branco ou quase em branco, poderá descobrir que o arquivo é simplesmente um erro do console que foi redirecionado para este arquivo que você criou. Um problema frequente aqui é que você está tentando copiar um banco de dados da variante Release do seu aplicativo. Você só pode copiar bancos de dados da variante de depuração do seu aplicativo . Se isso acontecer, basta instalar a variante de depuração e tentar o comando novamente. Espero que isso ajude alguém.
Aonghus Shortt de
72

A resposta aceita não funciona mais para mim (bloqueado pelo Android?)

Então, em vez disso, fiz isso:

> adb shell
shell $ run-as com.example.package
shell $ chmod 666 databases/file
shell $ exit                                               ## exit out of 'run-as'
shell $ cp /data/data/package.name/databases/file /sdcard/
shell $ run-as com.example.package
shell $ chmod 600 databases/file
> adb pull /sdcard/file .
marmor
fonte
3
Esta deve ser a nova resposta correta OU @Alex P. você deve adicionar esta resposta para versões mais recentes do Android. Também no meu caso eu tive que usar 777 e aplicá-lo ao diretório do banco de dados primeiro / as-well antes de poder acessar o arquivo db.
muetzenflo
1
Meu dispositivo está enraizado, mas descobri que ainda preciso executar supara fazer o run-ascomando funcionar.
ThomasW
E se você não tiver um cartão SD?
Gyum Fox
1
se você não tiver um cartão SD, ainda há um diretório "sdcard" de qualquer maneira.
treesAreEverywhere
1
Ótimo!. funcionou para mim também. Podemos fazer um arquivo batch / shell? apenas passando o nome do arquivo db como param e temos o arquivo db.
Qadir Hussain
22

Se alguém estiver procurando puxar banco de dados do aplicativo de depuração, pode usar o procedimento abaixo:

  1. pesquisar e abrir o explorador de arquivos do dispositivo

pesquisar e abrir o explorador de arquivos do dispositivo

  1. Selecione seu aparelho e navegue até o data/datadiretório

vá para o diretório de dados / dados

  1. Agora encontre seu pacote de aplicativo e vá para a pasta de bancos de dados. Você pode ver os bancos de dados lá e ao clicar com o botão direito, você terá a opção de salvar em sua unidade.

insira a descrição da imagem aqui

Ifta
fonte
1
Uau, muito mais fácil e seguro em comparação com o uso do adb-shell
user1708860
9

Publiquei um script de shell simples para despejar bancos de dados:

https://github.com/Pixplicity/humpty-dumpty-android

Ele executa dois métodos distintos descritos aqui:

  1. Primeiro, ele tenta tornar o arquivo acessível para outros usuários e tenta retirá-lo do dispositivo.
  2. Se isso falhar, ele envia o conteúdo do arquivo pelo terminal para a máquina local. Ele executa um truque adicional para remover \rcaracteres que alguns dispositivos geram no shell.

A partir daqui, você pode usar uma variedade de aplicativos CLI ou GUI SQLite, como sqlite3ou sqlitebrowser, para navegar pelo conteúdo do banco de dados.

Paul Lammertsma
fonte
Este script é para aplicativos depuráveis, e se o aplicativo não for depurável?
blueware de
É provável que suas únicas opções usem ferramentas de backup, se o aplicativo em questão expor esses dados como parte de um backup. Além disso, temo que exigiria permissões elevadas.
Paul Lammertsma
7

Não consegui que mais nada funcionasse para mim, exceto isso:

adb shell
run-as package.name
cat /databases/databaseFileName.db > /sdcard/copiedDatabaseFileName.db
exit
exit
adb pull /sdcard/copiedDatabaseFileName.db /file/location/on/computer/

A primeira saída é sair do run-as, a segunda saída é sair do shell adb para fazer o pull.

Triplee121
fonte
3

Para a versão de depuração do aplicativo, é muito conveniente usar o comando adb exec-out run-as xxx.yyy.zzz cat somefile > somefilepara extrair um único arquivo. Mas você tem que fazer várias vezes para vários arquivos. Aqui está um script simples que uso para extrair o diretório.

#!/bin/bash
P=
F=
D=

function usage()
{
    echo "$(basename $0) [-f file] [-d directory] -p package"
    exit 1
}

while getopts ":p:f:d:" opt
do
    case $opt in
        p)
            P=$OPTARG
            echo package is $OPTARG
            ;;
        f)
            F=$OPTARG
            echo file is $OPTARG
            ;;
        d)
            D=$OPTARG
            echo directory is $OPTARG
            ;;
        \?)
            echo Unknown option -$OPTARG
            usage
            ;;
        \:)
            echo Required argument not found -$OPTARG
            usage
            ;;
    esac
done

[ x$P == x ] && {
    echo "package can not be empty"
    usage
    exit 1
}

[[ x$F == x  &&  x$D == x ]] && {
    echo "file or directory can not be empty"
    usage
    exit 1
}

function file_type()
{
    # use printf to avoid carriage return
    __t=$(adb shell run-as $P "sh -c \"[ -f $1 ] && printf f || printf d\"")
    echo $__t
}

function list_and_pull()
{
    t=$(file_type $1)
    if [ $t == d ]; then
        for f in $(adb shell run-as $P ls $1)
        do
            # the carriage return output from adb shell should
            # be removed
            mkdir -p $(echo -e $1 |sed $'s/\r//')
            list_and_pull $(echo -e $1/$f |sed $'s/\r//')
        done
    else
        echo pull file $1
        [ ! -e $(dirname $1) ] && mkdir -p $(dirname $1)
        $(adb exec-out run-as $P cat $1 > $1)
    fi
}

[ ! -z $D ] && list_and_pull $D
[ ! -z $F ] && list_and_pull $F

Espero que seja útil. Este script também está disponível em gist .

O uso típico é

$ ./exec_out.sh -p com.example.myapplication -d databases

em seguida, ele extrairá todos os arquivos do diretório de bancos de dados do seu aplicativo, ou seja /data/data/com.example.myapplication/databases, para o diretório atual.

Alijandro
fonte
1
mesmo para vários arquivos, ainda é apenas um único comando. verifique a atualização stackoverflow.com/a/18472135/1778421 se preferir, você também pode adicionar outro canal no lado do host para descompactar os arquivos
Alex P.
2

Abordagem muito mais simples para baixar o arquivo em seu computador local:

No shell do seu PC, execute:

adb -d shell 'run-as <package_name> cat /data/data/<package_name>/databases/<db_name>' > <local_file_name>
Emre
fonte
Muito perto, mas isso puxa um banco de dados malformado para mim.
Nae
1
#!/bin/bash
#export for adb
export PATH=$PATH:/Users/userMe/Library/Android/sdk/platform-tools
export PATH=$PATH:/Users/userMe/Library/Android/sdk/tools

adb -d shell 'run-as com.android.app  cp /data/data/com.android.app/files/db.realm /sdcard'
adb pull sdcard/db.realm /Users/userMe/Desktop/db

Você pode usar este script para obter o banco de dados Realm.

dralexnumber
fonte
0

Se alguém está procurando uma outra resposta que pode ser usado para recuperar Database, bem como Shared Preferences, em seguida, siga esta etapa:

No build.gradlearquivo do seu aplicativo adicione a linha

debugCompile 'com.amitshekhar.android:debug-db:1.0.0'

agora, quando você executar seu aplicativo no non-releasemodo, então seu aplicativo abrirá automaticamente a porta 8080 do seu dispositivo, IP addresscertifique-se de que seu dispositivo está conectado via wifie laptopestá compartilhando a mesma rede. Agora basta visitar o url

http: // your_mobile_device_ip: 8080 /

para ver todos os dados do banco de dados junto com as preferências compartilhadas.

Pradeep Kumar Kushwaha
fonte
0

Esta é uma solução que funciona em um dispositivo com Android 5.1. O exemplo a seguir é para Windows.

Voce precisa sed (ou sed.exe no Windows, por exemplo, do cygwin.) (No Unix, ele estará lá;)). Para remover caracteres '\ r' ruins, pelo menos no Windows.

Agora basta executar o seguinte comando:

adb exec-out "run-as com.yourcompany.yourapp /data/data/com.yourcompany.yourapp/databases/YourDatabaseName" | c:\cygwin\bin\sed.exe 's/\x0D\x0A/\x0A/'>YourDatabaseName.db

O comando sed remove os caracteres / r finais.

Obviamente, você deve substituir "com.yourcompany.yourapp" pelo nome do pacote do aplicativo e "YourDatabaseName" pelo nome do banco de dados no aplicativo.

treesAreEverywhere
fonte
0

O arquivo de banco de dados fica vazio ao usaradb run-as . Isso pode ser resolvido chamando close () na instância RoomDatabase. Chame close () para permitir que o SQLite grave seu diário no disco. Criei este botão que fecha a conexão do banco de dados a pedido:

via GIPHY

Aqui está como chamar close na instância RoomDatabase.

Eimert
fonte