sqlite - tutorial - proyectos en android studio con base de datos
Android-extracción de la base de datos SQlite del dispositivo Android (20)
He buscado en todas partes y no puedo encontrar una respuesta precisa o un tutorial sobre cómo, si es posible, hacer esto.
¿Es posible tirar de alguna manera una base de datos de un dispositivo Android sin tener que rootearlo? solo necesito extraer esos datos de alguna forma para poder recopilarlos en mi pc, entonces, ¿cómo puedo hacer esto? ¿Tengo que reprogramar la aplicación o el método que ustedes conocen, pero recuerde sin rootear el dispositivo. Gracias
Alternativamente puede usar mi biblioteca Ultra Debugger . Permite descargar la base de datos como archivo o editar valores directamente en el navegador. No se necesita root, es muy fácil de usar.
Aquí hay una solución con imágenes sobre cómo puede acceder a un sistema de archivos de un teléfono Android 4.2 no rooteado por ssh desde ubuntu 16.04
Con Android Studio 3.0 o una versión posterior, es posible extraer la base de datos (también preferencias compartidas, directorio de caché y otros) si la aplicación se ejecuta en modo de depuración en un dispositivo no rooteado.
Para extraer la base de datos usando android studio, sigue estos pasos.
- Haga clic en Ver > Herramientas de Windows > Explorador de archivos de dispositivo .
- Expandir / datos / datos / [nombre del paquete] nodos.
Desde entonces, nada realmente funciona para mí. Creo un script de Windows BATCH basado en otras respuestas combinadas. Espero que ayude a alguien. Simplemente use: backupDatabase <PackageName> <ApplicationName> [TargetDirectory]. Utiliza el método de copia de seguridad de Sergei y sourceforge.net/projects/adbextractor .
@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
Doy la solución completa para "guardar" y "restaurar" la base de datos de la aplicación desde / hacia el almacenamiento interno (no a la PC con adb).
He hecho dos métodos, uno para guardar y otro para restaurar la base de datos. Utilice estos métodos al final de onCreate () en MainActivity (uno u otro si desea ahorrar o restaurar la base de datos).
guardar la base de datos en el almacenamiento interno:
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");
}
}
restaurar la base de datos desde el almacenamiento interno:
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");
}
}
En base a la respuesta dada por Lam Vinh, aquí hay un archivo por lotes simple que funciona para mí en mi Nexus 7 de primera generación. Solicita al usuario ingresar el nombre del paquete y luego el nombre de la base de datos (sin la extensión .sqlite) y lo pone en c: / temp Esto supone que tiene el conjunto de sdk de Android en las variables de entorno.
@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
En un dispositivo rooteado, puede:
// 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
La mayoría de las respuestas aquí son mucho más complicadas de lo que deben ser. Si solo quieres copiar la base de datos de tu aplicación desde tu teléfono a tu computadora, entonces solo necesitas este comando:
adb -d shell "run-as your.package.name cat databases/database.name" > target.sqlite
Todo lo que debe completar en el comando anterior es el nombre del paquete de su aplicación, a qué se llama la base de datos y, opcionalmente, a qué / dónde desea que se copie la base de datos.
Tenga en cuenta que este comando específico solo funcionará si solo tiene un dispositivo conectado a su computadora. El parámetro -d
significa que el único dispositivo conectado será el objetivo. Pero hay otros parámetros que puede usar en su lugar:
-
-e
dirigirá al único emulador en ejecución -
-s <serialnumber>
número de serie-s <serialnumber>
apuntará a un dispositivo con un número de serie específico.
Para las aplicaciones depurables 1 en dispositivos no rooteados , puede usar el siguiente comando:
adb shell run-as package.name chmod 666 /data/data/package.name/databases/file
adb pull /data/data/package.name/databases/file
Ejemplo:
adb shell run-as com.app chmod 666 /data/data/com.app/databases/data.db
adb pull /data/data/com.app/databases/data.db
Establezca PATH adb para Enviroment Variables o use el comando cd en la plataforma de Android sdk platform-tools.
Ejemplo:
cd /folder/android-sdk/platform-tools/
luego usa el comando anterior
1 Tenga en cuenta que la mayoría de las aplicaciones en Play Store no son depurables, ya que requiere establecer el indicador de depuración en el manifiesto.
Para Ubuntu (¿no solo?):
ver Respuesta de Sergeis pero en lugar de openssl use zlib-flate:
gato appbackup.ab | (dd bs = 24 conteo = 0 omisión = 1; cat) | zlib-flate -uncompress> appbackup.tar
De lo contrario, openssl probablemente lanzará:
openssl: Error: ''zlib'' es un comando no válido.
porque openssl no está compilado con soporte zlib en Ubuntu
Si está intentando hacerlo en Android 6 solicite el permiso y use el código de la respuesta de esta pregunta
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;
}
Una vez que se concede
@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();
}
}
}
Si quieres tu archivo de base de datos
Ver el DDMS> Explorar archivo
encuentre su archivo db a partir del nombre de su paquete
a continuación, haga clic en extraer un archivo del dispositivo (dispositivo rooteado solamente)
Si su dispositivo está ejecutando Android v4 o superior, puede extraer los datos de la aplicación, incluida su base de datos, sin root utilizando adb backup
comando de adb backup
, luego extraer el archivo de copia de seguridad y acceder a la base de datos sqlite.
Primero app.package.name
copia de seguridad de los datos de la aplicación en su PC mediante un cable USB con el siguiente comando, reemplace app.package.name
con el nombre del paquete real de la aplicación.
adb backup -f ~/data.ab -noapk app.package.name
Esto le pedirá que "desbloquee su dispositivo y confirme la operación de respaldo". No proporcione una contraseña para el cifrado de respaldo , para que pueda extraerlo más tarde. Haga clic en el botón "Copia de seguridad de mis datos" en su dispositivo. La pantalla mostrará el nombre del paquete del que está realizando la copia de seguridad, y luego se cerrará por sí solo al finalizar con éxito.
El archivo data.ab
resultante en su carpeta de inicio contiene datos de la aplicación en formato de copia de seguridad de Android. Para extraerlo, usa el siguiente comando:
dd if=data.ab bs=1 skip=24 | openssl zlib -d | tar -xvf -
Si lo anterior terminó con openssl:Error: ''zlib'' is an invalid command.
error, prueba lo siguiente
dd if=data.ab bs=1 skip=24 | python -c "import zlib,sys;sys.stdout.write(zlib.decompress(sys.stdin.read()))" | tar -xvf -
El resultado es la apps/app.package.name/
carpeta que contiene los datos de la aplicación, incluida la base de datos sqlite.
Para obtener más información, puede consultar la publicación original del blog .
Siempre es mejor si las cosas están automatizadas. Es por eso que escribí un script simple de python para copiar el archivo db del dispositivo usando ADB. Ahorra mucho tiempo de desarrollo si lo haces con frecuencia.
Funciona solo con aplicaciones depurables si el dispositivo no está rooteado.
Aquí hay un enlace a la esencia.
Ejecútelo como: 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")
Una forma común de lograr lo que desea es usar el comando de extracción ADB.
Otra forma que prefiero en la mayoría de los casos es copiar la base de datos por código a la tarjeta 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) {
}
No olvides configurar el permiso para escribir en SD en tu manifiesto, como a continuación.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
puede extraer fácilmente el archivo sqlite de su dispositivo (no es necesario root)
- Ir a la carpeta SDK
- herramientas de plataforma cd
comenzar adb
cd / sdk / platform-tools ./adb shell
Luego escriba el siguiente comando en la terminal./adb -d shell "run-as com.your_packagename cat /data/data/com.your_packagename/databases/jokhanaNepal> /sdcard/jokhana.sqlite"
Por ej../adb -d shell "run-as com.yuvii.app cat /data/data/com.yuvii.app/databases/jokhanaNepal> /sdcard/jokhana.sqlite"
En Mac (NO se requiere 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
Copiará el archivo sqlite en la carpeta platform-tools.
Si tienes Android 4.0 o una versión superior y estás en una Mac , aquí tienes una secuencia de comandos de ruby que guardará los contenidos de tu aplicación en el escritorio. Me imagino que esto también funcionaría en Ubuntu, aunque no lo probé.
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 -`
ejecutar -> ruby your_ruby_file_name.rb
Este script es solo una "ruta feliz", así que asegúrese de que su dispositivo esté conectado y que adb se haya agregado a su perfil.
> is it possible to pull in any way a database of an Android device without having to root it?
sí, si su aplicación de Android crea una copia de archivo de la base de datos accesible para todos.
Android protege los datos privados de las aplicaciones para que no sean visibles ni accesibles por otras aplicaciones. una base de datos es información privada. su aplicación puede, por supuesto, leer el archivo de la base de datos para que pueda hacer una copia de archivo en algún archivo público visible.
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/*"