web-dev-qa-db-ja.com

Android-SQliteデータベースの取得Androidデバイス

私はいたるところを見てきましたが、本当の正確な答えや、可能な場合はこれを行う方法に関するチュートリアルを見つけることができません。

Androidデバイスのデータベースをルート化せずに何らかの方法でプルすることは可能ですか?私のPCでデータを収集するには、何らかの方法でそのデータを抽出する必要がありますが、どうすればこれを実行できますか?アプリや、皆さんが知っている方法を再プログラムする必要がありますが、デバイスをルート化せずに覚えておいてください。ありがとう

93
DeX03

目的を達成する一般的な方法は、ADB pullコマンドを使用することです。

ほとんどの場合、私が好むもう1つの方法は、コードでデータベースを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" />
77
KarlKarlsom

デバイスがAndroid v4以上を実行している場合、adb backupコマンドを使用して、データベースを含むアプリデータrootなしをプルできます。バックアップファイルを抽出し、sqliteデータベースにアクセスします。

次のコマンドを使用して、最初にUSBケーブル経由でアプリデータをPCにバックアップし、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 -

結果は、sqliteデータベースを含むアプリケーションデータを含むapps/app.package.name/フォルダーです。

詳細については、 元のブログ投稿 を確認してください。

178
Sergei

Forデバッグ可能なアプリ1 on非ルートデバイスでは、次のコマンドを使用できます。

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フォルダーplatform-toolsに移動します。

例:

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

その後、上記のコマンドを使用します


1 マニフェストで debuggableフラグ を設定する必要があるため、Playストアのほとんどのアプリはデバッグ不可ではないことに注意してください。

68
Lam Vinh

ここでの答えのほとんどは、必要以上に複雑です。アプリのデータベースを携帯電話からコンピューターにコピーする場合は、次のコマンドが必要です。

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

上記のコマンドで入力する必要があるのは、アプリのパッケージ名、データベースの名前、およびオプションでデータベースをコピーする場所です。

この特定のコマンドは、コンピューターに接続されているデバイスが1つしかない場合にのみ機能することに注意してください。 -dパラメーターは、接続されている唯一のデバイスがターゲットとなることを意味します。ただし、代わりに使用できる他のパラメーターがあります。

  • -eは、実行中の唯一のエミュレーターをターゲットにします
  • -s <serialnumber>は、特定のシリアル番号を持つデバイスをターゲットにします。

53
Xaver Kapeller

Android St​​udio 3.0以降のバージョンを使用すると、アプリケーションが非ルートデバイスでデバッグモードで実行されている場合、データベース(共有設定、キャッシュディレクトリなど)をプルできます。

Android studioを使用してデータベースをプルするには、次の手順に従います。

  1. クリック表示>ツールウィンドウ>デバイスファイルエクスプローラー
  2. / data/data/[パッケージ名]ノードを展開します。

Steps followed in Android Studio 3.0

35
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

Ubuntuの場合(だけでなく?):

Sergeis Answer を参照してください。ただし、opensslの代わりにzlib-flateを使用します。

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

そうしないと、opensslはおそらく以下をスローします。

openssl:Error: 'zlib'は無効なコマンドです。

opensslはUbuntuのzlibサポートでコンパイルされていないため

5
Murmel

または、ライブラリ ltra Debugger を使用できます。データベースをファイルとしてダウンロードしたり、ブラウザで直接値を編集したりできます。ルートは不要で、非常に使いやすいです。

1
BArtWell

デバイスからsqliteファイルを簡単に抽出できます(ルートは必要ありません)

  1. SDKフォルダーに移動
  2. cd platform-tools
  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
yubaraj poudel

以来、私にとって本当に効果的なものはありません。他の回答を組み合わせて、小さなウィンドウBATCHスクリプトを作成します。それが誰かを助けることを願っています。単純な使用法:backupDatabase <PackageName> <ApplicationName> [TargetDirectory]。 Sergeiのバックアップ方式と 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

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

Platform-toolsフォルダーにsqliteファイルをコピーします。

1
Yogesh Suthar

アプリデータベースを内部ストレージ(adbを搭載したPCではなく)に「保存」および「復元」する完全なソリューションを提供します。

データベースの保存と復元の2つの方法を実行しました。 MainActivityのonCreate()の最後にこれらのメソッドを使用します(データベースを保存または復元する場合は、どちらかを使用します)。

データベースを内部ストレージに保存します。

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
Digital Cubes

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();
        } 
    } 
} 
0
Rodolfo Abarca

Lam Vinhからの回答に基づいて、ここに私の第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
0
chutcher

ルート化されたデバイスでは、次のことができます。

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

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がプロファイルに追加されていることを確認してください。

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

はい、Androidアプリが、誰でもアクセスできるデータベースのファイルコピーを作成する場合。

Androidはアプリのプライベートデータを保護するため、他のアプリからは見えない/アクセスできません。データベースはプライベートデータです。もちろん、アプリはデータベースファイルを読み取ることができるため、公開されているいくつかのファイルにファイルコピーを実行できます。

0
k3b

物事が自動化されている場合は常に優れています。だからこそ、ADBを使用してデバイスからdbファイルをコピーするための単純なpython scriptを書いたのです。頻繁に行う場合、開発時間を大幅に節約できます。

debuggable appsがデバイスである場合のみ動作しますルート化されていません。

ここに要旨へのリンクがあります。

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