Gỡ lỗi cơ sở dữ liệu sqlite trên thiết bị


98

Tôi hiện đang làm việc trên một ứng dụng WiFi cho Android. Tôi đang gặp sự cố khi cố gắng truy cập cơ sở dữ liệu trên thiết bị. Gỡ lỗi trong trình giả lập không hoạt động đối với tôi, vì không có hỗ trợ WiFi trong trình mô phỏng. Tôi đã thử kéo tệp cơ sở dữ liệu ra khỏi thiết bị bằng cách sử dụng

adb pull data/data/package-name/databases/database-name

Nhưng tôi gặp lỗi "Quyền bị từ chối.". Trong câu trả lời này, Android: Các tệp cơ sở dữ liệu được lưu trữ ở đâu? , Commonsware đã gợi ý để kéo tệp cơ sở dữ liệu bằng cách chạy ở chế độ gỡ lỗi. Nhưng nó cũng không hoạt động. Bất kỳ trợ giúp nào về cách gỡ lỗi cơ sở dữ liệu mà không cần root thiết bị sẽ được đánh giá cao.

Câu trả lời:


142

Tôi sẽ lặp lại chính mình từ một câu trả lời khác :

Bắt đầu từ API cấp 8 (Android 2.2), nếu bạn xây dựng ứng dụng dưới dạng có thể gỡ lỗi, bạn có thể sử dụng run-aslệnh shell để chạy một lệnh hoặc tệp thực thi với tư cách người dùng / ứng dụng cụ thể hoặc chỉ cần chuyển sang UIDứng dụng của bạn để bạn có thể truy cập dữ liệu của nó danh mục.

Vì vậy, nếu bạn muốn kéo cơ sở dữ liệu ứng dụng của mình từ thiết bị, bạn nên chạy bản dựng gỡ lỗi của ứng dụng, kết nối với adb shellvà chạy lệnh sau:

run-as com.yourpackage sh -c "cat ~/databases/db-file" > /sdcard/db-file.sqlite

Thao tác này sẽ sao chép của bạn db-filevào thư mục gốc của thẻ SD / bộ nhớ ngoài của bạn. Bây giờ bạn có thể dễ dàng lấy nó từ đó bằng cách sử dụng trình quản lý tệp adb pullhoặc bất kỳ thứ gì khác mà bạn thích. Lưu ý rằng với cách tiếp cận này, ứng dụng của bạn KHÔNG cần phải có WRITE_EXTERNAL_STORAGEquyền vì việc sao chép được thực hiện bởi người dùng shell, người luôn có thể ghi vào bộ nhớ ngoài.

Trên hệ thống Linux / Mac, có thể sao chép cơ sở dữ liệu trực tiếp vào máy tính của bạn bằng lệnh sau mà người ta có thể sử dụng mà không cần nhập adb shell:

adb shell 'run-as com.yourpackage sh -c "cat ~/databases/db-file"' > db-file.sqlite

Tuy nhiên, điều này sẽ không hoạt động chính xác trên Windows do chuyển đổi ký hiệu CR / LF. Sử dụng phương pháp cũ ở đó.


1
@MikeIsrael Chỉ trong trường hợp bạn không sử dụng SQLCipher trong ứng dụng của mình phải không? Nếu không, thì để kiểm tra sơ bộ xem cơ sở dữ liệu đã được tải xuống đúng cách hay chưa, hãy mở tệp DB trong trình xem (tốt nhất là trình xem hex) và kiểm tra xem nó có bắt đầu bằng SQLite format 3chuỗi hay không. Ngoài ra, hãy đảm bảo rằng bạn có một sqlitephiên bản chính xác (tức là bạn không cố mở cơ sở dữ liệu sqlite3 với tệp thực thi sqlite2). Và bạn cũng có thể thử các ứng dụng khách SQLite khác (ví dụ: SQLiteStudio ). Hy vọng nó giúp.
Idolon

1
Tôi đang gặp sự cố với một lớp lót. Nó hoạt động tốt nếu tôi chạy lệnh trong một trình bao nhưng nếu tôi đặt vào một lớp lót thì tôi nhận được: Hệ thống không thể tìm thấy đường dẫn được chỉ định.
Rev Tyler

2
package <my package> là không rõ ... có ai biết tại sao không. Tôi đã cài đặt qua studio bằng cách nhấn nút gỡ lỗi.
Nathan Schwermann

4
Trên Android Lollipop tôi nhận đượcpermission denied
Muhammad Babar

1
Tôi đã kéo một cơ sở dữ liệu với hai bảng và hàng chục hoặc nhiều hàng trong mỗi bảng và thực hiện các truy vấn chọn lọc đầy đủ trên mỗi bảng. Một cái hoạt động tốt, cái kia báo lỗi dữ liệu trong tệp. Dự đoán tốt nhất của tôi lúc này là sự không khớp về mã hóa giữa Android và local shell.
Mason

23

Tôi sử dụng tập lệnh shell này trên MAC của mình, sao chép cơ sở dữ liệu trực tiếp vào thư mục chính của tôi. Giải pháp một cú nhấp chuột dễ dàng, chỉ cần thay đổi tên gói (com.example.app) và tên cơ sở dữ liệu (database.sqlite)

Tập lệnh đơn giản

#!/bin/bash
adb -d shell 'run-as com.example.app cat /data/data/com.example.app/databases/database.sqlite > /sdcard/database.sqlite'
adb pull /sdcard/database.sqlite ~/

Tập lệnh chấp nhận các đối số [tên_gói] [cơ sở dữ liệu]

#!/bin/bash

REQUIRED_ARGS=2
ADB_PATH=/Users/Tadas/Library/sdk/platform-tools/adb
PULL_DIR="~/"

if [ $# -ne $REQUIRED_ARGS ]
    then
        echo ""
        echo "Usage:"
        echo "android_db_move.sh [package_name] [db_name]"
        echo "eg. android_db_move.sh lt.appcamp.impuls impuls.db"
        echo ""
    exit 1
fi;


echo""

cmd1="$ADB_PATH -d shell 'run-as $1 cat /data/data/$1/databases/$2 > /sdcard/$2' "
cmd2="$ADB_PATH pull /sdcard/$2 $PULL_DIR"

echo $cmd1
eval $cmd1
if [ $? -eq 0 ]
    then
    echo ".........OK"
fi;

echo $cmd2
eval $cmd2

if [ $? -eq 0 ]
    then
    echo ".........OK"
fi;

exit 0

Lệnh đầu tiên đang tạo bản sao 0 byte của cơ sở dữ liệu, vì vậy tôi đã thực hiện một số điều chỉnh trong tập lệnh của bạn: gist.github.com/romulof/6af8a8919660f395f975
romulof

14

Cách tốt nhất để xem và quản lý cơ sở dữ liệu ứng dụng android của bạn là sử dụng thư viện này https://github.com/sanathp/DatabaseManager_For_Android

Với thư viện này, bạn có thể quản lý cơ sở dữ liệu SQLite ứng dụng của mình từ chính ứng dụng của bạn. bạn có thể xem các bảng trong cơ sở dữ liệu ứng dụng của mình, cập nhật, xóa, chèn hàng vào bảng của mình. Mọi thứ từ ứng dụng của bạn.

Đó là một tệp hoạt động java duy nhất, chỉ cần thêm tệp java vào thư mục nguồn của bạn. Khi quá trình phát triển hoàn tất, hãy xóa tệp java khỏi thư mục src của bạn.

Nó đã giúp tôi rất nhiều. Hy vọng nó cũng giúp bạn.

Bạn có thể xem bản demo 1 phút tại đây: http://youtu.be/P5vpaGoBlBY


11

Mặc dù, đó là một câu hỏi cũ, tôi nghĩ nó vẫn có liên quan và xứng đáng có câu trả lời ở trạng thái hiện tại. Có sẵn các công cụ cho phép bạn kiểm tra cơ sở dữ liệu trực tiếp (mà không cần phải kéo chúng từ thiết bị hoặc trình mô phỏng).

Công cụ mà tôi đã khám phá gần đây nhất (và ưa thích nhất) là Android Debug Database .

Bạn chỉ cần thêm phần phụ thuộc này:

debugImplementation 'com.amitshekhar.android:debug-db:1.0.3'

Không cần thêm mã. Sau khi bạn khởi động ứng dụng của mình, hãy mở logcat và lọc "DebugDB" và bạn sẽ thấy một thông báo cho biết

D/DebugDB: Open http://192.168.178.XXX:8080 in your browser

Nó hoạt động với mọi trình duyệt và bạn có thể kiểm tra các bảng cơ sở dữ liệu và các tùy chọn được chia sẻ của mình.

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

Nó cũng hoạt động với trình giả lập mặc định và Genymotion.


Công cụ tôi đã sử dụng trước đây là stetho .

Nhược điểm: Bạn cần thêm một chút mã và bạn bị ràng buộc với trình duyệt Chrome.

Ưu điểm: Bạn cũng có tùy chọn để kiểm tra lưu lượng mạng.



5

Nếu bạn nhận được

The system cannot find the path specified.

thử

adb -d shell "run-as com.yourpackage cat /data/data/com.yourpackage/databases/dbname.sqlite > /sdcard/dbname.sqlite"

Lưu ý dấu ngoặc kép!


3

Tôi chỉ đơn giản làm:

$ adb shell
shell@android:/ $ run-as myapp.package.name sh
shell@android:/data/data/myapp.package.name $

Sau đó, tôi có thể gỡ lỗi cơ sở dữ liệu sqlite hoặc bất cứ điều gì tôi muốn làm từ shell với các quyền phù hợp.


2

Có một cách nếu apk có thể gỡ lỗi là sử dụng một chương trình có tên là run-as từ adb shell (không phải root) để sao chép tệp riêng tư của ứng dụng.


2

Đây là hướng dẫn từng bước - chủ yếu được lấy từ sự kết hợp của các câu trả lời khác. Điều này hoạt động với các thiết bị chưa được mở khóa.

  1. Kết nối thiết bị của bạn và khởi chạy ứng dụng ở chế độ gỡ lỗi.

  2. Sao chép tệp cơ sở dữ liệu từ thư mục ứng dụng của bạn vào thẻ sd của bạn: thực thi:

    ./adb -d shell 'run-as com.yourpackge.name cat /data/data/com.yourpackge.name/databases/filename.sqlite> /sdcard/filename.sqlite'

  3. Kéo các tệp cơ sở dữ liệu vào máy của bạn: thực thi:

    ./adb kéo / sdcard / thực thi: ./adb

  4. Cài đặt Firefox SQLLite Manager: https://addons.mozilla.org/en-US/firefox/addon/sqlite-manager/

  5. Mở Firefox SQLLite Manager và mở tệp cơ sở dữ liệu của bạn từ bước 3 ở trên.

  6. Thưởng thức!


2

Android Studio 4.1 Đã thêm một tính năng mới để xem / chỉnh sửa cơ sở dữ liệu Android SQLite.

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

Cách mở Trình kiểm tra cơ sở dữ liệu

Để mở Trình kiểm tra cơ sở dữ liệu trong Android Studio, bạn cần chọn View > Tool Windows > Database Inspector từ thanh menu.

Ngoài ra, bạn cần chạy ứng dụng đến một thiết bị chạy API cấp 26 trở lên.

Sử dụng công cụ này, bạn có thể

  • Truy vấn cơ sở dữ liệu của bạn

  • Sửa đổi và gỡ lỗi cơ sở dữ liệu của bạn

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


2

Trong Android Studio 4.1 mới có Trình kiểm tra cơ sở dữ liệu mới .

https://developer.android.com/studio/preview/features/images/database-ins rà.gif

Bạn có thể chọn các tùy chọn sau từ thanh menu View > Tool Windows > Database Inspectorđể mở nó. Hướng dẫn chi tiết hơn có thể được tìm thấy trong blog này .

Một cách khác là sử dụng stetho cho việc này. Bạn thêm phần phụ thuộc và sau đó có thể sử dụng Chrome DevTools (chrome: // Kiểm tra) để kiểm tra cơ sở dữ liệu khi thiết bị được cắm vào.


1

Bạn cần chạy adb dưới dạng root hoặc sử dụng nó trên điện thoại đã root.

Để chạy adb dưới dạng root, hãy sử dụng adb root

Xem thêm: Tại sao tôi bị từ chối truy cập vào thư mục dữ liệu khi sử dụng adb?


Tôi đã thử điều này. Nhưng nó cho tôi "adb không thể chạy dưới dạng root trong các bản dựng sản xuất"
Primal Pappachan

Bạn sẽ cần chạy nó ở chế độ Gỡ lỗi.
Malfist

Xem phần này: mydroidworld.com/forums/android-hacks/… Nếu bạn đang chạy nó trên điện thoại chứ không phải trình giả lập, bạn sẽ phải root nó.
Malfist

Tôi đã chạy ứng dụng ở chế độ gỡ lỗi và cũng đã thử các bước trên. Nó không hoạt động.
Primal Pappachan

Điều này chỉ hoạt động đối với trình giả lập hoặc thiết bị đã root.
slott 13/01

1

Không có run-asgiải pháp -and-cat-to-sdcard nào phù hợp với tôi trên Android 4.4.2. Tôi không chắc, nhưng tôi nghi ngờ có thể do run-ascông cụ xử lý không chính xác quyền sdcard_rsdcard_rwquyền mới.

Trước tiên, tôi phải sao chép tệp cơ sở dữ liệu /filesvào bộ nhớ trong riêng tư của ứng dụng của mình:

shell@hammerhead:/ $ run-as com.example.myapp   
shell@hammerhead:/data/data/com.example.myapp $ cp databases/mydb files/mydb

Sau đó, tôi đã sao chép /sdcard/Android/data/com.example.myapp/filesvào Javaland (điều này yêu cầu sự WRITE_EXTERNAL_STORAGEcho phép):

public class MainActivity extends BaseActivity {

    @Override
     protected void onCreate(Bundle savedInstanceState) {
         ...

         if (isExternalStorageWritable()) {
             final FileInputStream input;
             try {
                 input = openFileInput("mydb");

                 File output = new File(getExternalFilesDir(null), "mydb");

                 copy(input, output);
             } catch (FileNotFoundException e) {
                 e.printStackTrace();
             } catch (IOException e) {
                 e.printStackTrace();
             }
         }
     }

     public void copy(FileInputStream in, File dst) throws IOException {
         OutputStream out = new FileOutputStream(dst);

         // Transfer bytes from in to out
         byte[] buf = new byte[1024];
         int len;
         while ((len = in.read(buf)) > 0) {
             out.write(buf, 0, len);
         }
         in.close();
         out.close();
     }

     public boolean isExternalStorageWritable() {
         String state = Environment.getExternalStorageState();
         return Environment.MEDIA_MOUNTED.equals(state);
     }
 }

Cuối cùng, tôi đã sao chép tệp vào máy tính xách tay của mình:

$ adb pull /sdcard/Android/data/com.example.myapp/files/mydb

1
Có một giải pháp đơn giản hơn. Nếu bạn chmod 777 tệp sqlite của mình, sau đó thoát khỏi run-as, nó sẽ cho phép bạn sao chép nó sang / sdcard như usre thông thường.
zedix

1

Thiết bị của tôi không có thẻ sdcard

vì vậy giải pháp đầu tiên không làm việc cho tôi.

Nếu bạn đang gặp sự cố tương tự, hãy thử như sau:

  adb shell "run-as package chmod 777 /data/data/package/databases/yourdb.sqlite";
  adb pull /data/data/package/databases/yourdb.sqlite

/sdcardkhông nhất thiết phải là thẻ SD. Trên điện thoại của tôi, nó trỏ đến bộ nhớ trong khi không có thẻ SD vật lý.
DearVolt

0

Hãy thử ứng dụng này: SQLiteWeb ( https://play.google.com/store/apps/details?id=br.com.cm.sqliteweb ). Nó cung cấp quyền truy cập từ xa vào cơ sở dữ liệu của bạn mà không cần kéo nó ra.

Trong phiên bản trả phí, nó có quyền truy cập root cho cơ sở dữ liệu riêng (/ data / data / package-name ...) hoặc triển khai Nhà cung cấp nội dung để kết nối bằng SQLiteWeb (Hướng dẫn bên trong ứng dụng)

Nhưng nếu muốn tiếp tục với phiên bản miễn phí, bạn có thể tạo cơ sở dữ liệu của mình trong bộ nhớ ngoài:

database = SQLiteDatabase.openDatabase(Environment.getExternalStorageDirectory()
        + "/" + DATABASE_NAME, null, DATABASE_VERSION);

0

Trên OSX, sử dụng @Tadas answer với trình tự động và sqllitebrowser ( https://github.com/sqlitebrowser/sqlitebrowser ):

  1. mở Automator và tạo quy trình làm việc mới.

  2. thêm hành động "Run Shell Script".

  3. Dán cái này:

    source ~ / .bash_profile adb shell 'run-as cat /data/data/your_app_uid/databases/db.name> /tmp/db.name' adb pull /tmp/db.name ~ / open -a sqlitebrowser ~ / db. Tên

  4. bấm chạy để làm mới cơ sở dữ liệu trên sqlitebrowser.


0
  1. Mở một thiết bị đầu cuối
  2. cd <ANDROID_SDK_PATH>(đối với tôi trên Windows cd C:\Users\Willi\AppData\Local\Android\sdk)
  3. cd platform-tools
  4. adb shell (điều này chỉ hoạt động nếu chỉ có một trình giả lập đang chạy)
  5. cd data/data
  6. su (đạt được đặc quyền của người dùng cấp cao)
  7. cd <PACKAGE_NAME>/databases
  8. sqlite3 <DB_NAME>
  9. phát hành câu lệnh SQL ( quan trọng: chấm dứt chúng bằng ;, nếu không câu lệnh không được phát hành và thay vào đó, câu lệnh sẽ bị ngắt thành một dòng mới.)

Lưu ý: Sử dụng ls(Linux) hoặc dir(Windows) nếu bạn cần liệt kê nội dung thư mục.

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.