В настоящее время я работаю над приложением WiFi для Android. У меня возникли проблемы с попыткой доступа к базе данных на устройстве. Отладка в эмуляторе не работает для меня, потому что в эмуляторе нет поддержки WiFi. Я попытался вытащить файл базы данных из устройства с помощью
adb pull data/data/package-name/databases/database-name
Но я получаю сообщение об ошибке "Permission denied.". В этом ответе Android: Где хранятся файлы базы данных?, Commonsware предложила вытащить файл базы данных, запустив его в режиме отладки. Но это тоже не работает. Любая помощь в том, как отлаживать базу данных без укоренения устройства, будет очень признательна.
Повторюсь из другого ответа:
Начиная с уровня API 8 (Android 2.2), если вы создаете приложение как отладочное, вы можете использовать команду shell
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:
adb shell 'run-as com.yourpackage sh -c "cat ~/databases/db-file"' > db-file.sqlite
Это, однако, не будет корректно работать в Windows из-за преобразования символов CR/LF. Используйте там прежний метод.
Я использую эту оболочку script на моем MAC-адресе, которая копирует базу данных непосредственно в мою домашнюю папку. Простое решение одним кликом, просто измените имя пакета (com.example.app) и имя базы данных (database.sqlite)
Простой Script
#!/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 ~/
Script, который принимает аргументы [имя_пакета] [база данных]
#!/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
Лучший способ просмотра и управления вашей базой данных приложений Android - использовать эту библиотеку https://github.com/sanathp/DatabaseManager_For_Android
С помощью этой библиотеки вы можете управлять своей базой данных SQLite приложения непосредственно из своего приложения. вы можете просматривать таблицы в своей базе данных приложений, обновлять, удалять, вставлять строки в свои таблицы. Все, что из вашего приложения.
Его единственный файл активности java, просто добавьте java файл в исходную папку. После завершения разработки удалите java файл из вашей папки src.
Это очень помогло мне. Надеюсь, это тоже поможет.
Вы можете посмотреть 1-минутную демонстрацию здесь: http://youtu.be/P5vpaGoBlBY
Если вы получаете
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"
Обратите внимание на двойную кавычку!
В моем приложении я экспортирую базу данных на SD-карту. После того, как база данных находится на SD-карте, ее можно получить, подключив устройство к компьютеру.
Посмотрите на это сообщение: Создание резервной копии базы данных на SDCard на Android
Я просто сделал:
$ adb shell
shell@android:/ $ run-as myapp.package.name sh
shell@android:/data/data/myapp.package.name $
Затем я могу отлаживать базу данных sqlite или все, что я хочу сделать из оболочки с правильными разрешениями.
Вот пошаговые инструкции - в основном, взятые из комбинации других ответов. Это работает с устройствами, которые не разблокированы.
Подключите устройство и запустите приложение в режиме отладки.
Скопируйте файл базы данных из папки вашего приложения на вашу SD-карту: выполните:
./adb -d shell 'run-as com.yourpackge.name cat/data/data/com.yourpackge.name/databases/filename.sqlite > /sdcard/filename.sqlite'
Потяните файлы базы данных на свой компьютер: выполните:
./adb pull/sdcard/execute:./adb
Установите Firefox SQLLite Manager: https://addons.mozilla.org/en-US/firefox/addon/sqlite-manager/
Откройте Firefox SQLLite Manager и откройте файл базы данных с шага 3 выше.
Наслаждайтесь!
Существует способ, если apk отлаживается для использования программы, называемой run-as из оболочки (non-root) adb, для копирования закрытого файла приложения.
Если у вас такая же проблема, попробуйте вот так:
adb shell "run-as package chmod 777 /data/data/package/databases/yourdb.sqlite";
adb pull /data/data/package/databases/yourdb.sqlite
/sdcard
не обязательно SD-карта. На моем телефоне он указывает на внутреннюю память, когда нет физической SD-карты.
Ни один из решений 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
Вам нужно запустить adb как root или использовать его на корневом телефоне.
Чтобы запустить adb с правами root, используйте adb root
Смотрите также: Почему я получаю доступ к папке с данными при использовании adb?
В OSX, используя @Tadas ответ с помощью automator и sqllitebrowser (https://github.com/sqlitebrowser/sqlitebrowser):
откройте Automator и создайте новый рабочий процесс.
добавить действие "Run Shell Script".
Вставьте это:
источник ~/.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.name
нажмите, чтобы обновить базу данных на sqlitebrowser.
Попробуйте это приложение: 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);
SQLite format 3
. Также убедитесь, что у вас правильная версияsqlite
(т.е. вы не пытаетесь открыть базу данных sqlite3 с помощью исполняемого файла sqlite2). И вы также можете попробовать другие клиенты SQLite (например, SQLiteStudio ). Надеюсь, поможет.