web-dev-qa-db-fra.com

Android - Extraction de la base de données SQlite Appareil Android

J'ai regardé partout et je ne trouve pas de réponse précise ni de tutoriel sur la manière de procéder si possible.

est-il possible d'extraire de quelque manière que ce soit la base de données d'un appareil Android sans avoir à la rooter? J'ai juste besoin d'extraire ces données de quelque manière que ce soit afin de les rassembler sur mon pc, alors comment puis-je effectuer cela? Dois-je reprogrammer l'application ou la méthode que vous connaissez, mais souvenez-vous sans enraciner l'appareil. Merci

89
DeX03

Une méthode courante pour atteindre vos objectifs consiste à utiliser la commande d'extraction ADB.

Une autre façon que je préfère dans la plupart des cas consiste à copier la base de données par code sur la carte SD:

try {
    File sd = Environment.getExternalStorageDirectory();

    if (sd.canWrite()) {
        String currentDBPath = "/data/data/" + getPackageName() + "/databases/yourdatabasename";
        String backupDBPath = "backupname.db";
        File currentDB = new File(currentDBPath);
        File backupDB = new File(sd, backupDBPath);

        if (currentDB.exists()) {
            FileChannel src = new FileInputStream(currentDB).getChannel();
            FileChannel dst = new FileOutputStream(backupDB).getChannel();
            dst.transferFrom(src, 0, src.size());
            src.close();
            dst.close();
        }
    }
} catch (Exception e) {

}

N'oubliez pas de définir la permission d'écrire en SD dans votre manifeste, comme ci-dessous.

<uses-permission Android:name="Android.permission.WRITE_EXTERNAL_STORAGE" />
76
KarlKarlsom

Si votre appareil exécute Android v4 ou une version ultérieure, vous pouvez extraire les données d'applications, y compris sa base de données, sans root à l'aide de la commande adb backup, puis extraire le fichier de sauvegarde et accéder à la base de données SQLite.

Commencez par sauvegarder les données d'application sur votre PC via un câble USB à l'aide de la commande suivante: remplacez app.package.name par le nom du package actuel de l'application.

adb backup -f ~/data.ab -noapk app.package.name

Cela vous invitera à "déverrouiller votre appareil et à confirmer l'opération de sauvegarde". Ne fournissez pas de mot de passe pour le chiffrement de sauvegarde, vous pourrez donc l'extraire ultérieurement. Cliquez sur le bouton "Sauvegarder mes données" sur votre appareil. L'écran affiche le nom du paquet que vous sauvegardez, puis se ferme tout seul s'il est terminé avec succès.

Le fichier data.ab résultant dans votre dossier de départ contient des données d'application au format de sauvegarde Android. Pour l'extraire, utilisez la commande suivante:

dd if=data.ab bs=1 skip=24 | openssl zlib -d | tar -xvf -

Si ce qui précède s'est terminé par l'erreur openssl:Error: 'zlib' is an invalid command., essayez ce qui suit.

dd if=data.ab bs=1 skip=24 | python -c "import zlib,sys;sys.stdout.write(zlib.decompress(sys.stdin.read()))" | tar -xvf -

Le résultat est le dossier apps/app.package.name/ contenant les données de l'application, y compris la base de données SQLite.

Pour plus de détails, vous pouvez consulter le article de blog original .

177
Sergei

Pour applications déboguables1 sur les périphériques non rootés, vous pouvez utiliser la commande suivante:

adb Shell run-as package.name chmod 666 /data/data/package.name/databases/file
adb pull /data/data/package.name/databases/file

Exemple:

adb Shell run-as com.app chmod 666 /data/data/com.app/databases/data.db
adb pull /data/data/com.app/databases/data.db

Définissez PATH adb pour les variables environnementales ou utilisez la commande cd sur le dossier Android SDK-platform tools.

Exemple:

cd /folder/Android-sdk/platform-tools/

puis utilisez la commande ci-dessus


1 Notez que la plupart des applications de Play Store sont non déboguables, car il est nécessaire de définir le drapeau debuggable dans le manifeste.

67
Lam Vinh

La plupart des réponses ici sont bien plus compliquées qu’elles ne doivent l’être. Si vous souhaitez simplement copier la base de données de votre application de votre téléphone sur votre ordinateur, vous avez simplement besoin de cette commande:

adb -d Shell "run-as your.package.name cat databases/database.name" > target.sqlite

Dans la commande ci-dessus, il vous suffit de renseigner le nom du package de votre application, le nom de la base de données et éventuellement le type de copie de la base de données.

Veuillez noter que cette commande spécifique ne fonctionnera que si vous n'avez qu'un seul périphérique connecté à votre ordinateur. Le paramètre -d signifie que le seul périphérique connecté sera ciblé. Mais il y a d'autres paramètres que vous pouvez utiliser à la place:

  • -e ciblera le seul émulateur en cours d'exécution 
  • -s <serialnumber> ciblera un périphérique avec un numéro de série spécifique . </ sub>

51
Xaver Kapeller

Avec Android Studio 3.0 ou une version ultérieure, il est possible d'extraire une base de données (également une préférence partagée, un répertoire de cache et d'autres) si l'application s'exécute en mode débogage sur un périphérique non root. 

Pour extraire la base de données en utilisant Android studio, suivez ces étapes. 

  1. Cliquez sur Afficher> Fenêtres d'outils> Explorateur de fichiers de périphériques
  2. Développez les nœuds / data/data/[nom-package]

 Steps followed in Android Studio 3.0

30
Shahidul
 adb Shell "run-as [package.name] chmod -R 777 /data/data/[package.name]/databases" 
 adb Shell "mkdir -p /sdcard/tempDB" 
 adb Shell "cp -r /data/data/[package.name]/databases/ /sdcard/tempDB/." 
 adb pull sdcard/tempDB/ . 
 adb Shell "rm -r /sdcard/tempDB/*"
6
Speakeasys

Pour Ubuntu (pas seulement?):

voir Sergeis Answer mais au lieu de openssl, utilisez zlib-flate:

chat appbackup.ab | (dd bs = 24 count = 0 skip = 1; cat) | zlib-flate -uncompress> appbackup.tar

Sinon, openssl lancera probablement: 

openssl: Erreur: 'zlib' est une commande non valide.

parce que openssl n'est pas compilé avec le support zlib dans Ubuntu

5
Murmel

Sinon, vous pouvez utiliser ma bibliothèque Ultra Debugger . Il permet de télécharger la base de données sous forme de fichier ou de modifier les valeurs directement dans le navigateur. Aucune racine nécessaire, très facile à utiliser.

1
BArtWell

vous pouvez facilement extraire le fichier sqlite de votre appareil (root, pas nécessaire)

  1. Aller au dossier SDK
  2. outils de plate-forme cd
  3. commencer adb

    cd /sdk/platform-tools./adb Shell

    Puis tapez la commande suivante dans le terminal

    ./adb -d Shell "run-as com.votre_packagename cat /data/data/com.votre_packagename/databases/jokhanaNepal> /sdcard/jokhana.sqlite".__

    Par exemple

    ./adb -d Shell "lancé par as.yuvii.app cat /data/data/com.yuvii.app/databases/jokhanaNepal> /sdcard/jokhana.sqlite"

    </ p>
1
yubaraj poudel

Depuis, rien ne fonctionne vraiment pour moi. Je crée un petit script BATCH Windows basé sur d’autres réponses combinées. J'espère que ça aidera quelqu'un. Simplement utiliser: backupDatabase <NomduCadre> <NomApplication> [TargetDirectory]. Il utilise la méthode de sauvegarde de Sergei et Android Backup Extractor .

@echo off

if [%1]==[] goto usage
if [%2]==[] goto usage
if NOT [%4]==[] goto usage

@echo Processing: preparations
set PACKAGE=%1
set APPLICATION_NAME=%2
set TARGET_DIR=%cd%
IF NOT "%~3"=="" set TARGET_DIR=%3

set PATH_ADB="c:\Program Files (x86)\Android\android-studio\sdk\platform-tools"
set PATH_ABE="c:\Programs\Android-backup-extractor-20140630-bin"
set PATH_7Z="c:\Program Files\7-Zip"

@echo Processing: backup
%PATH_ADB%\adb.exe backup -f %TARGET_DIR%\%APPLICATION_NAME%\%APPLICATION_NAME%.ab -noapk %PACKAGE%

@echo Processing: unpack
Java -jar %PATH_ABE%\abe.jar unpack %TARGET_DIR%\%APPLICATION_NAME%\%APPLICATION_NAME%.ab %TARGET_DIR%\%APPLICATION_NAME%\%APPLICATION_NAME%.ab.tar

@echo Processing: extract
cd %TARGET_DIR%\%APPLICATION_NAME%
%PATH_7Z%\7z.exe e %APPLICATION_NAME%.ab.tar "apps\%PACKAGE%\db\%APPLICATION_NAME%"

@echo Processing: cleaning
del %APPLICATION_NAME%.ab
del %APPLICATION_NAME%.ab.tar
goto :eof

:usage
@echo.Pull out SQLite database file from your Android device.
@echo.Needs: - connected device
@echo.       - device enable backup.
@echo.       - application enable backup
@echo.       - application in debug mode
@echo.       - installed Android Backup Extractor 
@echo.       - installed command line TAR extractor (7z, ...)
@echo.Does NOT need: root device
@echo.
@echo.Uses: - ADB backup (set PATH_ADB)
@echo.      - Android Backup Extractor (http://sourceforge.net/projects/adbextractor/) (set PATH_ABE)
@echo.      - Extract TAR container, uses 7z (set PATH_7Z)
@echo.
@echo.Usage: backupDatabase ^<PackageName^> ^<ApplicationName^> [TargetDirectory]
@echo.Example: backupDatabase com.foo.example ExampleApp 
@echo Example: backupDatabase com.foo.example ExampleApp workspace\AndroidProjects\Example
exit /B 1
1
Wooff

Sur Mac (aucune racine requise)

1. Go to platform-tools folder.
2) Run following command in terminal.

./adb -d Shell "run-as your.package.name cat databases/database.sqlite" > database.sqlite

Il copiera le fichier sqlite dans le dossier platform-tools.

1
Yogesh Suthar

Je donne la solution complète pour "enregistrer" et "restaurer" la base de données d'applications de/vers la mémoire de stockage interne (pas sur le PC avec adb).

J'ai fait deux méthodes une pour enregistrer et l'autre pour restaurer la base de données. Utilisez ces méthodes à la fin de la méthode onCreate () de MainActivity (l’une ou l’autre si vous souhaitez enregistrer ou restaurer la base de données).

enregistrer la base de données dans la mémoire interne:

void copyDatabase (){
        try {
            final String inFileName = "/data/data/<pakage.name>/databases/database.db";
            final String outFileName = Environment.getExternalStorageDirectory() + "database_backup.db";
            File dbFile = new File(inFileName);
            FileInputStream fis = new FileInputStream(dbFile);


            Log.d(TAG, "copyDatabase: outFile = " + outFileName);

            // Open the empty db as the output stream
            OutputStream output = new FileOutputStream(outFileName);

            // Transfer bytes from the inputfile to the outputfile
            byte[] buffer = new byte[1024];
            int length;
            while ((length = fis.read(buffer)) > 0) {
                output.write(buffer, 0, length);
            }

            // Close the streams
            output.flush();
            output.close();
            fis.close();
        }catch (Exception e){
            Log.d(TAG, "copyDatabase: backup error");
        }
    }

restaurer la base de données à partir de la mémoire interne:

void restoreDatabase (){
        try {
            final String inFileName = Environment.getExternalStorageDirectory() + "database_backup.db";
            final String outFileName = "/data/data/<package.name>/databases/database.db";
            File dbFile = new File(inFileName);
            FileInputStream fis = new FileInputStream(dbFile);

            Log.d(TAG, "copyDatabase: outFile = " + outFileName);

            // Open the empty db as the output stream
            OutputStream output = new FileOutputStream(outFileName);

            // Transfer bytes from the inputfile to the outputfile
            byte[] buffer = new byte[1024];
            int length;
            while ((length = fis.read(buffer)) > 0) {
                output.write(buffer, 0, length);
            }

            // Close the streams
            output.flush();
            output.close();
            fis.close();
        }catch (Exception e){
            Log.d(TAG, "copyDatabase: backup error");
        }
    }
0
Digital Cubes

Si vous essayez de le faire sur Android 6, demandez l'autorisation et utilisez le code de la réponse à cette question.

if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { 
    ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_RC); 
    return; 
} 

Une fois qu'il est accordé

@Override 
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == STORAGE_PERMISSION_RC) {
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            //permission granted  start reading or writing database
        } else { 
            Toast.makeText(this, "No permission to read external storage.", Toast.LENGTH_SHORT).show();
        } 
    } 
} 
0
Rodolfo Abarca

Sur la base de la réponse donnée par Lam Vinh, voici un fichier de commandes simple qui fonctionne pour moi sur mon Nexus 7 de première génération. Il invite l'utilisateur à entrer le nom du package, puis le nom de la base de données (sans l'extension .sqlite), puis le met dans c:\temp. Cela suppose que le sdk Android est défini dans les variables d'environnement.

@echo off
cd c:\temp\

set /p UserInputPackage= Enter the package name: 
set /p UserInputDB= Enter the database name: 

@echo on
adb Shell "run-as %UserInputPackage% chmod 666 /data/data/%UserInputPackage%/databases/%UserInputDB%.sqlite"
adb pull /data/data/%UserInputPackage%/databases/%UserInputDB%.sqlite
@echo off
pause
0
chutcher

Sur un appareil enraciné, vous pouvez:

// check that db is there
>adb Shell
# ls /data/data/app.package.name/databases
db_name.sqlite // a custom named db
# exit
// pull it
>adb pull /data/app.package.name/databases/db_name.sqlite
0
yanchenko

Si vous utilisez Android 4.0 ou une version ultérieure, et que vous utilisez un Mac , voici un script Ruby qui enregistrera le contenu de votre application sur le bureau. J'imagine que cela fonctionnerait également sous Ubuntu, même si je ne l'ai pas testé.

puts "enter your package name"
package_name = gets.chomp
puts "press the 'Back up my data' button on your device"
`adb backup -f ~/Desktop/data.ab -noapk #{package_name}`
puts "press enter once once the 'Backup finished' toast has appeared"
gets.chomp
puts "extracting..."
`dd if=data.ab bs=1 skip=24 | openssl zlib -d | tar -xvf -`

à exécuter -> Ruby votre_nom_fichier_Ruby.rb

Ce script est uniquement "un chemin heureux", assurez-vous donc que votre appareil est connecté et qu'un adb a été ajouté à votre profil.

0
 > is it possible to pull in any way a database of an Android device without having to root it? 

oui si votre application Android crée une copie de fichier de la base de données accessible à tous.

Android protège les données privées des applications afin qu'elles ne soient pas visibles/accessibles par d'autres applications. une base de données est une donnée privée. votre application peut bien sûr lire le fichier de base de données afin de pouvoir copier un fichier dans un fichier public visible.

0
k3b

C’est toujours mieux si les choses sont automatisées. C’est pourquoi j’ai écrit un simple script python pour copier le fichier db à partir d’un périphérique utilisant ADB. Cela vous fait gagner beaucoup de temps de développement si vous le faites fréquemment.

Ne fonctionne qu'avec debuggable apps si le périphérique est pas enraciné.

Voici un lien vers le Gist.

Exécutez-le en tant que: python copyandroiddbfile.py

import sys
import subprocess
import re

#/
# Created by @nieldeokar on 25/05/2018.
#/

# 1. Python script which will copy database file of debuggable apps from the Android device to your computer using ADB.
# 2. This script ask for PackageName and DatabaseName at runtime.
# 3. You can make it static by passing -d at as command line argument while running script and setting defaults in following way.
# 4. Edit script and change the values of varialbe packageName and dbName to debuggable app package name and database name then
# run script as : python Copydbfileandroid.py -d 

useDefaults = False


def checkIfPackageInstalled(strSelectedDevice) :

    packageName = 'com.nileshdeokar.healthapp.debug'
    dbName = 'healthapp.db'


    if not useDefaults : 
        print('Please enter package name : ')
        packageName = raw_input()

    packageString = 'package:'+packageName

    try:
        adbCheckIfPackageInstalledOutput = subprocess.check_output('adb -s ' + strSelectedDevice + ' Shell pm list packages | grep -x '+ packageString, Shell=True)
    except subprocess.CalledProcessError as e:
                print "Package not found"
                return


    if packageString.strip() == adbCheckIfPackageInstalledOutput.strip() : 
        if not useDefaults : 
            print('Please enter db name : ')
            dbName = raw_input()

        adbCopyDbString = 'adb -s '+strSelectedDevice + ' -d Shell \"run-as '+packageName+' cat /data/data/'+packageName+'/databases/'+ dbName +'\" > '+dbName

        try:
            copyDbOp = subprocess.check_output(adbCopyDbString,Shell=True)
        except subprocess.CalledProcessError as e:
                return

        if "is not debuggable" in copyDbOp :
            print packageString + 'is nto debuggable'

        if copyDbOp.strip() == "":
            print 'Successfully copied '+dbName + ' in current directory'

    else :
        print 'Package is not installed on the device'



defaultString = "-d"
if len(sys.argv[1:]) > 0 and sys.argv[1] == defaultString :
        useDefaults = True

listDevicesOutput = subprocess.check_output("adb devices", Shell=True)
listDevicesOutput = listDevicesOutput.replace("List of devices attached"," ").replace("\n","").replace("\t","").replace("\n\n","")

numberofDevices = len(re.findall(r'device+', listDevicesOutput))

connectedDevicesArray = listDevicesOutput.split("device")   
del connectedDevicesArray[-1] 


strSelectedDevice = ''
if(numberofDevices > 1) :
    print('Please select the device : \n'),

    for idx, device in enumerate(connectedDevicesArray):
        print idx+1,device

    selectedDevice = raw_input()

    if selectedDevice.isdigit() :
        intSelected = int(selectedDevice)
        if 1 <= intSelected <= len(connectedDevicesArray) :
            print 'Selected device is : ',connectedDevicesArray[intSelected-1]
            checkIfPackageInstalled(connectedDevicesArray[intSelected-1])
        else :
            print 'Please select in range'
    else : 
        print 'Not valid input'

Elif numberofDevices == 1 :
    checkIfPackageInstalled(connectedDevicesArray[0])
Elif numberofDevices == 0 :
    print("No device is attached")
0
Nilesh Deokar