安卓通知回调

发布于 2024-11-11 02:55:24 字数 1506 浏览 3 评论 0 原文

我在 AsyncTask 上使用本教程以及任务和通知: https://eliasbland.wordpress.com/2011/03/11/an-example-of-how-to-run-a-background-task-and-report-progress-in-the- status-bar-using-asynctask-on-android/

我感到困惑的是如何使回调在调用它的原始类中执行某些操作。最理想的是,有这样的东西会很棒:

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);
        }
}

但是,似乎 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);

由于始终只有一个服务在运行,因此 DownloadService 有一个包含所有 AsyncTasks 的 ArrayList,并且 onStart 检查其中之一是否具有相同的 url 和标题,如果是,它调用 AsyncTask 的方法来取消正在运行的项目或对已完成的项目执行操作。

ArrayList 的计数作为新 DownloaderTasks 的 id 发送,因此每个任务都有一个唯一的 id 来创建其通知,但我注意到有时当我在状态下拉列表中选择通知时,它会使用错误的 url 调用 DownloadService和标题,几乎就像使用另一个通知的 ID 一样?如何解决这个问题?

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-the-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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦罢 2024-11-18 02:55:24

我终于找到了通知不起作用的原因。在我制作的Notification类中,“new PendingIntent”不足以制作新的PendingIntent。如文档中所述:
“如果创建应用程序稍后重新检索相同类型的 PendingIntent(相同操作、相同 Intent 操作、数据、类别和组件以及相同标志),它将接收表示相同令牌的 PendingIntent(如果该令牌仍然有效),因此可以调用 cancel() 来删除它。“它还需要 FLAG_CANCEL_CURRENT,因为它可能会从之前的运行中缓存它。

这段代码的工作原理:

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);

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);
星星的軌跡 2024-11-18 02:55:24

请参阅尝试取消 AsyncTask 执行的 cancel(boolean) 方法。

取消任务:

https://developer.android.com/reference/android/ os/AsyncTask.html

See cancel(boolean) method which attempts to cancel execution of AsyncTask.

Canceling a task:

https://developer.android.com/reference/android/os/AsyncTask.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文