Android服务的问题是操作系统会杀死后台服务,因为它被认为是低优先级,然后以定时间隔重新启动。这可能会在几天内发生多次,每次都会增加重新启动服务之前的时间长度(有些手机只是使用设定的时间,没有增加)。
我的建议是,如果你想要一个永远在线的服务,你需要把它变成一个前台服务。我会给出一些代码示例来说明如何实现这一点,但我不太了解 Xamarin,所以我不想给你任何不好的例子。
另一种方法是使用带有PendingIntent的AlarmManager来检查服务是否正在运行并在未运行时启动它。请注意,如果您经常这样做,可能会导致明显的电池消耗,但如果您不经常这样做,您可能会错过地理围栏事件。
希望这会有所帮助,祝你好运!
更新#1
以下是在前台运行服务和运行 AlarmManager 的代码示例。
前景
这确实是让您的应用程序保持活力的最简单方法。
public class ForegroundService extends Service{
@Override
public int onStartCommand(Intent intent, int flags, int startId){
Notification notification = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.icon)
.setContentTitle("TITLE")
.setContentText("This is an example notification!")
.build();
startForeground(ID, notification);
//Do your stuff here
}
@Override
public void onDestroy(){
super.onDestroy();
stopForeground(true);
//If you have anything else you want done here...
}
}
报警管理器
这将按照您设置的时间间隔(本示例为 10 分钟)不断尝试创建此服务。不过,这里有一些陷阱。首先,由于 Android 6.0 引入了 Doze Mode,AlarmManager 可能不会在手机处于睡眠状态时触发,这意味着该服务可能会死掉一段时间。其次,这是onStartCommand
多次调用该函数,因此您需要逻辑来处理它。
public class AlwaysOnService extends Service{
@Override
public int onStartCommand(Intent intent, int flags, int startId){
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
PendingIntent pi = PendingIntent.getService(this, requestCode, new Intent(this, AlwaysOnService.class), PendingIntent.FLAG_UPDATE_CURRENT);
am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + MIN_10_IN_MILLIS, pi);
//Do your stuff here
return START_STICKY;
}
@Override
public void onDestroy(){
super.onDestroy();
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
PendingIntent pi = PendingIntent.getService(this, requestCode, new Intent(this, AlwaysOnService.class), PendingIntent.FLAG_NO_CREATE);
if(pi != null){
am.cancel(pi);
pi.cancel();
}
//If you have anything else you want done here...
}
}
在这两者中,将服务设置为前台服务可能是最简单的事情,除非你真的不能拥有,否则 AlarmManager 是采取的路线。