繁体   English   中英

后台任务 Android Java,每 X 秒永久

[英]Backgroundtask Android Java, permanent every X seconds

直到现在,我一直使用“AlertManager”来执行后台任务。 这不再适用于新的 Android 版本。 它必须每 15 秒启动一次,并且在任何情况下都不能被系统停止。 当手机重新启动时,后台任务也必须启动。 现在后台任务只启动一次,然后就什么都没有发生了。

有解决办法吗?

这就是我计划任务的方式:

MainActivity.java

AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent startServiceIntent = new Intent(context, hintergrundModus.class);
PendingIntent startServicePendingIntent = PendingIntent.getService(context,0,startServiceIntent,0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
if(alarmManager != null)
alarmManager.set(AlarmManager.RTC_WAKEUP,hintergrundModus.timeHintergrundmodus,startServicePendingIntent);

对于 Android 的较新版本,您需要将androidx.core.app.JobIntentService IntentService (并且不要忘记删除IntentService#onBind(Intent)的实现,否则您的服务将永远不会启动)

class hintergrundModus extends IntentService

    @Override
    protected IBinder onBind(Intent arg0) { 
        return null
    }

    @Override
    protected void onHandleIntent(Intent arg0) {    
        ...
    }
}

会变成

import androidx.core.app.JobIntentService;

class hintergrundModus extends JobIntentService {

    @Override
    public void onHandleWork(Intent arg0) {
        ...
    }
}

对于AlarmManager ,您也将不再使用PendingIntent#getService直接调用您的服务,而是创建一个中介BroadcastReceiver然后可以在调用时将您的工作排入队列。

import static androidx.core.app.JobIntentService.enqueueWork;

public class ServiceLaunchReceiver extends BroadcastReceiver {

    public static final String RECEIVER_KEY = "com.package.ACTION";
    public static final int UNIQUE_JOB_ID = 0;

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(RECEIVER_KEY)) {
            enqueueWork(context, hintergrundModus.class, UNIQUE_JOB_ID , intent);
        }
    }
}

然后可以通过PendingIntent#getBroadcast引用

Intent launcherReceiverIntent = new Intent(context, ServiceLaunchReceiver.class);
PendingIntent startServicePendingIntent = PendingIntent.getBroadcast(context, 0, launcherReceiverIntent, 0);

如果需要重复的计时精度,您可能还想研究在运行 API 19 或更高版本的设备上使用AlarmManager#setExactAlarmManager#setExactAndAllowWhileIdle 然后,您可以在JobIntentService中的工作完成后安排后续警报,而不是安排重复警报。 来自关于AlarmManager#set的注释:

从API 19开始,传递给该方法的触发时间被认为是不准确的:在此时间之前不会发送警报,但可能会延迟并在一段时间后发送。

您还会发现 Android 的较新版本在终止后台应用程序方面可能非常激进。 由于您的服务似乎是短暂的,因此将其绑定到前台通知(通过startForeground(Int, Notification) )可能对您不起作用。 在这种情况下,您可能需要在运行时向用户请求电池优化排除,以避免系统限制。

最后,在用于侦听系统启动通知的BroadcastReceiver中,实现上述代码以将新的JobIntentService排队,或安排第一个警报以将其推迟到以后。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM