7

i want to update the sqlite database of the app when clicking on a button using the DownloadManager.

But it says "java.lang.IllegalArgumentException: Not a file URI: /data/user/0/com.example.laudien.listviewtesting/databases/Employees"

What do i make wrong? Do i need a permission for that? The internet permission is already in the manifest.

Here is the code of my updateDb() method:

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
}
Eric Bachhuber
  • 3,872
  • 2
  • 19
  • 26
P1xelfehler
  • 1,122
  • 7
  • 19
  • Hey ! Why don't you directly reuse databaseFile URI's directly ? Namely, databaseFile.toURI(); into the setDestinationUri() method. In addition, if you had a permission problem, you'd get a SecurityException. I've quickly adapted and tried your example to download Google's logo and it worked pretty fine. e.g. .setDestinationUri(Uri.parse("file:" + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)+ "/google.png")) – Yannick Müller Oct 07 '16 at 08:04
  • Thank you for your response! I tried .setDestinationUri(databaseFile.toURI()) but then it says "android.net.Uri" cannot be applied to "java.net.Uri". Then I tried .setDestinationUri(Uri.fromFile(databaseFile)) but it says "java.lang.SecurityException: Unsupported path /data/user/0/com.example.laudien.listviewtesting/databases/Employees" Then i added the WRITE_EXTERNAL_STORAGE and READ_EXTERNAL_STORAGE permissions and accepted it in the emulator, but it is the same error. – P1xelfehler Oct 07 '16 at 08:33

2 Answers2

7

Your path /data/user/0/com.example.laudien.listviewtesting is private internal memory of your app. You obtained it using getFilesDir(). Other apps have no access. Including the download manager. Use external memory given by getExternalStorageDirectory() instead.

greenapps
  • 11,154
  • 2
  • 16
  • 19
1

For anyone who wants to download sensitive files to app's private folders, I have to say that download manager doesn't have access to these folders inside internal storage. But the solution is moving the downloaded file in broadcast receiver. For example putting such line in BroadcastReceiver:

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

and copyFile is a method like this:

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();
}
Ehsan
  • 377
  • 1
  • 2
  • 10