2

I'm working on an app that can download files using DownloadManager. I set the download location to the external storage using this method:

setDestinationInExternalFilesDir(context, "temp_downloads", "filename");

The reason I decided to download to external storage is because some files are large (> 200 MB). The default download location which is a shared download cache directory has a limit of 200 MB size if I'm not mistaken and downloading more than 200 MB will cause the download to fail.

The problem is if a user that uses a device with sdcard ejects the sdcard while using the app, download will fail because setDestinationInExternalFilesDir method throws an IllegalStateException which will crash the app if not caught.

I have no issue with devices without sdcard slot because the system will generate an emulated external storage with path like: /storage/emulated/ and this storage will always be available. But if the device has sdcard slot, the external storage path will be /storage/sdcard0/ and if I try to call:

context.getExternalFilesDir(null);

while the sdcard is not mounted, it will return null.

Does this mean that DownloadManager will not work for downloading big files on device with ejected sdcard? or is there any work around for this problem?

I'm not looking for solutions like using a 3rd party library that downloads directly to internal storage or not using DownloadManager at all because using DownloadManager is a requirement.

Community
  • 1
  • 1
  • What is the problem with catching that exception? What is the problem first to check if a directory exists before calling a download manager? – greenapps Apr 21 '17 at 19:25
  • `setDestinationInExternalFilesDir()` will put the file on external storage. This should not be impacted by any change in the state of removable storage. There are a few devices in which external storage is removable. `getExternalFilesDir()` will not return a location on removable storage. – CommonsWare Apr 21 '17 at 19:25
  • @greenapps of course there is no problem with catching that exception and check if a directory exists. In fact, I'm already doing that. I just want to know if there's a work around for this problem so I don't just show a dialog message to the user saying "Please insert your SD card to download" –  Apr 21 '17 at 19:32
  • Sorry i do not understand your problem as most of what you said did not make sense. And if i were you i first would try to find out the path to an SD card. – greenapps Apr 21 '17 at 19:39
  • @CommonsWare thanks for the response. So does this mean I shouldn't use `setDestinationInExternalFilesDir()` because external storage is not always available on every devices? Can you recommend how I can download large files using DownloadManager and works on all devices? –  Apr 21 '17 at 19:39
  • "because external storage is not always available on every devices?" -- external storage is available the *vast* majority of the time. When I say "there are a few devices in which external storage is removable" I mean "a few out of ~2 billion". "Can you recommend how I can download large files using DownloadManager and works on all devices?" -- by definition, that is impossible. There are *many* reasons why this will fail. The user having removed external storage is merely one of them. And, again, that is very uncommon. – CommonsWare Apr 21 '17 at 19:41
  • If your `minSdkVersion` is below 11, you are at somewhat elevated risk of external storage being removable. The standard that external storage is part of the on-board flash came around in API Level 11. My recommendation at this point is to have a `minSdkVersion` of 15 or higher. If you really need a low `minSdkVersion`, you have little choice but to have the "please insert your SD card", as `DownloadManager` is not going to be an option otherwise. – CommonsWare Apr 21 '17 at 19:46
  • @CommonsWare my minSdkVersion is 14 and it's a requirement so I can't change it. Yeah showing a message to the user is what I could only think of. If you also said that then I guess there's no other choice. Thanks again dude. –  Apr 21 '17 at 19:51

0 Answers0