Android - ดึงอุปกรณ์ Android ฐานข้อมูล SQlite


103

ฉันได้ดูทุกที่แล้วและไม่พบคำตอบที่แท้จริงหรือคำแนะนำเกี่ยวกับวิธีการทำเช่นนี้ถ้าเป็นไปได้

เป็นไปได้ไหมที่จะดึงฐานข้อมูลของอุปกรณ์ Android โดยไม่ต้องรูทเครื่อง? ฉันเพียงแค่ต้องดึงข้อมูลนั้นด้วยวิธีใดก็ได้เพื่อรวบรวมไว้ในพีซีของฉันดังนั้นฉันจะดำเนินการได้อย่างไร ฉันต้องตั้งโปรแกรมแอปใหม่หรือวิธีใดก็ตามที่พวกคุณรู้จัก แต่จำไว้ว่าโดยไม่ต้องรูทอุปกรณ์ ขอบคุณ


นี่คือโซลูชันที่ใช้งานได้: stackoverflow.com/a/29257875/291427
kmalmur


1
stackoverflow.com/questions/13006315ดึงฐานข้อมูลโดยไม่ต้องรูท
Naveen Prince P

คำตอบ:


79

วิธีทั่วไปในการบรรลุสิ่งที่คุณต้องการคือใช้คำสั่งดึง ADB

อีกวิธีหนึ่งที่ฉันชอบในกรณีส่วนใหญ่คือการคัดลอกฐานข้อมูลด้วยรหัสไปยังการ์ด 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 ในไฟล์ Manifest ของคุณเช่นด้านล่าง

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

1
ฉันจะใช้สิ่งนี้บนแท็บ samsung galaxy ที่ไม่มีการ์ด SD แล้วฉันจะทำอย่างไรที่นั่น
DeX03

และฉันต้องใช้ double //?
DeX03

ใช่นี่เป็นเพราะ / เป็นอักขระสตริงพิเศษ // ใน "//" ของคุณจะส่งผลให้ /
KarlKarlsom

4
แทนที่จะสร้างเส้นทางฐานข้อมูล SQLiteDatabase มีgetPathวิธีการ
จะ

คำตอบที่ยอดเยี่ยม ฉลาดมากมีประโยชน์และเรียบง่าย
Gundu Bandgar

179

หากอุปกรณ์ของคุณใช้ Android v4 ขึ้นไปคุณสามารถดึงข้อมูลแอพรวมถึงฐานข้อมูลได้โดยไม่ต้องรูทโดยใช้adb backupคำสั่งจากนั้นแตกไฟล์สำรองและเข้าถึงฐานข้อมูล 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 -

หากข้างต้นลงเอยด้วย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

2
สำหรับผู้ใช้ Windows ที่ไม่สามารถใช้คำสั่ง unpack ได้คุณสามารถใช้ Java Application "Android Backup Extractor" ( sourceforge.net/projects/adbextractor ) โปรดดูที่forum.xda-developers.com/showthread.php?t=2011811สำหรับคำสั่งในการแตกไฟล์. ab
lalitm

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 -ก็ตามหลังจากที่มันแสดงให้เห็น17+0 records in17+0 records out17 bytes transferred in 0.000064 secsว่าไม่มีหลักฐานว่ามีการทำอะไรกับโฟลเดอร์ เนื่องจากเป็นเพียง 17 ไบต์ฉันจึงถือว่าคำสั่งนั้นล้มเหลว ฉันคิดว่ามันแย่adb pullที่ฐานข้อมูลจากแอป debug ไม่ได้ !!
ใครสักคน

12
เคล็ดลับสำหรับมืออาชีพ: ข้อมูลสำรองนี้จะไม่ทำงานหากรายการของแอปแสดงandroid:allowBackup="false"
ใครบางคนใน

9
ฉันopensslบน Mac OS X ไม่สนับสนุนคำสั่งอย่างใดอย่างหนึ่งเพื่อให้ฉันติดตั้งใหม่เป็นหนึ่งเดียวกับเบียร์:zlib brew reinstall opensslสิ่งนี้จะไม่แทนที่ระบบของคุณ openssl ดังนั้นฉันจึงแก้ไขคำสั่ง PATH สำหรับเซสชันปัจจุบันเท่านั้น: export PATH=/usr/local/opt/openssl/bin:$PATHหลังจากนั้นสามารถดำเนินการคำสั่งจากคำตอบนี้ได้สำเร็จ
Aleks N.

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 store ไม่สามารถดีบักได้เนื่องจากต้องตั้งค่าแฟล็กที่แก้ปัญหาได้ในไฟล์ Manifest


8
หลังจากที่ฉันแทนที่package.nameด้วยแพ็คเกจของแอปข้อผิดพลาดจะถูกส่งกลับ:run-as: Package 'com.my.app' is unknown
ใครบางคนใน

3
ดูเหมือนว่าจะใช้ไม่ได้กับโทรศัพท์ทุกรุ่น ใช้งานได้กับ Nexus 4 ไม่ทำงานกับ SGS4 เช่น
Roman Minenok

2
ไฟล์ db บันทึกอยู่ที่ไหน
VojtěchPešek

3
สิ่งนี้เคยใช้ได้ผลสำหรับฉัน แต่ดูเหมือนว่าฉันจะใช้งานกับ Nexus 7 ที่อัปเดตเป็น Android 5 ไม่ได้มีใครยืนยันได้ไหมว่าสิ่งนี้ใช้ได้กับ Android 5
treesAreEverywhere

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 ดึง 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

สิ่งที่คุณต้องกรอกในคำสั่งด้านบนคือชื่อแพ็กเกจของแอปของคุณสิ่งที่เรียกว่าฐานข้อมูลและเลือกได้ว่าต้องการคัดลอกฐานข้อมูลอะไร / ที่ไหน

โปรดทราบว่าคำสั่งเฉพาะนี้จะใช้ได้ก็ต่อเมื่อคุณมีอุปกรณ์เพียงเครื่องเดียวที่เชื่อมต่อกับคอมพิวเตอร์ของคุณ -dพารามิเตอร์หมายความว่าอุปกรณ์ที่เชื่อมต่อจะมีการกำหนดเป้าหมาย แต่มีพารามิเตอร์อื่น ๆ ที่คุณสามารถใช้แทนได้:

  • -e จะกำหนดเป้าหมายไปที่โปรแกรมจำลองที่ทำงานอยู่เท่านั้น
  • -s <serialnumber> จะกำหนดเป้าหมายอุปกรณ์ด้วยหมายเลขซีเรียลเฉพาะ


ฉันจะเปิดไฟล์นี้ได้อย่างไร?
Jehad

@ เจฮัด: ฉันมีปัญหาเดียวกัน ฉันพบวิธีนี้และได้ผลสำหรับฉัน ติดตั้ง SSHDroid บนโทรศัพท์ของคุณ adb -d shell "run-as your.package.name cat databases/database_name.db > /mnt/sdcard/database_name.db"เพื่อSSHDroidเริ่ม FileZilla และเชื่อมต่อกับโทรศัพท์ของคุณผ่านโปรโตคอล SFTP ตั้งค่า / mnt / sdcard เป็นรีโมตไดเร็กทอรีเริ่มต้น
ZoltánSüle

คำตอบที่ง่ายที่สุดเมื่อคุณต้องการรับฐานข้อมูลของแอปของคุณเอง การเพิ่มสองรายการ: 1) หากคุณไม่แน่ใจในชื่อฐานข้อมูลของคุณคุณสามารถใช้คำสั่ง ls เพื่อแสดงรายการไฟล์ในโฟลเดอร์ฐานข้อมูล ( adb -d shell "run-as your.package.name ls databases") และ 2) คุณอาจต้องการรับไฟล์อื่น ๆ ที่เกี่ยวข้องพร้อมกับฐานข้อมูลใน กรณีของฉันการแยกไฟล์ -smh และ -wal เป็นวิธีเดียวที่จะทำให้DB Browser สำหรับ SQLiteเปิดฐานข้อมูล
Ronan

สิ่งนี้จะใช้ได้เฉพาะในกรณีที่แอปสามารถแก้ไขข้อบกพร่องได้
dgw

36

การใช้ Android Studio 3.0 หรือเวอร์ชันที่ใหม่กว่าเป็นไปได้ที่จะดึงฐานข้อมูล (รวมถึงค่ากำหนดที่ใช้ร่วมกันไดเรกทอรีแคชและอื่น ๆ ) หากแอปพลิเคชันทำงานในโหมดดีบักบนอุปกรณ์ที่ไม่ได้รูท

ในการดึงฐานข้อมูลโดยใช้ android studio ให้ทำตามขั้นตอนเหล่านี้

  1. คลิกดู > เครื่องมือของ Windows > อุปกรณ์ File Explorer
  2. ขยายโหนด / data / data / [package-name]

ตามขั้นตอนใน Android Studio 3.0


ขอบคุณ. ดาวน์โหลดไฟล์จากโปรแกรมจำลองในขณะที่ไม่สามารถรับได้จาก Galaxy S4 ที่ยังไม่ได้รูท
CoolMind

คุณสามารถดึงฐานข้อมูลจากแอปใดก็ได้หรือเพียงแค่แอปของคุณเอง
live-love

แอพใด ๆ แต่เงื่อนไขเบื้องต้นคือแอพจะต้องดีบัก
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แต่แทนที่จะใช้ openssl ให้ใช้ zlib-flate:

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

มิฉะนั้น openssl อาจจะโยน:

openssl: ข้อผิดพลาด: 'zlib' เป็นคำสั่งที่ไม่ถูกต้อง

เนื่องจาก openssl ไม่ได้รวบรวมด้วยการรองรับ zlib ใน Ubuntu


1

ตั้งแต่นั้นมาไม่มีอะไรเหมาะกับฉันเลย ฉันสร้างสคริปต์ BATCH ของหน้าต่างเล็ก ๆ น้อย ๆ ตามคำตอบอื่น ๆ รวมกัน หวังว่ามันจะช่วยใครสักคน เพียงแค่ใช้: backupDatabase <PackageName> <ApplicationName> [TargetDirectory] มันใช้วิธีการสำรองข้อมูลและ Sergei ของAndroid สำรองดูด

@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. แพลตฟอร์มซีดีเครื่องมือ
  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

หากคุณพยายามทำบน 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();
        } 
    } 
} 

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 ใช่มันจะดึงฐานข้อมูลหากคอมไพล์สำหรับการดีบักมิฉะนั้นคุณสามารถดึงฐานข้อมูลของแอพใดก็ได้ และจะเป็นปัญหาด้านความปลอดภัยที่ร้ายแรงของแอพ :)
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 นี่คือไฟล์แบตช์ง่ายๆที่เหมาะกับฉันใน Nexus 7 รุ่นที่ 1 ของฉันมันแจ้งให้ผู้ใช้ป้อนชื่อแพ็กเกจจากนั้นตามด้วยชื่อฐานข้อมูล (โดยไม่มีนามสกุล. 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นี่คือสคริปต์ทับทิมที่จะบันทึกเนื้อหาแอปของคุณไปยังเดสก์ท็อป ฉันคิดว่าสิ่งนี้จะใช้ได้กับ 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)

ฉันได้ทำสองวิธีวิธีหนึ่งเพื่อบันทึกและวิธีอื่น ๆ เพื่อกู้คืนฐานข้อมูล ใช้วิธีการเหล่านี้ในตอนท้ายของ onCreate () ใน MainActivity (อย่างใดอย่างหนึ่งถ้าคุณต้องการประหยัดหรือกู้คืนฐานข้อมูล)

บันทึกฐานข้อมูลลงในที่จัดเก็บข้อมูลภายใน:

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

จะดีกว่าเสมอถ้าสิ่งต่าง ๆ เป็นไปโดยอัตโนมัตินั่นเป็นเหตุผลที่ฉันเขียนสคริปต์ pythonอย่างง่ายสำหรับคัดลอกไฟล์ db จากอุปกรณ์โดยใช้ ADB ช่วยประหยัดเวลาในการพัฒนาได้มากหากคุณทำบ่อยๆ

ใช้งานได้เฉพาะกับแอปที่แก้ไขข้อบกพร่องได้หากอุปกรณ์ไม่ได้รูท

นี่คือลิงค์ไปยังส่วนสำคัญ

เรียกใช้เป็น: 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> สำรวจไฟล์

ค้นหาไฟล์ db ของคุณจากชื่อแพ็คเกจของคุณ

จากนั้นคลิกที่ดึงไฟล์จากอุปกรณ์ (อุปกรณ์ที่รูทเท่านั้น)


3
สิ่งนี้สามารถทำได้ แต่บนอุปกรณ์ที่รูทซึ่งเป็นประเด็นของคำถามของฉันจะทำอย่างไรบนอุปกรณ์ที่ไม่ได้รูท
DeX03

1
สิ่งนี้ใช้ไม่ได้กับอุปกรณ์ที่ไม่ได้รูท คำตอบของคุณควรระบุว่า
tony9099
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.