当我的应用程序在后台时如何显示通知?

How to display a notification when my application is in background?

我正在尝试构建一个具有 -

的 Android 应用程序

一个第一个Activity启动器activity

还有一个第二个Activity

我想要达到的目标:

First Actvity 从用户获取输入,使用 AsyncTaskLoader 从 Web 获取数据。 在 onLoadFinished 它检查输入是否有效以及是否启动 Intent to Second Activity 以显示更多详细信息。输入也与 Intent 一起传递。

由于网络操作可能需要时间,因此我决定在创建第二个 Activity 之前使用 IntentService 显示通知,即通知正在 onLoadFinished 就在 Intent 之前。如果第二个 Activity 尚未启动,则通知应直接启动。

什么工作正常:

两个活动和加载器都工作正常。通知也正在显示,一切都按预期工作,前提是用户保留该应用程序 运行 .

什么不是:

当用户在加载数据时离开 First Activity 时,不会显示通知,因为 onPause 已执行。我尝试搜索它并了解 BroadcastReceiverJobSchedulerFirebaseJobDispatcher 但我不能真正了解他们以及他们如何提供帮助。

那么,我走在正确的轨道上吗?即使应用程序进入后台,我如何实现相同的功能?

P.S。代码比问题提示的要庞大得多,所以我没有包含它。这就是为什么如果解释似乎不完整或混乱我会尽力澄清你的疑惑。

是的。你走在正确的轨道上。

这是我制作的地图下载器的示例。我希望你不介意,但由于你没有给出上下文,我必须找到一个合适的例子。

/**
* @param entry the map entry to be downloaded
* @return returns a receiver that unzips the map file after downloading
*/
private BroadcastReceiver createMapReceiver(MapEntry entry) {
     return new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
             unregisterReceiver(this); // we unregister this receiver after the download is complete
             receiveDownloadedFile(entry); // once we receive the map file, we run this function, but you can do whatever you want. This is the part of the code youn were asking for
         }
     };
}


void downloadMap() {

    // preparing the download
    BroadcastReceiver receiver = createMapReceiver(entry); // see function above

  DownloadManager manager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
  registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));

  String downloadURL = fileListURL + entry.getFileName() + fileExtension; // building the url for the map
  DownloadManager.Request request = new DownloadManager.Request(Uri.parse(downloadURL));

  if (manager != null) {
      manager.enqueue(request
              .setDestinationUri(Uri.fromFile(new File(areaFolder, entry.getFolderName())))
                    .setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI|DownloadManager.Request.NETWORK_MOBILE)
                    .setAllowedOverRoaming(false)
                    .setTitle("Some title, preferably taken from Strings.xml")
                    .setDescription("Some Description")
                    .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
            );
        } else {
            // if we couldn't find the DownloadManager
            onFailure(entry); // we simply run some onFailure function
        }

    }

不要忘记权限。

通过 LocalBroadcastManager 注册广播接收器,并定义过滤器。现在,根据过滤器,您可以使用 UI 个元素或意图。

IntentFilter filter = new IntentFilter();
    filter.addAction("A");
    filter.addAction("B");
    filter.addAction("C");
    LocalBroadcastManager.getInstance(getContext()).registerReceiver(dummyReceiver, filter);



private BroadcastReceiver dummyReceiver = new BroadcastReceiver() {
@Override
    public void onReceive(final Context context, final Intent intent) {
          //Do your work**
 }}

试试这个。我已经实现了这个并且它有效。

how can I achieve the same functionality even if app goes into background

使用bound services or intent services。 意图服务允许您异步执行操作。 绑定服务可以使用 aidl 提供接口。只要服务是绑定的,它就不太可能被销毁。有多种使用标志绑定服务的方法。

恕我直言,activity只是一种显示方式UI。如果您需要任何后台工作,请使用服务。 通过 aidl 使用绑定服务时,您必须扩展 service connection。绑定后会从服务接收接口

我终于在不使用 BroadcastReciever 或服务的情况下实现了它,因此不熟悉它们的人可以从中参考,但 请自行决定使用它 因为服务和接收者是推荐的方式。

@Override
public void deliverResult(Data data) {
    super.deliverResult(data);
    showNotification(input);
}

这是AsyncTaskLoader中获取数据后触发的方法。覆盖它并更改响应通知单击的通知方法。

private PendingIntent onClick(Context context) {
     return PendingIntent.getActivity(context, 0, new Intent(context, ExtraActivity.class).
putExtra(Intent.EXTRA_TEXT,input),PendingIntent.FLAG_UPDATE_CURRENT);
}

ExtraActivity 类似于 。它允许您的通知响应,即使 activity 已关闭但通知尚未关闭。

同样,这只是针对这种特定情况的一种变通方法,它导致我在许多地方传递输入变量,因此它在性能方面可能不如其他选项有效。