ดึงฐานข้อมูลหรือไฟล์อื่น ๆ จาก Internal Storage โดยใช้ run-as


113

บนอุปกรณ์ Android ที่ไม่ได้รูทฉันสามารถไปที่โฟลเดอร์ข้อมูลที่มีฐานข้อมูลโดยใช้run-asคำสั่งกับชื่อแพ็กเกจของฉัน ประเภทไฟล์ส่วนใหญ่ฉันแค่ดูเนื้อหา แต่ด้วยฐานข้อมูลฉันต้องการดึงออกจากอุปกรณ์ Android

มีคำสั่งdownload copyหรือmoveคำสั่งจากส่วนนี้ของ adb shell หรือไม่? ฉันต้องการดาวน์โหลดไฟล์ฐานข้อมูลและดูเนื้อหาโดยใช้เบราว์เซอร์ฐานข้อมูล

คำตอบหนึ่งที่นี่เกี่ยวข้องกับการเปลี่ยนแพ็คเกจแอปพลิเคชันทั้งหมดให้เป็นไฟล์เก็บถาวรที่บีบอัด แต่ไม่มีคำตอบเพิ่มเติมเกี่ยวกับวิธีการแยกไฟล์เก็บถาวรนั้นเมื่อเสร็จสิ้นและย้ายไปที่เครื่องทำให้ฉันต้องหลบเลี่ยงเมื่ออาจมีวิธีแก้ปัญหาที่ตรงกว่าให้เริ่มต้นด้วย



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

คำตอบ:


230

ด้วยการออกแบบuserโครงสร้างของ Android (นั่นคือสิ่งที่คุณมีในโทรศัพท์ของคุณจนกว่าคุณจะปลดล็อกโปรแกรมโหลดบูตและแฟลชโทรศัพท์ด้วยuserdebugหรือengซอฟต์แวร์) จำกัด การเข้าถึงที่เก็บข้อมูลภายใน - ทุกแอปสามารถเข้าถึงไฟล์ของตัวเองได้เท่านั้น โชคดีสำหรับนักพัฒนาซอฟต์แวร์ที่ไม่เต็มใจที่จะรูทโทรศัพท์ของพวกเขา Google มีวิธีการเข้าถึงInternal Storageของแพ็คเกจเวอร์ชันdebuggableโดยใช้run-asคำสั่ง

ในการดาวน์โหลด/data/data/debuggable.app.package.name/databases/fileจากอุปกรณ์ Android 5.1+ ให้รันคำสั่งต่อไปนี้:

adb exec-out run-as debuggable.app.package.name cat databases/file > file

ในการดาวน์โหลดไฟล์หลายไฟล์ในโฟลเดอร์ภายใต้/data/data/debuggable.app.package.name/พร้อมtarกันให้ใช้:

adb exec-out run-as debuggable.app.package.name tar c databases/ > databases.tar
adb exec-out run-as debuggable.app.package.name tar c shared_prefs/ > shared_prefs.tar

8
หรือเพียงแค่ใช้run-asเพื่อคัดลอกไฟล์ไปยังจุดที่จัดเก็บข้อมูลภายนอกแล้วดึงไฟล์ฐานข้อมูลจากที่นั่นแทนที่จะไปยุ่งกับสิทธิ์ของไฟล์
CommonsWare

5
run-as ไม่ได้รับอนุญาตให้เขียนลงใน sdcard - มีสิ่งใหม่ที่เพิ่มเข้ามาพร้อมกับการอัปเดตล่าสุด ... :(
slott

4
เมื่อฉันเรียกใช้ adb shell "run-as package.name chmod 666 /data/data/package.name/databases/file" adb ทำให้ฉันเกิดข้อผิดพลาด -> run-as: exec ล้มเหลวสำหรับข้อผิดพลาด chmod666: ปฏิเสธการอนุญาต ฉันใช้ Nexus 7 โดยไม่ต้องรูท
Shudy

2
ไม่สามารถเขียนเข้าถึงการ์ด sd ภายนอกได้อีกต่อไปด้วย adb
slott

3
หากคุณพบว่าคุณได้รับไฟล์เปล่าหรือเกือบว่างเปล่าคุณอาจพบว่าไฟล์นั้นเป็นเพียงข้อผิดพลาดจากคอนโซลที่ถูกเปลี่ยนเส้นทางไปยังไฟล์ที่คุณสร้างขึ้น ปัญหาที่พบบ่อยคือคุณกำลังพยายามคัดลอกฐานข้อมูลจากตัวแปรรุ่นของแอปของคุณ คุณสามารถคัดลอกฐานข้อมูลได้จากตัวแปรการแก้ไขข้อบกพร่องของแอปของคุณเท่านั้น ในกรณีนี้ให้ติดตั้งตัวแปรดีบักแล้วลองคำสั่งอีกครั้ง หวังว่านี่จะช่วยใครบางคนได้
Aonghus Shortt

73

คำตอบที่ยอมรับใช้ไม่ได้อีกต่อไปสำหรับฉัน (ถูกบล็อกโดย Android?)

ดังนั้นฉันจึงทำสิ่งนี้แทน:

> adb shell
shell $ run-as com.example.package
shell $ chmod 666 databases/file
shell $ exit                                               ## exit out of 'run-as'
shell $ cp /data/data/package.name/databases/file /sdcard/
shell $ run-as com.example.package
shell $ chmod 600 databases/file
> adb pull /sdcard/file .

3
นี่ควรเป็นคำตอบใหม่ที่ถูกต้องหรือ @Alex P. คุณควรเพิ่มคำตอบนี้สำหรับ Android เวอร์ชันใหม่กว่า นอกจากนี้ในกรณีของฉันฉันต้องใช้ 777 และใช้กับไดเร็กทอรีฐานข้อมูลก่อน / เช่นกันก่อนที่ฉันจะเข้าถึงไฟล์ db
muetzenflo

1
อุปกรณ์ของฉันได้รับการรูท แต่ฉันพบว่าฉันยังต้องเรียกใช้suเพื่อให้run-asคำสั่งทำงาน
ThomasW

จะเกิดอะไรขึ้นถ้าคุณไม่มีการ์ด SD?
Gyum Fox

1
หากคุณไม่มีการ์ด SD ก็ยังมีไดเร็กทอรี "sdcard" อยู่ดี
treesAreEverywhere

1
ที่ดี !. มันได้ผลสำหรับฉันด้วย เราสามารถสร้างไฟล์แบทช์ / เชลล์ได้หรือไม่? เพียงแค่ส่งชื่อไฟล์ db เป็นพารามิเตอร์และเรามีไฟล์ db
Qadir Hussain

22

หากใครที่กำลังมองหาการดึงฐานข้อมูลจากdebug applicationอาจใช้ขั้นตอนด้านล่าง:

  1. ค้นหาและเปิดไฟล์ explorer ของอุปกรณ์

ค้นหาและเปิดไฟล์ explorer ของอุปกรณ์

  1. เลือกโทรศัพท์มือถือของคุณจากนั้นเรียกดูdata/dataไดเรกทอรี

ไปที่ไดเร็กทอรี data / data

  1. ค้นหาแพ็คเกจแอปพลิเคชันของคุณแล้วไปที่โฟลเดอร์ฐานข้อมูล คุณสามารถดูฐานข้อมูลที่นั่นและเมื่อคลิกขวาคุณจะได้รับตัวเลือกให้บันทึกลงในไดรฟ์ของคุณ

ใส่คำอธิบายภาพที่นี่


1
ว้าวง่ายและปลอดภัยกว่ามากเมื่อเทียบกับการใช้ adb-shell
user1708860

9

ฉันได้เผยแพร่เชลล์สคริปต์อย่างง่ายสำหรับการทิ้งฐานข้อมูล:

https://github.com/Pixplicity/humpty-dumpty-android

ดำเนินการสองวิธีที่แตกต่างกันที่อธิบายไว้ที่นี่:

  1. ขั้นแรกจะพยายามทำให้ไฟล์สามารถเข้าถึงได้สำหรับผู้ใช้รายอื่นและพยายามดึงไฟล์จากอุปกรณ์
  2. หากล้มเหลวระบบจะสตรีมเนื้อหาของไฟล์ผ่านเทอร์มินัลไปยังเครื่องภายใน ดำเนินการเคล็ดลับเพิ่มเติมเพื่อลบ\rอักขระที่อุปกรณ์บางอย่างส่งออกไปยังเชลล์

จากที่นี่คุณสามารถใช้แอปพลิเคชัน CLI หรือ GUI SQLite ที่หลากหลายเช่นsqlite3หรือsqlitebrowserเพื่อเรียกดูเนื้อหาของฐานข้อมูล


สคริปต์นี้มีไว้สำหรับแอปพลิเคชันที่ดีบักได้แล้วถ้าแอปไม่สามารถดีบั๊กได้ล่ะ?
blueware

ตัวเลือกเดียวของคุณน่าจะใช้เครื่องมือสำรองหากแอปที่เป็นปัญหาเปิดเผยข้อมูลนั้นเป็นส่วนหนึ่งของข้อมูลสำรอง นอกเหนือจากนั้นฉันเกรงว่าจะต้องมีการอนุญาตที่สูงขึ้น
Paul Lammertsma

7

ฉันไม่สามารถหาอย่างอื่นมาทำงานแทนฉันได้ แต่สิ่งนี้:

adb shell
run-as package.name
cat /databases/databaseFileName.db > /sdcard/copiedDatabaseFileName.db
exit
exit
adb pull /sdcard/copiedDatabaseFileName.db /file/location/on/computer/

ทางออกแรกคือออกจาก run-as ทางออกที่สองคือออกจาก adb shell เพื่อทำการดึง


3

สำหรับเวอร์ชันดีบักของแอปนั้นสะดวกมากที่จะใช้คำสั่งadb exec-out run-as xxx.yyy.zzz cat somefile > somefileเพื่อแตกไฟล์เดียว แต่คุณต้องทำหลายครั้งสำหรับไฟล์หลาย ๆ ไฟล์ นี่คือสคริปต์ง่ายๆที่ฉันใช้เพื่อแยกไดเร็กทอรี

#!/bin/bash
P=
F=
D=

function usage()
{
    echo "$(basename $0) [-f file] [-d directory] -p package"
    exit 1
}

while getopts ":p:f:d:" opt
do
    case $opt in
        p)
            P=$OPTARG
            echo package is $OPTARG
            ;;
        f)
            F=$OPTARG
            echo file is $OPTARG
            ;;
        d)
            D=$OPTARG
            echo directory is $OPTARG
            ;;
        \?)
            echo Unknown option -$OPTARG
            usage
            ;;
        \:)
            echo Required argument not found -$OPTARG
            usage
            ;;
    esac
done

[ x$P == x ] && {
    echo "package can not be empty"
    usage
    exit 1
}

[[ x$F == x  &&  x$D == x ]] && {
    echo "file or directory can not be empty"
    usage
    exit 1
}

function file_type()
{
    # use printf to avoid carriage return
    __t=$(adb shell run-as $P "sh -c \"[ -f $1 ] && printf f || printf d\"")
    echo $__t
}

function list_and_pull()
{
    t=$(file_type $1)
    if [ $t == d ]; then
        for f in $(adb shell run-as $P ls $1)
        do
            # the carriage return output from adb shell should
            # be removed
            mkdir -p $(echo -e $1 |sed $'s/\r//')
            list_and_pull $(echo -e $1/$f |sed $'s/\r//')
        done
    else
        echo pull file $1
        [ ! -e $(dirname $1) ] && mkdir -p $(dirname $1)
        $(adb exec-out run-as $P cat $1 > $1)
    fi
}

[ ! -z $D ] && list_and_pull $D
[ ! -z $F ] && list_and_pull $F

หวังว่าคงจะเป็นประโยชน์ สคริปต์นี้ยังมีบริการที่สำคัญ

การใช้งานโดยทั่วไปคือ

$ ./exec_out.sh -p com.example.myapplication -d databases

จากนั้นจะแตกไฟล์ทั้งหมดภายใต้ไดเร็กทอรีฐานข้อมูลแอพของคุณซึ่งก็คือ/data/data/com.example.myapplication/databasesลงในไดเร็กทอรีปัจจุบัน


1
แม้แต่ไฟล์หลายไฟล์ก็ยังเป็นเพียงคำสั่งเดียว ตรวจสอบการอัปเดตstackoverflow.com/a/18472135/1778421หากคุณต้องการคุณสามารถเพิ่ม
Alex P.

2

วิธีที่ง่ายกว่ามากในการดาวน์โหลดไฟล์ลงในคอมพิวเตอร์ของคุณ:

ในการรันเชลล์พีซีของคุณ:

adb -d shell 'run-as <package_name> cat /data/data/<package_name>/databases/<db_name>' > <local_file_name>

ค่อนข้างใกล้ แต่สิ่งนี้ดึงฐานข้อมูลที่ผิดรูปแบบออกมาสำหรับฉัน
Nae

1
#!/bin/bash
#export for adb
export PATH=$PATH:/Users/userMe/Library/Android/sdk/platform-tools
export PATH=$PATH:/Users/userMe/Library/Android/sdk/tools

adb -d shell 'run-as com.android.app  cp /data/data/com.android.app/files/db.realm /sdcard'
adb pull sdcard/db.realm /Users/userMe/Desktop/db

คุณสามารถใช้สคริปต์นี้เพื่อรับฐานข้อมูล Realm


0

หากมีคนกำลังมองหาคำตอบอื่นที่สามารถใช้ในการดึงข้อมูลได้Databaseเช่นกันให้Shared Preferencesทำตามขั้นตอนนี้:

ในbuild.gradleไฟล์แอพของคุณแอดไลน์

debugCompile 'com.amitshekhar.android:debug-db:1.0.0'

ตอนนี้เมื่อคุณเรียกใช้แอปในnon-releaseโหมดแอปของคุณจะเปิดพอร์ต 8080 จากอุปกรณ์ของคุณโดยอัตโนมัติIP addressตรวจสอบให้แน่ใจว่าอุปกรณ์ของคุณเชื่อมต่อผ่านwifiและคุณlaptopกำลังแชร์เครือข่ายเดียวกัน ตอนนี้เพียงเข้าไปที่ url

http: // your_mobile_device_ip: 8080 /

เพื่อดูข้อมูลทั้งหมดของฐานข้อมูลพร้อมกับการตั้งค่าที่ใช้ร่วมกัน


0

นี่คือวิธีแก้ปัญหาที่ใช้ได้กับอุปกรณ์ที่ใช้ Android 5.1 ตัวอย่างต่อไปนี้ใช้สำหรับ Windows

คุณต้องมีsed (หรือ sed.exe บน windows เช่นจาก cygwin) (ใน Unix มันจะอยู่ที่นั่น;)) ในการลบอักขระ '\ r' ที่ไม่ดีอย่างน้อยก็บน windows

ตอนนี้เพียงแค่เรียกใช้คำสั่งต่อไปนี้:

adb exec-out "run-as com.yourcompany.yourapp /data/data/com.yourcompany.yourapp/databases/YourDatabaseName" | c:\cygwin\bin\sed.exe 's/\x0D\x0A/\x0A/'>YourDatabaseName.db

คำสั่ง sed จะตัดอักขระต่อท้าย / r ออก

แน่นอนว่าคุณควรแทนที่ "com.yourcompany.yourapp" ด้วยชื่อแพ็กเกจของแอปและ "YourDatabaseName" ด้วยชื่อของฐานข้อมูลในแอป


0

ไฟล์ฐานข้อมูลเป็นemtpyadb run-asเมื่อใช้ สามารถแก้ไขได้โดยการเรียก close () บนอินสแตนซ์ RoomDatabase โทรปิด () เพื่อให้ SQLite เขียนบันทึกลงในดิสก์ ฉันได้สร้างปุ่มนี้เพื่อปิดการเชื่อมต่อฐานข้อมูลตามคำขอ:

ผ่าน GIPHY

นี่คือวิธีการเรียกปิดอินสแตนซ์ RoomDatabase

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