Truy xuất cơ sở dữ liệu hoặc bất kỳ tệp nào khác từ Bộ nhớ trong bằng run-as


113

Trên một thiết bị không bắt nguồn từ Android, tôi có thể điều hướng đến thư mục chứa dữ liệu cơ sở dữ liệu bằng cách sử dụng run-aslệnh với tên gói của tôi. Hầu hết các loại tệp tôi đều hài lòng khi chỉ xem, nhưng với cơ sở dữ liệu, tôi muốn lấy nếu từ thiết bị Android.

Có lệnh download copyhoặc movelệnh nào từ phần này của adb shell không? Tôi muốn tải xuống tệp cơ sở dữ liệu và xem nội dung của nó bằng trình duyệt cơ sở dữ liệu.

Một câu trả lời ở đây liên quan đến việc chuyển toàn bộ gói ứng dụng thành một kho lưu trữ nén, nhưng không có câu trả lời nào khác về cách giải nén kho lưu trữ đó sau khi việc này được thực hiện và chuyển vào máy, khiến tôi rất bối rối khi có thể có một giải pháp trực tiếp hơn để bắt đầu.



stackoverflow.com/questions/13006315 Kéo cơ sở dữ liệu mà không cần thiết bị root
Naveen Prince P

Câu trả lời:


230

Theo thiết kế userxây dựng của Android (đó là những gì bạn có trên điện thoại của mình cho đến khi bạn mở khóa bộ nạp khởi động và flash điện thoại bằng userdebughoặc engphần mềm) hạn chế quyền truy cập vào Bộ nhớ trong - mọi ứng dụng chỉ có thể truy cập các tệp của chính ứng dụng đó. May mắn thay cho các nhà phát triển phần mềm không sẵn sàng root điện thoại của họ, Google cung cấp một cách để truy cập vào Bộ nhớ trong của các phiên bản có thể gỡ lỗi trong gói của họ bằng run-aslệnh.

Để tải xuống /data/data/debuggable.app.package.name/databases/filetừ thiết bị Android 5.1+, hãy chạy lệnh sau:

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

Để tải xuống nhiều tệp trong một thư mục trong /data/data/debuggable.app.package.name/cùng một lúc - hãy sử dụng 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
Hoặc, chỉ cần sử dụng run-asđể sao chép tệp vào một vị trí trên bộ nhớ ngoài và kéo tệp cơ sở dữ liệu từ đó, thay vì làm rối với quyền đối với tệp.
CommonsWare

5
Run-as không có quyền ghi vào sdcard - có một cái gì đó mới được thêm vào với bản cập nhật mới nhất ... :(
slott

4
Khi tôi chạy adb shell "run-as package.name chmod 666 /data/data/package.name/databases/file" adb end me error -> run-as: exec không thành công cho chmod666 Lỗi: Quyền bị từ chối. Tôi đang sử dụng Nexus 7 mà không cần root
Shudy

2
Quyền truy cập ghi vào thẻ sd bên ngoài không còn khả thi với adb.
slott

3
Nếu bạn nhận thấy rằng bạn đang nhận lại một tệp trống hoặc gần như trống, bạn có thể thấy rằng tệp đó chỉ là lỗi từ bảng điều khiển đã được chuyển hướng đến tệp này mà bạn đã tạo. Một vấn đề thường xuyên xảy ra ở đây là bạn đang cố gắng sao chép DB từ phiên bản Release của ứng dụng. Bạn chỉ có thể sao chép DB từ biến thể Gỡ lỗi của ứng dụng của mình . Nếu điều này xảy ra, chỉ cần cài đặt biến thể gỡ lỗi và thử lại lệnh. Hy vọng điều này sẽ giúp ai đó.
Aonghus Shortt

73

Câu trả lời được chấp nhận không còn hoạt động đối với tôi nữa (bị Android chặn?)

Vì vậy, thay vào đó tôi đã làm điều này:

> 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
Đây phải là câu trả lời chính xác mới HOẶC @Alex P. bạn nên thêm câu trả lời này cho các phiên bản Android mới hơn. Ngoài ra trong trường hợp của tôi, tôi phải sử dụng 777 và áp dụng nó vào thư mục cơ sở dữ liệu trước / cũng như trước khi tôi có thể truy cập tệp db.
muetzenflo

1
Thiết bị của tôi đã được root, nhưng tôi thấy mình vẫn cần chạy suđể run-aslệnh hoạt động.
ThomasW

Nếu bạn không có thẻ SD thì sao?
Gyum Fox,

1
nếu bạn không có thẻ SD, vẫn có thư mục "sdcard".
treeAreEverywhere

1
Tuyệt quá!. nó cũng làm việc cho tôi. Chúng ta có thể tạo một tệp batch / shell không? chỉ cần chuyển tên tệp db dưới dạng param và chúng ta có tệp db.
Qadir Hussain

22

Nếu bất kỳ ai đang tìm cách kéo cơ sở dữ liệu từ ứng dụng gỡ lỗi có thể sử dụng quy trình dưới đây:

  1. tìm kiếm và mở trình khám phá tệp thiết bị

tìm kiếm và mở trình khám phá tệp thiết bị

  1. Chọn thiết bị cầm tay của bạn và sau đó duyệt đến data/datathư mục

đi đến dữ liệu / thư mục dữ liệu

  1. Bây giờ, hãy tìm gói ứng dụng của bạn và chuyển đến thư mục cơ sở dữ liệu. Bạn có thể thấy cơ sở dữ liệu ở đó và khi nhấp chuột phải, bạn sẽ có tùy chọn để lưu dữ liệu này vào ổ đĩa của mình.

nhập mô tả hình ảnh ở đây


1
Wow, vì vậy dễ dàng hơn và an toàn hơn so với sử dụng adb shell-
user1708860

9

Tôi đã xuất bản một tập lệnh shell đơn giản để kết xuất cơ sở dữ liệu:

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

Nó thực hiện hai phương pháp riêng biệt được mô tả ở đây:

  1. Đầu tiên, nó cố gắng làm cho tệp có thể truy cập được đối với những người dùng khác và cố gắng lấy tệp khỏi thiết bị.
  2. Nếu không thành công, nó sẽ truyền nội dung của tệp qua thiết bị đầu cuối đến máy cục bộ. Nó thực hiện một thủ thuật bổ sung để loại bỏ các \rký tự mà một số thiết bị xuất ra shell.

Từ đây, bạn có thể sử dụng nhiều ứng dụng CLI hoặc GUI SQLite, chẳng hạn như sqlite3hoặc sqlitebrowser, để duyệt nội dung của cơ sở dữ liệu.


Tập lệnh này dành cho các ứng dụng có thể gỡ lỗi, nếu ứng dụng không thể gỡ lỗi thì sao?
blueware

Các tùy chọn duy nhất của bạn có thể là sử dụng các công cụ sao lưu, nếu ứng dụng được đề cập để lộ dữ liệu đó như một phần của bản sao lưu. Ngoài ra, tôi e rằng nó sẽ yêu cầu quyền cao hơn.
Paul Lammertsma

7

Tôi không thể nhận bất cứ điều gì khác để làm việc cho tôi ngoài điều này:

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

Lối thoát đầu tiên là thoát ra khỏi run-as, lối thoát thứ hai là thoát ra khỏi adb shell để thực hiện kéo.


3

Đối với phiên bản gỡ lỗi của ứng dụng, rất tiện lợi khi sử dụng lệnh adb exec-out run-as xxx.yyy.zzz cat somefile > somefileđể giải nén một tệp duy nhất. Nhưng bạn phải thực hiện nhiều lần cho nhiều tệp. Đây là một script đơn giản tôi sử dụng để giải nén thư mục.

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

Hy vọng nó sẽ hữu ích. Tập lệnh này cũng có sẵn tại ý chính .

Cách sử dụng điển hình là

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

sau đó nó sẽ trích xuất tất cả các tệp trong thư mục cơ sở dữ liệu ứng dụng của bạn /data/data/com.example.myapplication/databases, vào thư mục hiện tại.


1
ngay cả đối với nhiều tệp, nó vẫn chỉ là một lệnh duy nhất. kiểm tra các bản cập nhật stackoverflow.com/a/18472135/1778421 nếu bạn muốn bạn cũng có thể thêm đường ống khác ở phía máy chủ để giải nén các tập tin
Alex P.

2

Cách tiếp cận đơn giản hơn nhiều để tải tệp xuống máy tính cục bộ của bạn:

Trong PC shell của bạn chạy:

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

Khá gần nhưng điều này kéo ra một db dị dạng cho tôi.
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

Bạn có thể sử dụng tập lệnh này để tải cơ sở dữ liệu Realm.


0

Nếu ai đó đang tìm kiếm một câu trả lời khác có thể được sử dụng để truy xuất Databasecũng như Shared Preferencessau đó hãy làm theo bước sau:

Trong build.gradletệp ứng dụng của bạn, thêm dòng

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

bây giờ khi bạn chạy ứng dụng của mình ở non-releasechế độ thì ứng dụng của bạn sẽ tự động mở cổng 8080 từ thiết bị của bạn, IP addressđảm bảo rằng thiết bị của bạn được kết nối qua wifivà của bạn laptopđang chia sẻ cùng một mạng. Bây giờ chỉ cần truy cập url

http: // your_mobile_device_ip: 8080 /

để xem tất cả dữ liệu của cơ sở dữ liệu cùng với các tùy chọn được chia sẻ.


0

Đây là một giải pháp hoạt động trên thiết bị chạy Android 5.1. Ví dụ sau dành cho Windows.

Bạn cần sed (hoặc sed.exe trên windows, ví dụ như từ cygwin.) (Trên Unix, nó sẽ ở đó;)). Để xóa các ký tự '\ r' xấu, ít nhất là trên windows.

Bây giờ chỉ cần chạy lệnh sau:

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

Lệnh sed loại bỏ các ký tự dấu / r.

Tất nhiên bạn nên thay thế "com.yourcompany.yourapp" bằng tên gói của ứng dụng và "YourDatabaseName" bằng tên của cơ sở dữ liệu trong ứng dụng.


0

Tệp cơ sở dữ liệu là emtpy khi sử dụng adb run-as. Điều này có thể được giải quyết bằng cách gọi close () trên cá thể RoomDatabase. Gọi close () để SQLite ghi nhật ký vào đĩa. Tôi đã tạo nút này để đóng kết nối cơ sở dữ liệu theo yêu cầu:

qua GIPHY

Đây là cách gọi close trên cá thể RoomDatabase.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.