Android - Получение базы данных SQlite на устройстве Android

102

Я искал везде и не могу найти настоящего точного ответа или руководства о том, как, если это возможно, это сделать.

Можно ли каким-либо образом получить базу данных Android-устройства без рутирования? Мне просто нужно каким-либо образом извлечь эти данные, чтобы собрать их на моем компьютере, так как я могу это сделать? мне нужно перепрограммировать приложение или какой-либо другой метод, о котором вы, ребята, знаете, но помните, без рутирования устройства. Спасибо

DeX03
источник
вот работоспособное решение: stackoverflow.com/a/29257875/291427
kmalmur
stackoverflow.com/a/28558521/1939564
Мухаммад Бабар,
1
stackoverflow.com/questions/13006315 Вытяните db без рутирования
Naveen Prince P

Ответы:

78

Распространенный способ добиться желаемого - использовать команду ADB pull.

Другой способ, который я предпочитаю в большинстве случаев, - это скопировать базу данных по коду на 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) {

}

Не забудьте указать в манифесте разрешение на запись на SD, как показано ниже.

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
КарлКарлсом
источник
1
ну, я собираюсь использовать это на вкладке галактики Samsung, у которой нет SD-карты, так как мне это сделать там?
DeX03
и я должен использовать двойной //?
DeX03,
Да, это потому, что / - это специальный строковый символ. // в вашем "//" приведет к /.
KarlKarlsom
4
В SQLiteDatabase есть getPathметод , а не путь к базе данных .
Will
Блестящий ответ. очень умно, полезно и просто.
Гунду Бандгар
179

Если ваше устройство работает под управлением Android v4 или выше, вы можете получить данные приложения, включая его базу данных, без root с помощью adb backupкоманды, затем извлечь файл резервной копии и получить доступ к базе данных sqlite.

Сначала сделайте резервную копию данных приложения на свой компьютер через USB-кабель с помощью следующей команды, заменив app.package.nameфактическое имя пакета приложения.

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

Вам будет предложено «разблокировать устройство и подтвердить операцию резервного копирования». Не указывайте пароль для резервного копирования , чтобы его можно было извлечь позже. Нажмите на своем устройстве кнопку «Создать резервную копию моих данных». На экране отобразится имя пакета, для которого выполняется резервное копирование, а после успешного завершения он закроется сам.

Полученный data.abфайл в вашей домашней папке содержит данные приложения в формате резервной копии Android. Чтобы извлечь его, используйте следующую команду:

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

Если вышеуказанное завершилось с openssl:Error: 'zlib' is an invalid command.ошибкой, попробуйте следующее.

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

В результате apps/app.package.name/получится папка, содержащая данные приложения, в том числе базу данных sqlite.

Для получения дополнительной информации вы можете проверить исходное сообщение в блоге .

Сергей
источник
9
Для тех, у кого zlib не скомпилирован без zlib, ознакомьтесь с ответом на blog.shvetsov.com/2013/02/…, чтобы извлечь данные с помощью python.
ingh.am
2
Для пользователей Windows, у которых команда unpack недоступна, вы можете использовать Java-приложение "Android Backup Extractor" ( sourceforge.net/projects/adbextractor ). См. Forum.xda-developers.com/showthread.php?t=2011811, чтобы узнать о командах для распаковки файла .ab.
lalitm
7
на моем MacBook Pro я получаю сообщение openssl:Error: 'zlib' is an invalid command., на которое я ответил dd if=data.ab bs=1 skip=24 | python -c "import zlib,sys;sys.stdout.write(zlib.decompress(sys.stdin.read()))" | tar -xvf -ОДНАКО после того, как оно показывает, 17+0 records in17+0 records out17 bytes transferred in 0.000064 secsчто нет никаких доказательств того, что с папкой что-либо было сделано. Поскольку это всего 17 байт, я предполагаю, что эта команда также не удалась. Я думаю, это плохо, что я не могу adb pullбазу данных из отладочного приложения !!
Someone Somewhere
12
совет от профессионала: эта резервная копия не будет работать, если в манифесте приложения отображаетсяandroid:allowBackup="false"
Somewhere Somewhere
9
Мой opensslна Mac OS X не поддерживают zlibкоманду либо, поэтому я переустановил один с варевом: brew reinstall openssl. Это не заменит вашу систему openssl. Поэтому я изменил команду PATH только для текущего сеанса: export PATH=/usr/local/opt/openssl/bin:$PATHпосле чего мог успешно выполнять команды из этого ответа.
Алекс Н.
69

Для отлаживаемых приложений 1 на некорневых устройствах вы можете использовать следующую команду:

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

Пример:

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

Установите PATH adb для переменных среды или используйте команду cd для android sdk folder platform-tools.

Пример:

cd /folder/android-sdk/platform-tools/

затем используйте команду выше


1 Обратите внимание, что большинство приложений в магазине Play не могут быть отлажены, так как для этого требуется установить флаг отладки в манифесте.

Лам Винь
источник
8
После замены package.nameна пакет приложения возвращается ошибка:run-as: Package 'com.my.app' is unknown
Someone Somewhere
3
Вроде работает не на всех телефонах. Работает для Nexus 4, не работает, например, для SGS4.
Роман Миненок
2
Где сохранен файл db?
Войтех Пешек
3
Раньше это работало для меня, но я не могу заставить это работать на моем Nexus 7, обновленном до Android 5. Может ли кто-нибудь подтвердить, что это работает на Android 5?
treeAreEverywhere
15
Вот хак для Android 5 (Lollipop) 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 / *"
Rubin Yoo
55

Большинство ответов здесь намного сложнее, чем должно быть. Если вы просто хотите скопировать базу данных своего приложения со своего телефона на компьютер, вам просто понадобится эта команда:

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

Все, что вам нужно заполнить в приведенной выше команде, - это имя пакета вашего приложения, название базы данных и, возможно, куда и куда вы хотите скопировать базу данных.

Обратите внимание, что эта конкретная команда будет работать только в том случае, если к вашему компьютеру подключено только одно устройство. В-d означает параметр , что только подключенное устройство будет адресоваться. Но есть и другие параметры, которые вы можете использовать вместо этого:

  • -e будет нацелен на единственный работающий эмулятор
  • -s <serialnumber> будет нацеливаться на устройство с определенным серийным номером.

Ксавер Капеллер
источник
Как я могу открыть этот файл?
Jehad
@Jehad: У меня была такая же проблема. Я нашел этот способ, и он у меня работает. Установите SSHDroid на свой телефон, adb -d shell "run-as your.package.name cat databases/database_name.db > /mnt/sdcard/database_name.db" запустите SSHDroidFileZilla и подключитесь к телефону по протоколу SFTP. Установите / mnt / sdcard в качестве удаленного каталога по умолчанию.
Zoltán Süle
Самый простой ответ, если вы хотите получить базу данных собственного приложения. Два дополнения: 1) если вы не уверены в имени своей базы данных, вы можете использовать команду ls для вывода списка файлов в папке базы данных ( adb -d shell "run-as your.package.name ls databases") и 2) вы можете захотеть получить любые другие связанные файлы вместе с базой данных в в моем случае извлечение файлов -smh и -wal было единственным способом заставить браузер БД для SQLite открыть базу данных,
Ронан,
36

Используя Android Studio 3.0 или более позднюю версию, можно получить базу данных (а также общие настройки, каталог кеша и другие), если приложение работает в режиме отладки на некорневом устройстве.

Чтобы извлечь базу данных с помощью студии Android, выполните следующие действия.

  1. Щелкните Вид > Окна инструментов > Проводник файлов устройства .
  2. Разверните узлы / data / data / [package-name] .

Действия, выполняемые в Android Studio 3.0

Шахидул
источник
Спасибо. Загруженные файлы из эмулятора, при этом не могут получить их из некорневого Galaxy S4.
CoolMind
Можете ли вы извлечь базу данных из любого приложения или только из собственного приложения?
live-love
Любое приложение, кроме предварительного условия, должно быть отлаживаемым.
Shahidul
6
 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/*"
SaundersB
источник
5

Для Ubuntu (не только?):

см. ответ Сергея, но вместо openssl используйте zlib-flate:

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

В противном случае openssl, вероятно, выдаст:

openssl: Ошибка: «zlib» - недопустимая команда.

потому что openssl не скомпилирован с поддержкой zlib в Ubuntu

Мурмель
источник
1

Поскольку у меня ничего не работает. Я создаю небольшой сценарий BATCH для Windows на основе других ответов, объединенных вместе. Надеюсь, это кому-нибудь поможет. Простое использование: backupDatabase <PackageName> <ApplicationName> [TargetDirectory]. Он использует метод резервного копирования Сергея и 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
Wooff
источник
1

вы можете легко извлечь файл sqlite со своего устройства (root не требуется)

  1. Перейти в папку SDK
  2. инструменты платформы CD
  3. запустить adb

    cd / sdk / platform-tools ./adb shell

    Затем введите следующую команду в терминале

    ./adb -d shell "run-as com.your_packagename cat /data/data/com.your_packagename/databases/jokhanaNepal> /sdcard/jokhana.sqlite"

    Например,

    ./adb -d shell "run-as com.yuvii.app cat /data/data/com.yuvii.app/databases/jokhanaNepal> /sdcard/jokhana.sqlite"

Юбарадж Пудель
источник
1

Если вы пытаетесь сделать это на android 6, запросите разрешение и используйте код ответа на этот вопрос

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

Как только это будет предоставлено

@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();
        } 
    } 
} 
Родольфо Абарка
источник
1

В качестве альтернативы вы можете использовать мою библиотеку Ultra Debugger . Это позволяет загружать базу данных в виде файла или редактировать значения прямо в браузере. Корень не требуется, очень прост в использовании.

BArtWell
источник
1

На Mac (root не требуется)

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

Он скопирует файл sqlite в папку инструментов платформы.

Йогеш Сутар
источник
Кажется, это работает, только если приложение скомпилировано для отладки.
Дэвид Берри
@DavidBerry Да, он будет извлекать db, если скомпилирован для отладки, иначе вы могли бы вытащить db любого приложения. И это будет серьезная проблема безопасности приложения. :)
Йогеш Сутар
0
 > is it possible to pull in any way a database of an Android device without having to root it? 

да, если ваше приложение для Android создает копию файла базы данных, доступную для всех.

Android защищает личные данные приложений, поэтому они не видны / недоступны другим приложениям. база данных - это частные данные. ваше приложение, конечно, может читать файл базы данных, чтобы сделать копию файла в какой-то общедоступный видимый файл.

k3b
источник
0

На устройстве с root-доступом вы можете:

// 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
Янченко
источник
Я не уверен на 100%, но я думаю, что перед тем, как тянуть, необходимо> su и дать разрешение
pavol.franek
0

Основываясь на ответе Лам Виня, вот простой командный файл, который работает для меня на моем Nexus 7 1-го поколения. Он предлагает пользователю ввести имя пакета, а затем имя базы данных (без расширения .sqlite) и помещает его в c: \ temp. Предполагается, что у вас установлен Android sdk в переменных среды.

@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

Если у вас Android 4.0 или более поздняя версия, и вы используете Mac , то вот сценарий Ruby, который сохранит содержимое вашего приложения на рабочий стол. Я предполагаю, что это также будет работать в Ubuntu, хотя я не тестировал это.

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 -`

для запуска -> рубин your_ruby_file_name.rb

Этот сценарий предназначен только для «счастливого пути», поэтому убедитесь, что ваше устройство подключено и что adb был добавлен в ваш профиль.

Свифти МакСвифтертон
источник
0

Даю комплексное решение по "сохранению" и "восстановлению" базы данных приложения во внутреннем хранилище (не на ПК с adb).

Я использовал два метода: один для сохранения, а другой - для восстановления базы данных. Используйте эти методы в конце onCreate () в MainActivity (один или другой, если вы хотите сохранить или восстановить базу данных).

сохранить базу данных во внутреннем хранилище:

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

восстановить базу данных из внутреннего хранилища:

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

Всегда лучше, если все будет автоматизировано, поэтому я написал простой скрипт на Python для копирования db файла с устройства с помощью ADB. Это экономит время на разработку, если вы делаете это часто.

Работает только с отлаживаемыми приложениями, если устройство не рутировано.

Вот ссылка на суть.

Запустите его как: 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")
Нилеш Деокар
источник
-1

Если вам нужен файл базы данных

См. DDMS> Просмотр файлов

найдите свой файл db по имени вашего пакета

затем нажмите, чтобы извлечь файл с устройства (только для корневого устройства)

MAC
источник
3
это можно сделать, но на устройстве с
рутированным доступом
1
это не работает на устройстве без рута. Это должно быть сказано в вашем ответе.
tony9099