I have a Notification that has a Progress Bar
and a Cancel
button. I am using Thread to increment the Progress Bar and the Cancel button is supposed to clear the notification.
Here's the code for Notification
remoteViews = new RemoteViews(getPackageName(), R.layout.customnotification);
Intent intent = new Intent(this, LocationBroadcastReceiver.class);
intent.putExtra("CancelServiceAndNotification","CancelServiceAndNotification");
intent.putExtra("ID",1);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getBaseContext(),
0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.bCancel, pendingIntent);
Code for incrementing Progress Bar using Thread
thread = new Thread(new Runnable() {
@Override
public void run() {
int incr;
for(incr = 0;incr<=100;incr+=10){
remoteViews.setProgressBar(R.id.progressBar, 100, incr, false);
if(cancelNotification){
}
notificationManager.notify(1,notification);
try{
Thread.sleep(1000);
}
catch (Exception e){
}
}
notificationManager.cancel(1);
}
});
thread.start();
In Broadcast Receiver, I am trying to cancel the notification using
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(ID);
The problem is that when I click on Cancel
button the notification disappear for a second but then appear again, may be due to the thread still running. How to destroy the thread from broadcast Receiver class? What should I do to remove the notification on cancel
button click ?
To stop the thread you should interrupt it, for example when receiving "CancelServiceAndNotification" in your BroadcastReceiver
you can call :
thread.interrupt();
Then, in your run() method :
if (Thread.currentThread().isInterrupted()) {
// we were interrupted, should stop immediately
return;
}
If thread is interrupted while sleeping it will throw InterruptedException
and clear interrupted flag, so in your case it is very important that you return from run()
when catching InterruptedException
:
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// we were interrupted, should stop immediately
return;
}
And you should cancel notification the same way you do :
// make sure you pass 1 as id here as you use it for notify()
notificationManager.cancel(1);
That should work.
However, it is strongly not recommended to update UI from non-main thread (which you do from you custom thread when calling remoteViews.setProgressBar
).
I recommend using custom AsyncTask
for doing background job in doInBackground
(instead of your run()
method and updating progress of your notification in its onProgressUpdate
.
You can cancel AsyncTask
by calling cancel()
on it in a similar way you interrupt()
a thread as shown above.
Hope that helps.