Загрузка файла базы данных в каталог приложения

#java #android #sqlite

#java #Android #sqlite

Вопрос:

я хочу обновить базу данных sqlite приложения при нажатии на кнопку с помощью DownloadManager.

Но там написано «java.lang.Исключение IllegalArgumentException: не URI файла: /data/user/0/com.example.laudien.listviewtesting/базы данных /Сотрудники»

Что я делаю неправильно? Мне нужно разрешение для этого? Разрешение на доступ в Интернет уже есть в манифесте.

Вот код моего метода updateDb():

 private void updateDb() {
    DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); // create download manager
    DownloadFinishedReceiver receiver = new DownloadFinishedReceiver(); // create broadcast receiver
    registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); // register the receiver
    DownloadManager.Request request = new DownloadManager.Request(Uri.parse(DATABASE_URL)); // create a download request

    // delete database file if it exists
    File databaseFile = new File(getDatabasePath(DATABASE_NAME).getAbsolutePath());
    if(databaseFile.exists())
        databaseFile.delete();

    request//.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN) // not visible
        .setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI) // only via wifi
        .setDestinationUri(Uri.parse("file:"   getDatabasePath(DATABASE_NAME).getAbsolutePath())); // set path in app dir
    downloadManager.enqueue(request); // enqueue the download request
}
  

Комментарии:

1. Привет ! Почему вы не используете URI файла базы данных напрямую напрямую? А именно, databaseFile.toURI(); в метод setDestinationUri(). Кроме того, если у вас возникли проблемы с разрешениями, вы получите исключение SecurityException. Я быстро адаптировал и попробовал ваш пример для загрузки логотипа Google, и он работал довольно хорошо. например .setDestinationUri(Uri.parse(«file:» Environment.getExternalStoragePublicDirectory(Environment. DIRECTORY_PICTURES) «/google.png»))

2. Спасибо за ваш ответ! Я попробовал .setDestinationUri(databaseFile.toURI()), но затем он говорит «android.net . Uri» не может быть применен к «java.net.Uri». Затем я попробовал .setDestinationUri(Uri.fromFile(databaseFile)), но там написано «java.lang. Исключение SecurityException: неподдерживаемый путь /data/user/0/com.example. laudien.listviewtesting/databases/Employees» Затем я добавил разрешения WRITE_EXTERNAL_STORAGE и READ_EXTERNAL_STORAGE и принял их в эмуляторе, но это та же ошибка.

Ответ №1:

Ваш путь /data/user/0/com.example.laudien.listviewtesting — это частная внутренняя память вашего приложения. Вы получили его с помощью getFilesDir() . Другие приложения не имеют доступа. Включая менеджер загрузок. Вместо этого используйте внешнюю память, предоставленную getExternalStorageDirectory() .

Ответ №2:

Для тех, кто хочет загрузить конфиденциальные файлы в личные папки приложения, я должен сказать, что менеджер загрузок не имеет доступа к этим папкам во внутреннем хранилище. Но решение заключается в перемещении загруженного файла в широковещательный приемник. Например, поместить такую строку в BroadcastReceiver:

 String destinationFileName = "test.mp4";
String filePath = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
copyFile(Uri.parse(filePath).getPath(), context.getFilesDir()   "/"   destinationFileName);
  

и CopyFile — это метод, подобный этому:

 private void copyFile(String inFileName, String outFileName) throws IOException {

    InputStream myInput = new FileInputStream(inFileName);

    OutputStream myOutput = new FileOutputStream(outFileName);

    // Transfer bytes from the input file to the output file
    byte[] myBuffer = new byte[1024];
    int length;
    while ((length = myInput.read(myBuffer)) > 0)
        myOutput.write(myBuffer, 0, length);

    // Close the streams
    myOutput.flush();
    myOutput.close();
    myInput.close();
}
  

Комментарии:

1. Что такое cursor ?

2. @Starwave Я использую курсор для чтения определенной константы COLUMN_* из результата download => Cursor cursor = DownloadManager . запрос (новый DownloadManager. Запрос ());