Friday, May 24, 2013

Workaround bug in Android's DownloadManager

Bug in Android's DownloadManager service is quite well known. You can check it out here and here for some example. Here is what I found on my use of it :

  1. Some files are re-downloaded and and saved with '-1' suffix
  2. Some other files are re-downloaded but failed on the second download. However, it just not fail but together with it, the first succesfully downloaded files are deleted!
  3. The events on 'onReceive' is pretty whacky too which takes some tries and hack to get it right
Suffice to say it was no fun and I saw hours of work just goes out of window because of it which can be used for more productive work if the API just do what it supposed to do as stated on the documentation. Strangely,  so far there was no good workaround that I can use on my case. Some are overly complicated that I don't see them as justified in term of long-term maintenance cost.

In my case, the first case above (successful double download) is not my primary concern. The duplicates are negligible. However, the second one done some catastrophic damage on how my code are run. So, after trying things here and there, here's what I come up with in pseudocode :
  • prepare two files : the true destination file and temporary destination file
  • download to temporary
  • right after download successful,  rename temporary to original destination file
  • now, in the case Android going into the second case above, it will try to delete temporary file instead and the original destination file is save
Below are the code snippet to be put in onReceive of BroadcastReceiver :

   1 if(status == DownloadManager.STATUS_SUCCESSFUL)
   2 {
   3     File fileTmp = new File(fileNameTmp);
   4     File file = new File(fileName);
   5     
   6     if(file.exists())file.delete();
   7     fileTmp.renameTo(file);
   8 }