Android-SQliteデータベースのAndroidデバイスのプル


99

私は至る所を調べましたが、可能であれば、これを行う方法についての正確な答えやチュートリアルを見つけることができません。

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


:ここに実行可能なソリューションであるstackoverflow.com/a/29257875/291427
kmalmur


1
stackoverflow.com/questions/13006315応援せずにDBをプルする
Naveen Prince P

回答:


78

希望どおりの結果を得る一般的な方法は、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" />

1
まあ私はこれをSDカードを持たないサムスンのギャラクシータブで使用するつもりですので、そこでどうすればいいですか?
DeX03 2012

そして、私はダブル//を使用する必要がありますか?
DeX03

はい、これは/が特殊な文字列文字であるためです。// "//"内では/になります。
KarlKarlsom 2012

4
SQLiteDatabaseには、データベースパスを構築するのではなく、getPathメソッドがあります。
2014年

素晴らしい答え。とてもスマートで、便利でシンプル。
Gundu Bandgar 2017年

179

デバイスでAndroid v4以降を実行している場合は、コマンドを使用してroot なしでデータベースを含むアプリデータをプルしadb backup、バックアップファイルを抽出して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 -

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

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


9
zlibなしでzlibをコンパイルしていない人は、blog.shvetsov.com / 2013/02 /…で回答を確認して、Pythonでデータを抽出してください。
ingh.am 2013

2
unpackコマンドを使用できないWindowsユーザーの場合は、「Android Backup Extractor」Javaアプリケーション(sourceforge.net/projects/adbextractor)を使用できます。.abファイルを解凍するコマンドについては、forum.xda-developers.com / showthread.php?t = 2011811を参照してください。
lalitm 14

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 -後、HOWEVERで応答し17+0 records in17+0 records out17 bytes transferred in 0.000064 secsました。たった17バイトなので、コマンドも失敗したと思います。adb pullデバッグアプリからデータベースにアクセスできないのは悪いことだと思います。
誰かどこか

12
プロのヒント:アプリのマニフェストが表示されている場合、このバックアップは機能しませんandroid:allowBackup="false"
Someone Somewhere

9
opensslMac OS Xの私zlibもコマンドをサポートしていなかったため、brewを使用して再インストールしましたbrew reinstall openssl。これはあなたのシステムopensslを置き換えません。したがって、私は現在のセッションに対してのみPATHコマンドを変更しました。export PATH=/usr/local/opt/openssl/bin:$PATHその後、この回答からコマンドを正常に実行できました。
Aleks N. 2014

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フォルダーの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では機能しません。
Roman Minenok 2014

2
dbファイルはどこに保存されますか?
VojtěchPešek

3
以前はこれで機能していましたが、Android 5に更新されたNexus 7では機能しないようです。Android5で機能することを誰かが確認できますか?
treesAreEverywhere 2014

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

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

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

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


このファイルを開くにはどうすればよいですか?
Jehad

@ジェハド:私は同じ問題を抱えていました。私はこの方法を見つけ、それは私のために働きます。お使いの携帯電話にSSHDroidをインストールして adb -d shell "run-as your.package.name cat databases/database_name.db > /mnt/sdcard/database_name.db"SSHDroidFileZillaを起動し、SFTPプロトコルを介して携帯電話に接続します。/ mnt / sdcardをデフォルトのリモートディレクトリとして設定します。
ゾルタンスーレーパゴダ

自分のアプリのデータベースを取得したい場合の最も簡単な答え。2つの追加:1)データベース名がわからない場合は、lsコマンドを使用して、データベースフォルダー(adb -d shell "run-as your.package.name ls databases")内のファイルを一覧表示できます。2)他の関連ファイルをデータベースと共に取得する-smhファイルと-walファイルを抽出する私のケースは、SQLiteのDBブラウザでデータベースを開く唯一の方法でした
Ronan

36

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

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

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

Android Studio 3.0での手順


ありがとう。エミュレータからファイルをダウンロードしたが、ルート化されていないGalaxy S4からファイルを取得できない。
CoolMind 2017

データベースを任意のアプリからプルできますか、それとも自分のアプリだけからプルできますか?
live-love

前提条件がapp以外のアプリは、デバッグ可能である必要があります。
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/*"

5

Ubuntuの場合(だけではないですか?):

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

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

そうでなければopensslはおそらくスローします:

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

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


1

それ以来、私には何もうまくいきません。他の回答を組み合わせて、小さなウィンドウバッチスクリプトを作成します。それが誰かを助けることを願っています。単純な使用法: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

1

あなたはあなたのデバイスから簡単に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"

    For eg

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


1

あなたがアンドロイド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を使用することもできます。データベースをファイルとしてダウンロードしたり、ブラウザで直接値を編集したりできます。ルートは必要なく、非常に使いやすいです。


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フォルダーにコピーします。


これは、アプリがデバッグ用にコンパイルされている場合にのみ機能するようです。
David Berry、

@DavidBerryはい、デバッグ用にコンパイルされている場合はdbをプルします。それ以外の場合は、アプリのdbをプルすることができます。そして、それはアプリの深刻なセキュリティ問題になります。:)
Yogesh Suthar

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

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

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


0

ルート権限を取得されたデバイスでは、次のことができます。

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

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

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

アプリデータベースを(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

自動化されている場合は常に優れています。そのため、ADBを使用してデバイスからdbファイルをコピーするための簡単なpythonスクリプト作成しました。頻繁に実行すれば、開発時間を大幅に節約できます。

デバイスがルート化されていない場合、デバッグ可能なアプリでのみ機能します

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

次のように実行します。 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> File exploreを参照してください

パッケージ名からdbファイルを見つけます

次に、デバイスからファイルをプルするをクリックします(ルート化されたデバイスのみ)


3
これは実行できますが、私の質問のポイントであるルート化されたデバイスで、ルート化されていないデバイスでそれを実行する方法
DeX03

1
これは、ルート権限を取得していないデバイスでは機能しません。あなたの答えはそれを述べるべきです。
tony9099 2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.