How to run a Jobscheduler or a Service every minute wihout stopping?

社会主义新天地 提交于 2019-12-08 12:54:28

You can put your code that sends location in a Service and implement an AlarmManager that periodically checks if your Service is running and restarts it if the Service has been killed by OS. You'll have to implement the AlarmManager using a WakefulBroadcastReceiver.

ReceiverService.java

public class ReceiverService extends WakefulBroadcastReceiver {

@Override
public void onReceive(Context ctx, Intent intent) {

    if (!YourService.isRunning()) {
        startWakefulService(ctx, new Intent(ctx, YourService.class));
    }

    new ServiceAlarmManager(ctx).register();
}
}

ServiceAlarmManager.java

public class ServiceAlarmManager {

private Context ctx;
private static final int TIME_INTERVAL = 300 * 1000;

public ServiceAlarmManager(Context context) {
    ctx = context;
}

public void register() {

    Intent serviceRestarter = new Intent();
    serviceRestarter.setAction("someString");

    PendingIntent pendingIntentServiceRestarter = PendingIntent.getBroadcast(ctx, 0, serviceRestarter, 0);
    AlarmManager alarmManager = (AlarmManager) ctx.getSystemService(ctx.ALARM_SERVICE);
    Date now = new Date();
        alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, now.getTime() + TIME_INTERVAL, pendingIntentServiceRestarter);

}
}

Also register your BroadcastReceiver in your Manifest.xml file

<receiver android:name=".ReceiverService">
        <intent-filter>
            <action android:name="someString" />
        </intent-filter>
    </receiver>

The register() method does two things.

1- Issues a broadcast which is caught by WakefulBroadcastReceiver and restarts the Service if required

2- Sets the next alarm to be invoked to check if the Service has been killed.

This way the service keeps running even if the OS kills it and you'll be able to send location updates periodically.

Note: Though this practice is not recommended as your application will use more battery but you don't seem to care about it as I did not either as some business requirements don't leave us a choice.

I tried this and it works: in the onCreate() of your activity you schedule an Alarm for every minute (setAlarm). Everytime the alarm is triggered, WakefulBroadcastReceiver is called, and that's where we launch our service(s):

private static long INTERVAL_ALARM = 1 * 60 * 1000;

public static void setAlarm(Context context) {
    long current_time = Calendar.getInstance().getTimeInMillis();
    Intent myAlarm = new Intent(context.getApplicationContext(), AlarmReceiver.class);
    PendingIntent recurringAlarm = PendingIntent.getBroadcast(context.getApplicationContext(), 0, myAlarm, PendingIntent.FLAG_CANCEL_CURRENT);
    AlarmManager alarms = (AlarmManager) context.getApplicationContext().getSystemService(Context.ALARM_SERVICE);
    alarms.setRepeating(AlarmManager.RTC_WAKEUP, current_time, INTERVAL_ALARM, recurringAlarm);
} 

And in the receiver:

public class AlarmReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
        Intent myService = new Intent(context, MyService.class);
        context.startService(myService);
    }

}

In your service, you should stopSeflf() in the end of your treatment.

Don't forget to register your BroadcastReceiver in your Manifest.xml file

NB: WakefulBroadcastReceiver is deprecated in API level 26.1.0. JobSchedulerService does the work

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!