私はいたるところを見てきましたが、本当の正確な答えや、可能な場合はこれを行う方法に関するチュートリアルを見つけることができません。
Androidデバイスのデータベースをルート化せずに何らかの方法でプルすることは可能ですか?私のPCでデータを収集するには、何らかの方法でそのデータを抽出する必要がありますが、どうすればこれを実行できますか?アプリや、皆さんが知っている方法を再プログラムする必要がありますが、デバイスをルート化せずに覚えておいてください。ありがとう
目的を達成する一般的な方法は、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" />
デバイスが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/
フォルダーです。
詳細については、 元のブログ投稿 を確認してください。
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ストアのほとんどのアプリはデバッグ不可ではないことに注意してください。
ここでの答えのほとんどは、必要以上に複雑です。アプリのデータベースを携帯電話からコンピューターにコピーする場合は、次のコマンドが必要です。
adb -d Shell "run-as your.package.name cat databases/database.name" > target.sqlite
上記のコマンドで入力する必要があるのは、アプリのパッケージ名、データベースの名前、およびオプションでデータベースをコピーする場所です。
この特定のコマンドは、コンピューターに接続されているデバイスが1つしかない場合にのみ機能することに注意してください。 -d
パラメーターは、接続されている唯一のデバイスがターゲットとなることを意味します。ただし、代わりに使用できる他のパラメーターがあります。
-e
は、実行中の唯一のエミュレーターをターゲットにします-s <serialnumber>
は、特定のシリアル番号を持つデバイスをターゲットにします。 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:Error: 'zlib'は無効なコマンドです。
opensslはUbuntuのzlibサポートでコンパイルされていないため
または、ライブラリ ltra Debugger を使用できます。データベースをファイルとしてダウンロードしたり、ブラウザで直接値を編集したりできます。ルートは不要で、非常に使いやすいです。
デバイスからsqliteファイルを簡単に抽出できます(ルートは必要ありません)
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"
以来、私にとって本当に効果的なものはありません。他の回答を組み合わせて、小さなウィンドウ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
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ファイルをコピーします。
アプリデータベースを内部ストレージ(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");
}
}
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();
}
}
}
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
ルート化されたデバイスでは、次のことができます。
// 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 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がプロファイルに追加されていることを確認してください。
> is it possible to pull in any way a database of an Android device without having to root it?
はい、Androidアプリが、誰でもアクセスできるデータベースのファイルコピーを作成する場合。
Androidはアプリのプライベートデータを保護するため、他のアプリからは見えない/アクセスできません。データベースはプライベートデータです。もちろん、アプリはデータベースファイルを読み取ることができるため、公開されているいくつかのファイルにファイルコピーを実行できます。
物事が自動化されている場合は常に優れています。だからこそ、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")