当我的应用程序在后台时如何显示通知?
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 已执行。我尝试搜索它并了解 BroadcastReceiver , JobScheduler 和 FirebaseJobDispatcher 但我不能真正了解他们以及他们如何提供帮助。
那么,我走在正确的轨道上吗?即使应用程序进入后台,我如何实现相同的功能?
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 已关闭但通知尚未关闭。
同样,这只是针对这种特定情况的一种变通方法,它导致我在许多地方传递输入变量,因此它在性能方面可能不如其他选项有效。
我正在尝试构建一个具有 -
的 Android 应用程序一个第一个Activity(启动器activity)
还有一个第二个Activity
我想要达到的目标:
First Actvity 从用户获取输入,使用 AsyncTaskLoader 从 Web 获取数据。 在 onLoadFinished 它检查输入是否有效以及是否启动 Intent to Second Activity 以显示更多详细信息。输入也与 Intent 一起传递。
由于网络操作可能需要时间,因此我决定在创建第二个 Activity 之前使用 IntentService 显示通知,即通知正在 onLoadFinished 就在 Intent 之前。如果第二个 Activity 尚未启动,则通知应直接启动。
什么工作正常:
两个活动和加载器都工作正常。通知也正在显示,一切都按预期工作,前提是用户保留该应用程序 运行 .
什么不是:
当用户在加载数据时离开 First Activity 时,不会显示通知,因为 onPause 已执行。我尝试搜索它并了解 BroadcastReceiver , JobScheduler 和 FirebaseJobDispatcher 但我不能真正了解他们以及他们如何提供帮助。
那么,我走在正确的轨道上吗?即使应用程序进入后台,我如何实现相同的功能?
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 类似于
同样,这只是针对这种特定情况的一种变通方法,它导致我在许多地方传递输入变量,因此它在性能方面可能不如其他选项有效。