Android - вытащить базу данных SQlite для Android устройства
Я искал повсюду, и я не могу найти действительно точный ответ или учебник о том, как, если это возможно, сделать это.
Можно ли каким-либо образом вытащить базу данных устройства Android без необходимости рутировать ее? Мне просто нужно извлечь эти данные любым способом, чтобы собрать их на моем компьютере, так как я могу это сделать? Должен ли я перепрограммировать приложение или любой другой метод, о котором вы, ребята, знаете, но помните, не рутируя устройство. Спасибо
19 ответов
Обычный способ достичь желаемого - использовать команду 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" />
Если ваше устройство работает под управлением Android v4 или выше, вы можете получить данные приложения, включая базу данных, без рута, используя 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.
Для более подробной информации вы можете проверить оригинальное сообщение в блоге.
Для отлаживаемых приложений 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.
Пример:
cd /folder/android-sdk/platform-tools/
затем используйте вышеуказанную команду
1 Обратите внимание, что большинство приложений в магазине Play не подлежат отладке, поскольку для них требуется установить флаг отладки в манифесте.
Большинство ответов здесь намного сложнее, чем они должны быть. Если вы просто хотите скопировать базу данных вашего приложения с телефона на компьютер, вам просто нужна эта команда:
adb -d shell "run-as your.package.name cat databases/database.name" > target.sqlite
Все, что вам нужно заполнить в приведенной выше команде, - это имя пакета вашего приложения, как называется база данных и, по желанию, куда / куда вы хотите скопировать базу данных.
Обратите внимание, что эта конкретная команда будет работать только в том случае, если к вашему компьютеру подключено только одно устройство. -d
Параметр означает, что будет выбрано только одно подключенное устройство. Но есть и другие параметры, которые вы можете использовать вместо:
-e
будет нацелен на единственный работающий эмулятор-s <serialnumber>
будет ориентирован на устройство с конкретным серийным номером.
Используя Android Studio 3.0 или более позднюю версию, можно получить базу данных (также общие настройки, каталог кэша и другие), если приложение работает в режиме отладки на устройстве без рута.
Чтобы вытащить базу данных с помощью Android Studio, выполните следующие действия.
- Нажмите " Вид" > " Инструменты Windows" > " Проводник".
- Разверните /data/data/[имя-пакета] узлы.
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/*"
Для Ubuntu (не только?):
см. Sergeis Answer, но вместо openssl используйте zlib-flate:
кошка appbackup.ab | (dd bs=24 count=0 skip=1; cat) | zlib-flate -uncompress > appbackup.tar
В противном случае openssl, вероятно, сгенерирует:
openssl: Ошибка: 'zlib' - недопустимая команда.
потому что openssl не скомпилирован с поддержкой zlib в Ubuntu
Так как для меня ничего не работает. Я создаю небольшой скрипт Windows BATCH, основанный на других ответах, объединенных вместе. Надеюсь, это поможет кому-нибудь. Просто использование: backupDatabase
@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
На Mac (без рута требуется)
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 в папку platform-tools.
Если вы пытаетесь сделать это на 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();
}
}
}
В качестве альтернативы вы можете использовать мою библиотеку Ultra Debugger. Это позволяет загружать базу данных в виде файла или редактировать значения непосредственно в браузере. Нет необходимости в корне, очень прост в использовании.
Вы можете легко извлечь файл sqlite с вашего устройства (root не требуется)
- Перейти в папку SDK
- cd platform-tools
начать ADB
оболочка cd /sdk/platform-tools ./adb
Затем введите следующую команду в терминале./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"
> is it possible to pull in any way a database of an Android device without having to root it?
да, если ваше приложение для Android создает копию базы данных, доступную для всех.
Android защищает личные данные приложений, поэтому они не видны и недоступны для других приложений. база данных - это личные данные. Ваше приложение, конечно, может прочитать файл базы данных, чтобы оно могло скопировать файл в какой-либо общедоступный видимый файл.
Я даю полное решение "сохранить" и "восстановить" базу данных приложения в / из внутреннего хранилища (не на ПК с 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");
}
}
Основываясь на ответе Lam Vinh, вот простой пакетный файл, который работает для меня на моем Nexus 7 первого поколения. Он предлагает пользователю ввести имя пакета, а затем имя базы данных (без расширения.sqlite) и поместить его в с:\ темп. Это предполагает, что у вас установлен 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
Если у вас 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 -`
запустить -> ruby your_ruby_file_name.rb
Этот скрипт предназначен только для "счастливого пути", поэтому убедитесь, что ваше устройство подключено и что adb добавлен в ваш профиль.
Всегда лучше, если все будет автоматизировано. Поэтому я написал простой скрипт на python для копирования файла db с устройства с использованием ADB. Это экономит много времени на разработку, если вы делаете это часто.
Работает только с отлаживаемыми приложениями, если устройство не имеет root-прав.
Запустите это как: 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")
На рутованном устройстве вы можете:
// 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
Вот решение с картинками о том, как вы можете получить доступ к файловой системе не рутированного 4.2 телефона с помощью ssh из ubuntu 16.04
как получить доступ к файловой системе не рутированного 4.2 телефона Android по ssh из ubuntu 16.04
Если вы хотите, чтобы ваш файл базы данных
Смотрите DDMS > Файл исследовать
найдите свой файл БД из названия вашего пакета
затем нажмите, чтобы вытащить файл с устройства (только для корневого устройства)