android - 后台提醒通知 - Android
问题描述
我正在尝试创建提醒通知,但在后台服务中,但我有很多问题。让我们从基础开始。我想用 MainAcitivity 和重启设备后启动后台服务。我在 MainAcivitiy 中添加了 onCreate:
Intent StartBackgroundService = new Intent(getApplicationContext(), StartBackgroundService.class);
sendBroadcast(StartBackgroundService);
所以我使用StartBackgroundService 扩展 BroadcastReceiver作为启动后台进程的东西,并且在onReceive中我正在启动后台服务。
起初我创建了BackgroundWorker extends Service并且在onStartCommand中我想管理我的后台进程。
它工作得很好,但看起来从 Android Oreo开始,即使你添加到清单, BroadcastReceiver也无法启动后台服务:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.QUICKBOOT_POWERON" />
<application
//....... code
<receiver android:name=".StartBackgroundService">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
所以,我检查了我可以为后台服务做什么,我可以使用前台服务或 WorkManager,但看起来我应该使用 WorkManager,所以我已经尝试过了。
所以,再次:在 MainAcitity onCreate 我发送到 BroadcastReceiver 消息以启动后台服务:
Intent StartBackgroundService = new Intent(getApplicationContext(), StartBackgroundService.class);
sendBroadcast(StartBackgroundService);
StartBackgroundService看起来像这样:
public class StartBackgroundService extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent)
{
if(!BackgroundWorker.isServiceStarted) {
BackgroundWorker.isServiceStarted = true;
WorkRequest backgroundWorker =
new OneTimeWorkRequest.Builder(BackgroundWorker.class)
.build();
WorkManager
.getInstance(context)
.enqueue(backgroundWorker);
}
}
}
最后是 BackgroundWorker:
public class BackgroundWorker extends Worker {
static boolean isServiceStarted = false; //flag to prevent running background process twice
Context context;
public BackgroundWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
this.context = context;
}
@NonNull
@Override
public Result doWork() {
backgroundProcess();
return Result.success();
}
public void backgroundProcess(){
//Code for background process:
//Load from database time
//Check time changed since last change
//if not -> skip to sleep
//if true -> clear all set notifications alarms
//send notification at specific time from db
//....
//if notoifction was sent, change flag for getting time from db to another
//and then sleep and open function again as below
SystemClock.sleep(10000);
backgroundProcess();
}
@Override
public void onStopped() {
BackgroundWorker.isServiceStarted = false;
Intent backgroundWorker = new Intent(getApplicationContext(), StartBackgroundService.class);
context.sendBroadcast(backgroundWorker);
super.onStopped();
}
}
因此,从Service更改为Worker有助于在重新启动设备后在后台启动进程。是的,它有效,但我还有另一个问题。当我打开应用程序时,后台进程启动,但是当我单击“概述”按钮并从上次使用的应用程序中删除我的应用程序时,后台进程停止。看起来它在 10-12 秒后启动,但是当我再次打开应用程序时,后台进程再次启动,因此有两个线程在后台工作(因此忽略标志 BackgroundWorker.isServiceStarted)。我在使用服务时没有遇到这样的问题,但是重启设备后我无法打开后台进程,因此需要打开应用程序。
我应该为此使用前台服务吗?(我讨厌这个,因为这整个时间都是活动的通知,并且由于例如电池使用情况而不确定我是否应该将它用于我的问题)。有没有其他方法可以满足我的需求?我想实现类似于谷歌日历的东西。重新启动后您无需打开应用程序,或者您可以将其从上次使用的应用程序中删除,当您由于日历事件而应该获得剩余时,它仍会向您发送通知。
解决方案
推荐阅读
- android - 您可以测量尚未加载的活动的视图高度吗?
- python - 为什么我的函数不会返回变量值并在 python 中更新它们?
- botframework - 对话完成后,我们如何将与机器人(使用 Microsoft Power Apps 构建)的对话发送到他的 Outlook 电子邮件?
- c - 不知何故,我让它执行而不会崩溃,我该如何打印它?
- heroku - 我在我的 Discord 机器人中使用 Quick.db。每次我部署更新时,数据库都不会保存,为什么会这样,我该如何解决?
- sql - 将本机 SAS 日期时间转换为 oracle
- c# - 为什么我的列表对象添加功能不起作用?
- javascript - 我如何访问 GeoJson 中的几何图形
- snowflake-cloud-data-platform - INFORMATION_SCHEMA.TABLES 访问所有模式和表
- javascript - Discord.js 清除命令不接受数字