Android-拉入SQlite数据库Android设备

Android-拉入SQlite数据库Android设备,sqlite,android,Sqlite,Android,我到处都找过了,但我找不到一个真正准确的答案,也找不到关于如何做到这一点的教程(如果可能的话) 有没有可能在不需要根目录的情况下以任何方式提取Android设备的数据库?我只需要以任何方式提取数据,以便在我的pc上收集数据,那么我如何才能执行此操作?我是否需要重新编程应用程序或任何你们知道的方法,但请记住,不必在设备上生根。谢谢 > is it possible to pull in any way a database of an Android device without havi

我到处都找过了,但我找不到一个真正准确的答案,也找不到关于如何做到这一点的教程(如果可能的话)

有没有可能在不需要根目录的情况下以任何方式提取Android设备的数据库?我只需要以任何方式提取数据,以便在我的pc上收集数据,那么我如何才能执行此操作?我是否需要重新编程应用程序或任何你们知道的方法,但请记住,不必在设备上生根。谢谢

 > is it possible to pull in any way a database of an Android device without having to root it? 
是的,如果你的android应用程序创建了一个每个人都可以访问的数据库文件副本

android保护应用程序的私有数据,因此其他应用程序无法看到/访问这些数据。数据库是私有数据。
您的应用程序当然可以读取数据库文件,以便将文件复制到某个公共可见文件。

实现所需功能的常用方法是使用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" />

如果需要数据库文件

请参阅DDMS>文件

从包名中查找数据库文件


然后单击从设备中拉出文件(仅限根设备)

在根设备上,您可以:

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

如果您的设备运行的是Android v4或更高版本,您可以使用
adb backup
命令在不使用root的情况下提取应用程序数据,包括其数据库,然后提取备份文件并访问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 -
adb shell run-as package.name chmod 666 /data/data/package.name/databases/file
adb pull /data/data/package.name/databases/file
如果上述操作以openssl:Error结束:“zlib”是无效命令。Error,请尝试以下操作

dd if=data.ab bs=1 skip=24 | python -c "import zlib,sys;sys.stdout.write(zlib.decompress(sys.stdin.read()))" | tar -xvf -
结果是包含应用程序数据(包括sqlite数据库)的
apps/app.package.name/
文件夹

有关更多详细信息,请查看。

有关非根设备上的1,您可以使用以下命令:

dd if=data.ab bs=1 skip=24 | openssl zlib -d | tar -xvf -
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
cd /folder/android-sdk/platform-tools/
为环境变量设置路径adb或使用cd命令设置android sdk文件夹平台工具

例如:

adb shell run-as com.app chmod 666 /data/data/com.app/databases/data.db
adb pull /data/data/com.app/databases/data.db
cd /folder/android-sdk/platform-tools/
然后使用上面的命令


1请注意,Play store中的大多数应用程序都不可调试,因为它需要在清单中设置。

对于Ubuntu(不仅仅是?):

请参见但不使用openssl使用zlib flate:

cat APPBACK.ab |(dd bs=24计数=0跳过=1;cat)| zlib平面 -解压缩>appbackup.tar

否则,openssl可能会抛出:

openssl:错误:“zlib”是无效命令


因为openssl在Ubuntu中没有使用zlib支持编译,所以对我来说什么都不管用。我在其他答案的基础上创建了一个小的windows批处理脚本。希望它能帮助别人。简单用法:backupdatebase[TargetDirectory]。 它使用Sergei的备份方法和

@echo关闭
如果[%1]=[]转到使用情况
如果[%2]=[]转到使用情况
如果不是[%4]=[]转到使用情况
@回波处理:准备工作
设置包=%1
设置应用程序名称=%2
设置目标目录=%cd%
如果不是“%~3”==”设置目标\u DIR=%3
设置路径\u ADB=“c:\Program Files(x86)\Android\Android studio\sdk\platform tools”
设置路径_ABE=“c:\Programs\android-backup-extractor-20140630-bin”
设置路径_7Z=“c:\Program Files\7-Zip”
@回显处理:备份
%路径\u ADB%\ADB.exe备份-f%TARGET\u DIR%\%APPLICATION\u NAME%\%APPLICATION\u NAME%.ab-noapk%PACKAGE%
@回波处理:解包
java-jar%PATH\u ABE%\ABE.jar解包%TARGET\u DIR%\%APPLICATION\u NAME%\%APPLICATION\u NAME%.ab%TARGET\u DIR%\%APPLICATION\u NAME%\%APPLICATION\u NAME%.ab.tar
@回波处理:提取
cd%TARGET\u DIR%\%APPLICATION\u NAME%
%PATH_7Z%\7Z.exe e%应用程序名称%.ab.tar“应用程序\%PACKAGE%\db\%APPLICATION名称%”
@回波处理:清洗
删除%APPLICATION\u NAME%.ab
删除%APPLICATION\u NAME%.ab.tar
后藤:eof
:用法
@从android设备中取出SQLite数据库文件。
@需要:-连接的设备
@回声设备启用备份。
@回声应用程序启用备份
@回声调试模式下的应用程序
@回声已安装的Android备份提取器
@回声已安装的命令行TAR提取器(7z,…)
@echo.不需要:根设备
@回声。
@echo.Uses:-ADB备份(设置路径\u ADB)
@回声Android备份提取器(http://sourceforge.net/projects/adbextractor/)(设置路径_ABE)
@回声提取焦油容器,使用7z(设置路径_7z)
@回声。
@用法:backupdatebase^^[TargetDirectory]
@echo.Example:backupdatebase com.foo.ExampleApp
@echo示例:backupdatebase com.foo.Example示例应用程序工作区\AndroidProjects\Example
退出/B 1

根据林荣给出的答案,这里有一个简单的批处理文件,适用于我的第一代Nexus 7。它提示用户输入包名,然后输入数据库名(不带.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

如果您使用的是安卓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您的\u ruby\u文件\u name.rb

此脚本仅为“快乐路径”,因此请确保您的设备已连接,并且adb已添加到您的配置文件中。

您可以轻松地
 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/*"
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");
        }
    }
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
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")