I'm using this tutorial on AsyncTask with a task and a notification: https://eliasbland.wordpress.com/2011/03/11/an-example-of-how-to-run-a-background-task-and-report-progress-in-t开发者_StackOverflow社区he-status-bar-using-asynctask-on-android/
What I'm confused about is how to make a callback do something in the original class it was called from. Optimally, it would be great to have something like:
private class DownloaderTask extends AsyncTask {
doInBackground() { ... download the file ... }
onProgressUpdate, onPreExecute, etc. from the example, managing a notification.
notificationClicked() {
if (success) {
//show file
} else {
cancel(true);
}
}
however, it seems the PendingIntent is made to open a new intent, not call a function on the class that opened it? Is there any way to do this?
EDIT: Ok, I found out how to call the calling service from pendingintent:
Intent returnIntent = new Intent(_context,DownloadService.class);
returnIntent.putExtra("url", _url);
returnIntent.putExtra("name",_title);
notificationIntent = PendingIntent.getService(_context, 0, returnIntent, 0);
notification.setLatestEventInfo(_context, _title, _url, notificationIntent);
Since there is always only one service running, the DownloadService has an ArrayList of all its AsyncTasks, and onStart checks to see if one of them has the same url and title, if so, it calls the AsyncTask's method to cancel running item or do action on completed item.
The count of the ArrayList is sent as the id of new DownloaderTasks, so each one will have a unique id to create its notification, but I noticed that sometimes when I select a notification in the status dropdown, it calls the DownloadService with the wrong url and title, almost like it's using another notification's ID? How can this be fixed?
I finally found why the notification wasn't working. In the Notification class I made, "new PendingIntent" is not enough to make a new PendingIntent. As described in the documentation: "If the creating application later re-retrieves the same kind of PendingIntent (same operation, same Intent action, data, categories, and components, and same flags), it will receive a PendingIntent representing the same token if that is still valid, and can thus call cancel() to remove it. " It also needs FLAG_CANCEL_CURRENT since it may have it cached from a previous run.
This code works:
Intent returnIntent = new Intent(_context,DownloadService.class);
returnIntent.putExtra("url", _url);
returnIntent.putExtra("name",_title);
returnIntent.putExtra("notifClick",true);
returnIntent.setAction("test.test.myAction"+_NOTIFICATION_ID);
// Important to make a unique action name, and FLAG_CANCEL_CURRENT, to make separate notifications.
notificationIntent = PendingIntent.getService(_context, 0, returnIntent, PendingIntent.FLAG_CANCEL_CURRENT);
See cancel(boolean)
method which attempts to cancel execution of AsyncTask.
Canceling a task:
https://developer.android.com/reference/android/os/AsyncTask.html
精彩评论