14

I want to download a file to SDCard with Android DownloadManager class:

Request request = new Request(Uri.parse(url));
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename); //set destination dir
long downloadId = downloader.enqueue(request);

But I always get download status=16(STATUS_FAILED), and reason=1008(ERROR_CANNOT_RESUME). I have already included android.permission.WRITE_EXTERNAL_STORAGE in the manifest.

When i commented out the

request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename); 

and use the default download folder, it's OK. But I don't know where is the file goes, the localUri I get from the result is something like:

content://downloads/my_downloads/95

I don't know how to copy the file to SDCard.

What I want is download a file to SDCard. Could someone help? Thanks!

Dagang
  • 24,586
  • 26
  • 88
  • 133

2 Answers2

17

You can retrieve file path from localUri like this:

public static String getFilePathFromUri(Context c, Uri uri) {
    String filePath = null;
    if ("content".equals(uri.getScheme())) {
        String[] filePathColumn = { MediaColumns.DATA };
        ContentResolver contentResolver = c.getContentResolver();

        Cursor cursor = contentResolver.query(uri, filePathColumn, null,
                null, null);

        cursor.moveToFirst();

        int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
        filePath = cursor.getString(columnIndex);
        cursor.close();
    } else if ("file".equals(uri.getScheme())) {
        filePath = new File(uri.getPath()).getAbsolutePath();
    }
    return filePath;
}
Min
  • 301
  • 3
  • 4
13

Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString() gives me /mnt/sdcard/downloads

And I'm able to use the downloaded file in onReceive (ACTION_DOWNLOAD_COMPLETE)

long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
Query query = new Query();
query.setFilterById(downloadId);
Cursor cur = dm.query(query);

if (cur.moveToFirst()) {
    int columnIndex = cur.getColumnIndex(DownloadManager.COLUMN_STATUS);
    if (DownloadManager.STATUS_SUCCESSFUL == cur.getInt(columnIndex)) {
        String uriString = cur.getString(cur.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));

        File mFile = new File(Uri.parse(uriString).getPath());
        ....

    } else {
        Toast.makeText(c, R.string.fail, Toast.LENGTH_SHORT).show();
    }
}
tjpaul
  • 343
  • 3
  • 16
Mikhail
  • 398
  • 2
  • 15
  • I get only "content://downloads/my_downloads/539" with this code and no local path. – Radon8472 Sep 24 '15 at 13:12
  • 2
    Depending on the Android version you either get a file:// back (on android < 4.2) or a content:// (on android 4.2 and up). so this answer only applies to android lower 4.2 and on 4.2 and up the content would need to be resolved with the answer below by Min. – Bernd Kampl Oct 17 '15 at 07:52