Android KitKat 4.4杀死了由Alarm Manager监视的我的服务

时间:2014-01-04 11:45:17

标签: android service alarmmanager android-4.4-kitkat kill-process

Android KitKat和Alarm Manager存在很大问题。

我的所有应用都使用一种始终在后台运行而不会杀死Android的服务。

在Android 4.4 KitKat之前,我发现解决方案是通过AlarmManager触发的BroadcastReceiver启动服务。

...

Intent intent = new Intent(c, MyReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(c, 0, intent, PendingIntent.FLAG_ONE_SHOT);
        AlarmManager am = (AlarmManager) c.getSystemService(Context.ALARM_SERVICE);

        if (Build.VERSION.SDK_INT<Build.VERSION_CODES.KITKAT) {
            am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), pendingIntent);
        } else {
            setAlarmFromKitkat(am, System.currentTimeMillis(), pendingIntent);
        }
...




@TargetApi(19)
    private static void setAlarmFromKitkat(AlarmManager am, long ms, PendingIntent pi){
        am.setExact(AlarmManager.RTC_WAKEUP, ms, pi);
    }

...


public class MyReceiver extends BroadcastReceiver {

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

            Intent service = new Intent(context, MyService.class);
            context.startService(service);
     }

}

在Android 4.4 KitKat上通过这个解决方案,我可以开始服务,但是经过一段时间Android杀了它!

有没有办法在不使用Android 4.4 KitKat的情况下使用后台工作的服务?

非常感谢

2 个答案:

答案 0 :(得分:1)

Android Kitkat版

如果您的应用使用AlarmManager ...

当您将应用的targetSdkVersion设置为“19”或更高时,使用set()或setRepeating()创建的警报将不准确。

为了提高电源效率,Android现在将来自所有应用程序的警报批处理混合,这些警报发生在相当类似的时间,因此系统会唤醒设备一次,而不是多次处理每个警报。

如果您的闹钟与确切的时钟时间无关,但在特定时间范围内(例如下午2点到下午4点之间)调用闹钟仍然很重要,那么您可以使用新的setWindow()方法,在系统应该调用警报的最早时间之后接受警报的“最早”时间和“窗口”时间。

如果您的闹钟必须固定到确切的时钟时间(例如日历事件提醒),那么您可以使用新的setExact()方法。

这种不精确的批处理行为仅适用于更新的应用程序。如果您将targetSdkVersion设置为“18”或更低,则在Android 4.4上运行时,您的警报将继续像以前的版本一样。

原始资料来源: http://developer.android.com/about/versions/android-4.4.html

答案 1 :(得分:1)

在kitkat中,使用下面的代码段自动重启te服务:

@Override
public void onTaskRemoved(Intent rootIntent) {
    // TODO Auto-generated method stub
    Intent restartService = new Intent(getApplicationContext(),
            this.getClass());
    restartService.setPackage(getPackageName());
    PendingIntent restartServicePI = PendingIntent.getService(
            getApplicationContext(), 1, restartService,
            PendingIntent.FLAG_ONE_SHOT);
    AlarmManager alarmService = (AlarmManager)getApplicationContext().getSystemService(Context.ALARM_SERVICE);
    alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() +1000, restartServicePI);

}