การดีบักฐานข้อมูล sqlite บนอุปกรณ์


98

ขณะนี้ฉันกำลังทำงานกับแอปพลิเคชัน WiFi สำหรับ Android ฉันมีปัญหาในการพยายามเข้าถึงฐานข้อมูลบนอุปกรณ์ การดีบักในโปรแกรมจำลองไม่ได้ผลสำหรับฉันเพราะไม่มีการรองรับ WiFi ในโปรแกรมจำลอง ฉันพยายามดึงไฟล์ฐานข้อมูลออกจากอุปกรณ์โดยใช้ไฟล์

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

แต่ฉันได้รับข้อผิดพลาด "การอนุญาตถูกปฏิเสธ" ในคำตอบนี้Android: ไฟล์ฐานข้อมูลถูกเก็บไว้ที่ไหน? Commonsware ได้แนะนำให้ดึงไฟล์ฐานข้อมูลโดยเรียกใช้ในโหมดดีบัก แต่ก็ไม่ได้ผลเช่นกัน ความช่วยเหลือใด ๆ เกี่ยวกับวิธีการดีบักฐานข้อมูลโดยไม่ต้องรูทอุปกรณ์จะได้รับการชื่นชมมาก

คำตอบ:


142

ฉันจะพูดซ้ำจากคำตอบอื่น :

เริ่มตั้งแต่ API ระดับ 8 (Android 2.2) หากคุณสร้างแอปพลิเคชันแบบดีบักได้คุณสามารถใช้run-asคำสั่งเชลล์เพื่อเรียกใช้คำสั่งหรือเรียกใช้งานได้ในฐานะผู้ใช้ / แอปพลิเคชันเฉพาะหรือเพียงแค่เปลี่ยนไปUIDใช้แอปพลิเคชันของคุณเพื่อให้คุณสามารถเข้าถึงข้อมูลได้ ไดเรกทอรี

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

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

สิ่งนี้จะคัดลอกdb-fileไปที่รากของการ์ด SD / ที่เก็บข้อมูลภายนอก ตอนนี้คุณสามารถรับได้อย่างง่ายดายจากที่นั่นโดยใช้ตัวจัดการไฟล์adb pullหรืออะไรก็ได้ที่คุณต้องการ โปรดทราบว่าด้วยวิธีนี้แอปของคุณไม่จำเป็นต้องมีWRITE_EXTERNAL_STORAGEรับอนุญาตเนื่องจากการคัดลอกจะกระทำโดยผู้ใช้เชลล์ซึ่งสามารถเขียนลงในที่จัดเก็บข้อมูลภายนอกได้ตลอดเวลา

บนระบบ Linux / Mac มีความเป็นไปได้ที่จะคัดลอกฐานข้อมูลไปยังคอมพิวเตอร์ของคุณโดยตรงด้วยคำสั่งต่อไปนี้ซึ่งสามารถใช้ได้โดยไม่ต้องเข้าสู่ adb shell:

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

อย่างไรก็ตามสิ่งนี้จะทำงานไม่ถูกต้องบน Windows เนื่องจากการแปลงสัญลักษณ์ CR / LF ใช้วิธีเดิมที่นั่น


1
@MikeIsrael ในกรณีที่คุณไม่ได้ใช้ SQLCipher ในแอปของคุณใช่หรือไม่? หากไม่เป็นเช่นนั้นให้ตรวจสอบโดยคร่าวๆว่าฐานข้อมูลถูกดาวน์โหลดอย่างถูกต้องหรือไม่ให้เปิดไฟล์ DB ในวิวเวอร์ (ควรเป็น hex-viewer) และตรวจสอบว่าเริ่มต้นด้วยSQLite format 3สตริงหรือไม่ ตรวจสอบให้แน่ใจว่าคุณมีsqliteเวอร์ชันที่ถูกต้อง(กล่าวคือคุณไม่ได้พยายามเปิดฐานข้อมูล sqlite3 ด้วยไฟล์ปฏิบัติการ sqlite2) และคุณยังสามารถลองใช้ไคลเอนต์ SQLite อื่น ๆ (ตัวอย่างเช่นSQLiteStudio ) หวังว่าจะช่วยได้
Idolon

1
ฉันมีปัญหากับซับเดียว ใช้งานได้ดีถ้าฉันรันคำสั่งในเชลล์ แต่ถ้าฉันใส่ซับในอันเดียวฉันจะได้รับ: ระบบไม่พบพา ธ ที่ระบุ
Rev Tyler

2
แพ็คเกจ <แพ็คเกจของฉัน> ไม่เป็นที่รู้จัก ... มีใครรู้ว่าทำไม ฉันติดตั้งผ่านสตูดิโอโดยกดปุ่มแก้ไขข้อบกพร่อง
Nathan Schwermann

4
บน Android Lollipop ฉันได้รับpermission denied
มูฮัมหมัดบาบาร์

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

23

ฉันใช้เชลล์สคริปต์นี้บน MAC ของฉันซึ่งคัดลอกฐานข้อมูลไปยังโฟลเดอร์บ้านของฉันโดยตรง วิธีแก้ปัญหาง่ายๆในคลิกเดียวเพียงแค่เปลี่ยนชื่อแพ็คเกจ (com.example.app) และชื่อฐานข้อมูล (database.sqlite)

สคริปต์ง่ายๆ

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

สคริปต์ที่ยอมรับอาร์กิวเมนต์ [package_name] [ฐานข้อมูล]

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

คำสั่งแรกคือการสร้างสำเนาฐานข้อมูลแบบศูนย์ไบต์ดังนั้นฉันจึงทำการปรับเปลี่ยนบางอย่างในสคริปต์ของคุณ: gist.github.com/romulof/6af8a8919660f395f975
romulof

14

วิธีที่ดีที่สุดในการดูและจัดการฐานข้อมูลแอป Android ของคุณคือใช้ไลบรารีนี้https://github.com/sanathp/DatabaseManager_For_Android

ด้วยไลบรารีนี้คุณสามารถจัดการฐานข้อมูล SQLite ของแอปจากแอปของคุณเอง คุณสามารถดูตารางในฐานข้อมูลแอปอัปเดตลบแทรกแถวในตารางของคุณได้ทุกอย่างจากแอปของคุณ

มันเป็นไฟล์กิจกรรม java ไฟล์เดียวเพียงเพิ่มไฟล์ java ลงในโฟลเดอร์ต้นทางของคุณเมื่อการพัฒนาเสร็จสิ้นให้ลบไฟล์ java ออกจากโฟลเดอร์ src ของคุณ

มันช่วยฉันได้มากหวังว่ามันจะช่วยคุณเช่นกัน

คุณสามารถดูการสาธิต 1 นาทีได้ที่นี่: http://youtu.be/P5vpaGoBlBY


11

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

เครื่องมือที่ฉันค้นพบล่าสุด (และชอบมากที่สุด) คือAndroid Debug Databaseฐานข้อมูล

คุณต้องเพิ่มการอ้างอิงนี้เท่านั้น:

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

ไม่ต้องใช้รหัสเพิ่มเติม หลังจากที่คุณเริ่มแอปของคุณให้เปิด logcat และกรอง "DebugDB" แล้วคุณจะพบข้อความว่า

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

ใช้งานได้กับทุกเบราว์เซอร์และคุณสามารถตรวจสอบตารางฐานข้อมูลและค่ากำหนดที่ใช้ร่วมกันได้

ป้อนคำอธิบายภาพที่นี่

นอกจากนี้ยังทำงานร่วมกับค่าเริ่มต้นและตัวเลียนแบบ Genymotion


เครื่องมือที่ฉันใช้ก่อนหน้านี้คือstetho stetho

ข้อเสีย: คุณต้องเพิ่มโค้ดเล็กน้อยและคุณจะผูกพันกับเบราว์เซอร์ Chrome

ข้อดี: คุณมีตัวเลือกในการตรวจสอบการรับส่งข้อมูลเครือข่าย


5

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

ดูที่โพสต์นี้: การสำรองฐานข้อมูลไปยัง SDCard บน Android


5

ถ้าคุณได้รับ

The system cannot find the path specified.

ลอง

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

หมายเหตุคำพูดคู่!


3

ฉันแค่ทำ:

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

จากนั้นฉันสามารถดีบักฐานข้อมูล sqlite หรืออะไรก็ได้ที่ฉันต้องการทำจากเชลล์ด้วยสิทธิ์ที่ถูกต้อง


3

ในใหม่Android 4.1 สตูดิโอมีใหม่ตรวจสอบฐานข้อมูล

https://i.ibb.co/9tNM1xg/database-Inspector.gif

คุณสามารถเลือกตัวเลือกต่อไปนี้จากแถบเมนูView > Tool Windows > Database Inspectorเพื่อเปิด ( App Inspectorใน Android Studio 4.2) สามารถดูคำแนะนำโดยละเอียดเพิ่มเติมได้ในบล็อกนี้และในบทความExploring the Database Inspector ใน Android Studioขนาดกลาง

อีกวิธีหนึ่งคือการใช้stethoสำหรับสิ่งนี้ คุณเพิ่มการอ้างอิงจากนั้นสามารถใช้ Chrome DevTools (chrome: // ตรวจสอบ) เพื่อตรวจสอบฐานข้อมูลเมื่อเสียบอุปกรณ์


2
นี่คือตัวเลือกที่ดีที่สุดสำหรับปี 2020 และใหม่กว่า
Yair Kukielka

2

มีวิธีหาก apk สามารถดีบักได้เพื่อใช้โปรแกรมที่เรียกว่า run-as จาก adb shell (ไม่ใช่รูท) เพื่อคัดลอกไฟล์ส่วนตัวของแอปพลิเคชัน


2

นี่คือคำแนะนำทีละขั้นตอนซึ่งส่วนใหญ่มาจากการรวมกันของคำตอบอื่น ๆ ซึ่งใช้ได้กับอุปกรณ์ที่ไม่ได้ปลดล็อก

  1. เชื่อมต่ออุปกรณ์ของคุณและเปิดแอปพลิเคชันในโหมดแก้ไขข้อบกพร่อง

  2. คัดลอกไฟล์ฐานข้อมูลจากโฟลเดอร์แอปพลิเคชันของคุณไปยังการ์ด SD ของคุณ: ดำเนินการ:

    ./adb -d เชลล์ 'run-as com.yourpackge.name cat /data/data/com.yourpackge.name/databases/filename.sqlite> /sdcard/filename.sqlite'

  3. ดึงไฟล์ฐานข้อมูลไปยังเครื่องของคุณ: ดำเนินการ:

    ./adb pull / sdcard / execute: ./adb

  4. ติดตั้ง Firefox SQLLite Manager: https://addons.mozilla.org/en-US/firefox/addon/sqlite-manager/

  5. เปิด Firefox SQLLite Manager และเปิดไฟล์ฐานข้อมูลของคุณจากขั้นตอนที่ 3 ด้านบน

  6. สนุก!


2

Android Studio 4.1เพิ่มคุณสมบัติใหม่เพื่อดู / แก้ไขฐานข้อมูล Android SQLite

ป้อนคำอธิบายภาพที่นี่

วิธีเปิดตัวตรวจสอบฐานข้อมูล

ในการเปิดตัวตรวจสอบฐานข้อมูลใน Android Studio คุณต้องเลือกView > Tool Windows > Database Inspectorจากแถบเมนู

นอกจากนี้คุณต้องเรียกใช้แอปไปยังอุปกรณ์ที่ใช้ API ระดับ 26 ขึ้นไป

คุณสามารถใช้เครื่องมือนี้ได้

  • สืบค้นฐานข้อมูลของคุณ

  • แก้ไขและดีบักฐานข้อมูลของคุณ

ป้อนคำอธิบายภาพที่นี่


1

คุณต้องใช้ adb ในฐานะรูทหรือใช้บนโทรศัพท์ที่รูท

ในการเรียกใช้ adb ในฐานะ root ให้ใช้ adb root

ดูเพิ่มเติม: เหตุใดฉันจึงถูกปฏิเสธการเข้าถึงโฟลเดอร์ข้อมูลเมื่อใช้ adb


ฉันได้ลองสิ่งนี้แล้ว แต่มันทำให้ฉัน "adb ไม่สามารถทำงานเป็นรูทในงานสร้าง"
Primal Pappachan

คุณจะต้องเรียกใช้ในโหมดแก้ไขข้อบกพร่อง
Malfist

ดูสิ่งนี้: mydroidworld.com/forums/android-hacks/…หากคุณใช้งานบนโทรศัพท์ไม่ใช่โปรแกรมจำลองคุณจะต้องรูทเครื่อง
Malfist

ฉันรันแอปพลิเคชันในโหมดดีบักและลองทำตามขั้นตอนข้างต้นด้วย มันใช้ไม่ได้
ปฐมปุพพาจารย์

ใช้งานได้กับโปรแกรมจำลองหรืออุปกรณ์ที่รูทเท่านั้น
slott

1

ไม่มีrun-asโซลูชัน -and-cat-to-sdcard ที่ใช้ได้กับฉันใน Android 4.4.2 ฉันไม่แน่ใจ แต่ฉันสงสัยว่าอาจเป็นเพราะrun-asเครื่องมือไม่สามารถจัดการกับใหม่sdcard_rและsdcard_rwสิทธิ์ได้อย่างถูกต้อง

ก่อนอื่นฉันต้องคัดลอกไฟล์ฐานข้อมูลไปยังที่/filesเก็บข้อมูลภายในส่วนตัวของแอปพลิเคชันของฉัน:

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

จากนั้นฉันคัดลอกไปยัง/sdcard/Android/data/com.example.myapp/filesใน Javaland (ต้องWRITE_EXTERNAL_STORAGEได้รับอนุญาต):

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);
     }
 }

สุดท้ายฉันคัดลอกไฟล์ไปยังแล็ปท็อปของฉัน:

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

1
มีวิธีแก้ปัญหาที่ง่ายกว่านี้ หากคุณ chmod 777 ไฟล์ sqlite ของคุณให้ออกจาก run-as มันจะช่วยให้คุณคัดลอกไปที่ / sdcard เป็น usre ปกติ
zedix

1

อุปกรณ์ของฉันไม่มี sdcard

ดังนั้นวิธีแก้ปัญหาแรกจึงไม่ได้ผลสำหรับฉัน

หากคุณประสบปัญหาคล้ายกันให้ลองทำดังนี้:

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

/sdcardไม่จำเป็นต้องเป็นการ์ด SD บนโทรศัพท์ของฉันชี้ไปที่ที่เก็บข้อมูลภายในเมื่อไม่มีการ์ด SD จริง
DearVolt

0

ลองใช้แอปนี้: SQLiteWeb ( https://play.google.com/store/apps/details?id=br.com.cm.sqliteweb ) ให้การเข้าถึงฐานข้อมูลของคุณจากระยะไกลโดยไม่ต้องดึงออก

ในเวอร์ชันที่ต้องชำระเงินจะมีการเข้าถึงรูทสำหรับฐานข้อมูลส่วนตัว (/ data / data / package-name ... ) หรือใช้ Content Provider เพื่อเชื่อมต่อโดยใช้ SQLiteWeb (คำแนะนำภายในแอป)

แต่หากต้องการอยู่กับเวอร์ชันฟรีคุณสามารถสร้างฐานข้อมูลของคุณในที่จัดเก็บข้อมูลภายนอก:

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

0

บน OSX โดยใช้ @Tadas answer กับ automator และ sqllitebrowser ( https://github.com/sqlitebrowser/sqlitebrowser ):

  1. เปิด Automator และสร้างเวิร์กโฟลว์ใหม่

  2. เพิ่มการดำเนินการ "เรียกใช้เชลล์สคริปต์"

  3. วางสิ่งนี้:

    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 ชื่อ

  4. คลิกรันเพื่อรีเฟรชฐานข้อมูลบน sqlitebrowser


0
  1. เปิดเทอร์มินัล
  2. cd <ANDROID_SDK_PATH>(สำหรับฉันใน Windows cd C:\Users\Willi\AppData\Local\Android\sdk)
  3. cd platform-tools
  4. adb shell (ใช้งานได้ก็ต่อเมื่อมีเพียงโปรแกรมจำลองเดียวเท่านั้นที่ทำงานอยู่)
  5. cd data/data
  6. su (รับสิทธิ์ผู้ใช้ขั้นสูง)
  7. cd <PACKAGE_NAME>/databases
  8. sqlite3 <DB_NAME>
  9. ออกคำสั่ง SQL ( สำคัญ:ยกเลิกคำสั่งด้วย;มิฉะนั้นคำสั่งจะไม่ออกและแตกไปขึ้นบรรทัดใหม่แทน)

หมายเหตุ: ใช้ls(Linux) หรือdir(Windows) หากคุณต้องการแสดงรายการเนื้อหาไดเรกทอรี

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