如何在不停止的情况下每分钟运行一个Jobcheduler或Service?

时间:2017-11-10 13:45:55

标签: android service periodic-task

我正在做一个Android应用程序,需要经常发送它的位置,最多每1分钟或2分钟。为此,我使用JobSchedulerService。我已设法通过将Android N version替换为.setPeriodic(),在.setMinimumLatency()的设备上每15分钟运行一次。事实上,它在开始时会在规定的时间内定期执行,但过了一段时间它会大约每7或9分钟运行一次。

我已将该应用程序包含在省电白名单中,但无效。有没有办法每分钟执行它或类似的服务没有任何限制?无论应用花费多少电池都无关紧要。

修改

这是我尝试过的:

ReceiverService:

public class ReceiverService extends WakefulBroadcastReceiver {

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

    if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
        if (!isMyServiceRunning(ServiceBackground.class, ctx))
            startWakefulService(ctx, new Intent(ctx, ServiceBackground.class));

        new ServiceAlarmManager(ctx).register();
    }

}

private boolean isMyServiceRunning(Class<?> serviceClass,Context context) {
    ActivityManager manager = (ActivityManager)context. getSystemService(Context.ACTIVITY_SERVICE);
    for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
        if (serviceClass.getName().equals(service.service.getClassName())) {
            Log.i("Service already","running");
            return true;
        }
    }
    Log.i("Service not","running");
    return false;
}

}

ServiceAlarmManager与@madking说完全相同。

2 个答案:

答案 0 :(得分:1)

您可以将代码发送到Service并执行AlarmManager,定期检查Service是否正在运行,如果Service已经运行,则重新启动它被OS杀死。您必须使用AlarmManager来实施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);

}
}

同时在BroadcastReceiver文件

中注册Manifest.xml
<receiver android:name=".ReceiverService">
        <intent-filter>
            <action android:name="someString" />
        </intent-filter>
    </receiver>

register()方法做了两件事。

1-发布由WakefulBroadcastReceiver捕获的广播,并在需要时重新启动Service

2-设置要调用的下一个警报,以检查Service是否已被杀死。

这样,即使操作系统杀死了服务,服务也会继续运行,并且您可以定期发送位置更新。

注意:虽然不推荐这种做法,因为您的应用程序将使用更多电池,但您似乎并不关心它,因为我没有,因为某些业务要求不会让我们做出选择。

答案 1 :(得分:0)

我试过这个并且它有效:在你的活动的onCreate()中,你为每分钟安排一个警报(setAlarm)。每次触发警报时,都会调用WakefulBroadcastReceiver,以及我们启动服务的地方:

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);
} 

在接收器中:

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

}

在您的服务中,您应该在治疗结束时停止医疗()。

不要忘记在Manifest.xml文件中注册BroadcastReceiver

注意:WakefulBroadcastReceiver在API级别26.1.0中已弃用。 JobSchedulerService完成工作