My app has 5 big text files on them, each one about 40kb. Those files are updated weekly on a website.
I managed to set downloadManager to download the 5 files from the site. The problem is that I don't want the user to be able to use the app while the files are downloading because that will cause problems.
I want that when the user clicks the "Update" button it will show up a loading box. Then when the files finish downloading the box will disappear and a toast will say "Updated."
This is the method I've set up:
#SuppressLint("NewApi")
public void DownloadTxtFile(String url, String fileName) {
if (!new File(Environment.getExternalStorageDirectory()
+ "/folder").exists()) {
new File(Environment.getExternalStorageDirectory()
+ "/Dovahzul_Dictionary").mkdirs();
}
File file = new File(extStore.getAbsolutePath()
+ "/folder/" + fileName);
DownloadManager.Request request = new DownloadManager.Request(
Uri.parse(url));
request.setDescription("Downloading Text Files...");
request.setTitle("Updating")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
}
request.setDestinationInExternalPublicDir("/Dovahzul_Dictionary",
fileName);
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
if (file.exists()) {
file.delete();
} else {
}
manager.enqueue(request);
}
By the way, if you find any problem with the method, plase inform me as well.
Thanks in advance.
I know this is old, but to anyone that has the same problem: What you need to do, is start the download in a different thread.
As android is not thread prof, you need to use AsyncTask instead. An AsyncTask is very similar to a thread. By starting and using one, you can do some quite long operations without freezing the ui. (Note that AsyncTasks are recomended for operations that take seconds, not minutes. In that case, you need to find something else)
You start an AsyncTask, and make it download the file. The problem is that AsyncTasks can't access ui methods, so they can't change threads.
You can, luckly, override a method they have to update the ui, and call it directly from it's onExecute.
Many tutorials on this can be found in the web.
Related
I am developing an app that grabs a new json file every time is starts. But I've found that even though I delete the file and download the new one, the phone somehow still ends up with the old file.
Delete code:
if (test.exists()) {
test.delete();
Log.i(TAG, "Deleting File");
} else {
Log.i(TAG, "File does not exist");
}
Download Code:
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(path));
request.setTitle("stations.json");
request.setDescription("File is being downloaded.....");
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
request.setDestinationInExternalFilesDir(getApplicationContext(), null, "stations.json");
request.setVisibleInDownloadsUi(false);
manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
jsonRef = manager.enqueue(request);
I've deleted the file myself from the storage. It still grabs the old file. I've checked in a browser if the server version is updated. It was. I'm at a loss as to what may be happening. If the Stack community has any suggestions, it would be greatly appreciated. Thanks so much!
It appears that my phone was somehow caching the file. It would see that I was downloading the same file and would instead just give it to me. By giving it a new url, it tricked the app into thinking it was a new file.
In the end, what worked was to add:
?v=" + Math.random()
to the end of the file.
For Example:
String path = example.com/stations.json?v=" + Math.random();
Then download with:
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(path));
I'm not exactly sure what my problem is. I using the code below to download a bunch of files:
public void DownloadNow(ArrayList<String> must_download)
{
String serviceString = Context.DOWNLOAD_SERVICE;
DownloadManager download;
download = (DownloadManager)getSystemService(serviceString);
for(int x = 0; x < must_download.size(); x++)
{
System.out.println("DOWNLOADING "+must_download.get(x).toString());
Uri uri = Uri.parse("http://drm.csdev.nmmu.ac.za/Zandre/"+must_download.get(x).toString());
DownloadManager.Request request = new DownloadManager.Request(uri);
request.setDestinationInExternalFilesDir(this, Environment.DIRECTORY_DOWNLOADS, must_download.get(x).toString());
request.setNotificationVisibility(Request.VISIBILITY_VISIBLE);
request.setTitle(must_download.get(x).toString());
long reference = download.enqueue(request);
}
}
Where must_download is an ArrayList full of file names. This method has successfully worked in the past, until I tried to run it on a different thread. The thread idea did not work out so well, so I decided to switch back.
Now, the problem is this- since I switched back to the original method the Download Manager runs full time, downloading the same files over and over in an endless loop.The only way I can stop it is to **Disable the Download Manager, but then I can't download anything...
What I've read so far and tried is
Uninstall the app- still downloading...
Switch device off and back on again- still downloading...
Clear cache of Download Manager- still downloading...
Even after this has used all the devices mobile data, it still just carries on downloading.
Has anyone else encountered this type of problem? Any ideas solutions?
Based on another SO answer, I am using the following lines of code to download media files:
DownloadManager.Request r = new DownloadManager.Request(Uri.parse(uri));
// This put the download in the same Download dir the browser uses
r.setDestinationInExternalPublicDir(Environment.DIRECTORY_PODCASTS, fileName);
// When downloading music and videos they will be listed in the player
// (Seems to be available since Honeycomb only)
r.allowScanningByMediaScanner();
// Notify user when download is completed
// (Seems to be available since Honeycomb only)
r.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
// Start download
DownloadManager dm = (DownloadManager) getActivity().getSystemService(Context.DOWNLOAD_SERVICE);
dm.enqueue(r);
Now, that is all good except that I have a few questions:
The person who answered said that the notifications can be customized. How can that be done?
If I want to add a "cancel" button to cancel the download and delete the file, how do I do it? What do I need to implement to get this behavior? :)
// Changing the Notification Title, Description, and its Visibility
DownloadManager mgr = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
Uri uri = Uri.parse("///.mp3");
DownloadManager.Request req = DownloadManager.Request(uri);
req.setTitle("Download");
req.setDescription("Kick Ass Description");
req.setVisibility(Request.VISIBILITY_VISIBLE_COMPLETION_ONLY);
Pretty self-explanatory.
I am attempting a download through the DownloadManager. It is calling just fine and seems to initialize just fine. I can see a file is created in my "music" directory and it even starts to grow a bit. Once it gets to around 3-4 MB then the download will cancel and say "download" unsuccessful. This might be because I am downloading from a slow source but it is definitely available. Any ideas on how to not have this quit/timeout. Below is the function that i am using.
In case it is important. I am calling this from an Asynchronous method and I am looping thorough a map that will begin the download of 20 (or so) mp3 files.
Thanks,
Craig
private void download(String strUrl, String fileName){
try {
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(strUrl));
request.setDescription(strUrl);
request.setTitle(fileName);request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_MUSIC,fileName);
// get download service and enqueue file
DownloadManager manager = (DownloadManager) ctx.getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);
} catch (Exception e) {
e.printStackTrace();
Log.i("ERROR: ", e.getCause().getMessage());
}
}
FWIW - I never found a good answer to this question but once I fixed my network it seemed to go away. It still occassionally happens but it is relatively infrequent and appears to be network related.
I'm trying to set an icon for the DownloadManager request that I created, but I can't manage to do that.
I read about creating a BroadcastReceiver, but I was wondering if it's possible to do that without it.
This is my code for the DownloadManager Request:
final String filename = getIntent().getExtras().getString("id") + ".apk";
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setTitle(filename);
request.setDescription("Downloading...");
request.setMimeType("application/vnd.android.package-archive");
// in order for this if to run, you must use the android 3.2 to compile your app
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
}
request.setDestinationInExternalPublicDir("/Library", filename);
// get download service and enqueue file
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);
Toast.makeText(LinkActivity.this, "Download has started.", Toast.LENGTH_LONG).show();
Here's an example of what it looks like now:
My target is to change the image of the notification ImageView on the left.
Thank you very much.
You cannot override this icon. And, if I remember correctly, it would make no much sense to be able to, as download manager can have more than one downloading running and it will still take one notification slot to indicate that...