Solution: API 11 is needed see answer below!
Easy Question: After downloading a File with the implemented DownloadManager the Notification disappears. How do I force the Notification to stay after Download?
I tried to use VISIBILITY_VISIBLE_NOTIFY_COMPLETED, but i do not know how i can use it
Thank for any kind of help to solve this problem ;)
EDIT: Code
public class BgDL extends Activity {
private DownloadManager mgr = null;
private long id;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);
mgr = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
Request request = new Request(Uri.parse(getIntent().getStringExtra("URL")));
id = mgr.enqueue(request
.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "UPDATE")
.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI|DownloadManager.Request.NETWORK_MOBILE)
.setAllowedOverRoaming(false)
.setTitle("APP update")
.setDescription("New version "+getIntent().getDoubleExtra("OV", 0.0))
);
registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}
BroadcastReceiver receiver = new BroadcastReceiver () {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(mgr.ACTION_DOWNLOAD_COMPLETE) ){
unregisterReceiver(receiver);
finishActivity(99);
}
}
};
}
Add the correct flag to your request:
Request request = new Request(Uri.parse(getIntent().getStringExtra("URL")));
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
Reference:
http://developer.android.com/reference/android/app/DownloadManager.Request.html#setNotificationVisibility(int)
Control whether a system notification is posted by the download manager while this download is running or when it is completed. If enabled, the download manager posts notifications about downloads through the system NotificationManager. By default, a notification is shown only when the download is in progress.
http://developer.android.com/reference/android/app/DownloadManager.Request.html#VISIBILITY_VISIBLE_NOTIFY_COMPLETED
This download is visible and shows in the notifications while in progress and after completion.
Related
Here i used DownloadManger to download and it will show the progress in Notification bar
DownloadManager.Request request = new DownloadManager.Request(uri);
request.setTitle("Data Download");
//Setting description of request
request.setDescription("Android Data download using DownloadManager.");
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
registerReceiver(downloadReceiver, filter);
Broadcast receiver to receive click action(DownloadManager.ACTION_NOTIFICATION_CLICKED) during downloading and the action is working during download
private BroadcastReceiver downloadReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (DownloadManager.ACTION_NOTIFICATION_CLICKED.equals(action))
{
startActivity(new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS));
}
}
};
but after download DownloadManager.ACTION_NOTIFICATION_CLICKED is not working to redirect to downloads app.
Can any one help me how can i redirect after clicking on DownloadManger notification(after complete download) to downloads app ????????????
This is the code I'm currently using
String iosjiUrl = "http://modapps.com/NotoCoji.ttf";
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(iosjiUrl));
request.setDescription("Sscrition");
request.setTitle("Somle");
// 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(Environment.DIRECTORY_DOWNLOADS, "NotoColorji.ttf");
// get download service and enqueue file
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);
I'm not able to find a way for me to wait until the file is downloaded.
I also tried figuring out how to go about doing ASync but couldn't figure that out either =/
Thanks again!
Use a BroadcastReceiver to detect when the download finishes:
public class DownloadBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
//Show a notification
}
}
}
and register it in your manifest:
<receiver android:name=".DownloadBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>
</intent-filter>
</receiver>
A Broadcast intent action sent by the download manager when a download completes so you need to register a receiver for when the download is complete:
To register receiver
registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
and a BroadcastReciever handler
BroadcastReceiver onComplete=new BroadcastReceiver() {
public void onReceive(Context ctxt, Intent intent) {
// your code
}
};
You can also create AsyncTask to handle the downloading of big files
Create a download dialog of some sort to display downloading in notification area and than handle the opening of the file:
protected void openFile(String fileName) {
Intent install = new Intent(Intent.ACTION_VIEW);
install.setDataAndType(Uri.fromFile(new File(fileName)),"MIME-TYPE");
startActivity(install);
}
you can also check the sample link
sample
I've created a BroadcastReceiver to receive ACTION_DOWNLOAD_COMPLETE when my app starts downloading something using DownloadManager. As I want to capture ACTION_DOWNLOAD_COMPLETE only when downloading is started from my app, I've used LocalBroadcastManager.
But onReceiver is not being called at all. DownloadManager app shows that download is complete but onReceive is not triggered. When I use registerReceiver it works as expected. But this would let app being notified even if downloading is started by some other app. So LocalBroadcastManager is desired.
MainActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
downloadReceiver = new DownloadReceiver();
LocalBroadcastManager.getInstance(this).registerReceiver(downloadReceiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
if(FileHelper.isStorageAvailable()) {
DownloadManager.Request request = new DownloadManager.Request(Uri.parse("http://example.com/image.jpg"));
downloadManager.enqueue(request);
}
}
#Override
protected void onPause() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(downloadReceiver);
super.onPause();
}
DownloadReciever
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(downloadId);
Cursor c = downloadManager.query(query);
if (c.moveToFirst()) {
int columnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS);
if (DownloadManager.STATUS_SUCCESSFUL == c.getInt(columnIndex)) {
String title = c.getString(c.getColumnIndex(DownloadManager.COLUMN_TITLE));
Toast.makeText(context, title, Toast.LENGTH_SHORT).show();
}
}
}
}
It simply don't call onRecieve as it should. Point out if I'm doing something wrong here. Been stuck here for quite time now. I can't use registerReceiver as I need to track download complete action only if my app starts downloading.
As I want to capture ACTION_DOWNLOAD_COMPLETE only when downloading is started from my app, I've used LocalBroadcastManager.
That is not going to work. DownloadManager does the download in a separate process, and it will use a system broadcast. The only broadcasts that you can receive via LocalBraodcastManager are the ones that you broadcast via LocalBroadcastManager.
I am using Android DownloadManager to download some file say of XMB if DownloadManager completes download it will send broadcast of action android.intent.action.DOWNLOAD_COMPLETE in normal scenario.
My question is what if the internet connection gets lost in between. Will it send any broadcast? Same case in between if server stops serving what DownloadManager does. Maybe its silly question, I have very small file so I am unable to test this scenario.
Could some one tell me what DownloadManager does in these kind of scenarios?
The broadcast will be sent. You need to check the status of DownloadManager to determine if it was successful. For example:
private DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
Query query = new Query();
query.setFilterById(enqueue);
Cursor c = dm.query(query);
if (c.moveToFirst()) {
int columnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS);
if (DownloadManager.STATUS_SUCCESSFUL == c.getInt(columnIndex)) {
// handle data
} else if (DownloadManager.STATUS_FAILED == c.getInt(columnIndex)) {
// handle error
}
}
}
}
};
For a full example, see: this link. For ways to determine the reason of the failure, see this link.
Courtesy : Android DownloadManager Example
I register my receiver for DownloadManager.ACTION_DOWNLOAD_COMPLETE broadcast only. This is invoked only when the download is successfully completed
Follow this three steps
Create a BroadcastReceiver as shown in snippet below.Inside the receiver we just check if the received broadcast is for our download by matching the received download id with our enqueued download.
private BroadcastReceiver onDownloadComplete = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//Fetching the download id received with the broadcast
long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
//Checking if the received broadcast is for our enqueued download by matching download id
if (downloadID == id) {
Toast.makeText(MainActivity.this, "Download Completed", Toast.LENGTH_SHORT).show();
}
}
};
Once the BroadcastReceiver is created you can register for ACTION_DOWNLOAD_COMPLETE in the onCreate method of your activity.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
registerReceiver(onDownloadComplete,new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}
It is also important that you unregister the BroadcastReceiver in onDestroy. This ensures you only listen for this broadcast as long as the activity is active
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(onDownloadComplete);
}
Complete example here
I am writing an application targeting API level 9 or higher. So, i
have decided to go with DownloadManager Class that SDK offers.
My question is 2 part -
1. When i am downloading a single file, how do i display the progress
of the download. I see i can get COLUMN_TOTAL_SIZE_BYTES and
COLUMN_BYTES_DOWNLOADED_SO_FAR from the querying the download manager
instance. But i am not sure if i have to put the query in a thread and
implement a loop so that i can poll regularly to update the progress
bar. I guess, i am not sure, how to query regularly - will it go in
the main thread or be implemented as a runnable - the mechanism i am
not clear.
2. If i have to support multiple file downloads, then do i have to
launch each one of them in it's own thread?
Thanks.
If you are building on 2.3 and above you don't need to, it automatically displays it in the status bar. Do it like this,
Code from commonsware,
private static final int DOWNLOAD_SUCCESSFUL = 100;
private static final int DOWNLOAD_FAILED = 99;
private DownloadManager mgr=null;
on create do this,
`mgr = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
registerReceiver(onComplete,
new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
`
Then on the click event of the file download,
lastDownload =
mgr.enqueue(new DownloadManager.Request(uri)
.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI |
DownloadManager.Request.NETWORK_MOBILE)
.setAllowedOverRoaming(false)
.setTitle("Test File")
.setDescription("Download zipped file.")
.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS,
file_name));
And then a broadcast receiver for when your donwnload compeletes,
BroadcastReceiver onComplete=new BroadcastReceiver() {
public void onReceive(Context ctxt, Intent intent) {
findViewById(R.id.start).setEnabled(true);
File unzipFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),file_name);
//check for new file download
//extract if it's a new download
if (unzipFile.exists()) {
new UnzipFile().execute();
} else {
Toast.makeText(Main.this, "Download not found!", Toast.LENGTH_LONG).show();
}
}
};`