首页 > 解决方案 > 后台提醒通知 - 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)。我在使用服务时没有遇到这样的问题,但是重启设备后我无法打开后台进程,因此需要打开应用程序。

我应该为此使用前台服务吗?(我讨厌这个,因为这整个时间都是活动的通知,并且由于例如电池使用情况而不确定我是否应该将它用于我的问题)。有没有其他方法可以满足我的需求?我想实现类似于谷歌日历的东西。重新启动后您无需打开应用程序,或者您可以将其从上次使用的应用程序中删除,当您由于日历事件而应该获得剩余时,它仍会向您发送通知。

标签: androidandroid-serviceandroid-workmanager

解决方案


推荐阅读