Android 服务的问题在于,操作系统会终止后台服务,因为它被认为是低优先级,然后按时间间隔重新启动。这可能会在几天内发生多次,每次都会增加重新启动服务之前的时间长度(有些手机只是使用设定的时间,没有增加)。
我的建议是,如果您想要始终在线服务,则需要将其设置为 foreground service。我会给出一些代码示例来说明如何实现这一点,但我对 Xamarin 不是很了解,所以我不想给你任何不好的例子。
另一种方法是使用AlarmManager 和PendingIntent 来检查服务是否正在运行并在未运行时启动它。请注意,如果您经常这样做,可能会导致明显的电池消耗,但如果您不经常这样做,您可能会错过地理围栏事件。
希望这会有所帮助,祝你好运!
更新 #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 是采取的路线。