Android - 前台在 Oreo 中不起作用。操作系统在一段时间后终止服务
Posted
技术标签:
【中文标题】Android - 前台在 Oreo 中不起作用。操作系统在一段时间后终止服务【英文标题】:Android - Foreground is not working in Oreo. OS killed service after some interval 【发布时间】:2019-05-12 02:04:22 【问题描述】:我有一个应用程序每隔 5 分钟在后台使用一次定位服务。我们在前台服务中使用 Fusedlocationproviderclient。当应用程序打开时它工作正常。
当我将应用程序置于后台或从后台滑动杀死时,android 8.0 及更高版本的操作系统会自动杀死前台服务。
我们在三星 note 8、一加 5t 和 red mi 设备中遇到问题。
请告诉我如何实现兼容所有设备的服务。
这是我的定位服务课程。
public class TrackingForgroundService extends Service
private final long UPDATE_INTERVAL = (long) 2000;
private static final long FASTEST_INTERVAL = 2000;
public BookingTrackingForgroundService()
@Nullable
@Override
public IBinder onBind(Intent intent)
return null;
@Override
public void onCreate()
super.onCreate();
@Override
public int onStartCommand(Intent intent, int flags, int startId)
if (intent != null)
String action = intent.getAction();
switch (action)
case ACTION_START_FOREGROUND_SERVICE:
startForegroundService();
break;
case ACTION_STOP_FOREGROUND_SERVICE:
stopForegroundService();
break;
return START_STICKY;
private class TimerTaskToGetLocation extends TimerTask
@Override
public void run()
mHandler.post(new Runnable()
@Override
public void run()
// Call webservice evry 5 minute
);
private void startForegroundService()
Log.d(TAG_FOREGROUND_SERVICE, "Start foreground service.");
context = this;
startLocationUpdates();
notify_interval1 = Prefs.with(this).readLong("notify_interval1", 5000);
mTimer = new Timer();
mTimer.scheduleAtFixedRate(new TimerTaskToGetLocation(), 15000, notify_interval1);
mTimer.scheduleAtFixedRate(new TimerTaskToSendCsvFile(), 60000, 1200000);
prefsPrivate = getSharedPreferences(Constants.prefsKeys.PREFS_PRIVATE, Context.MODE_PRIVATE);
internet = new NetConnectionService(context);
Intent notificationIntent = new Intent(this, ActTherapistDashboard.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle(getString(R.string.app_name))
.setContentText("Geolocation is running")
.setTicker("Geolocation").setSmallIcon(R.drawable.app_small_icon_white)
.setContentIntent(pendingIntent);
Notification notification = builder.build();
if (Build.VERSION.SDK_INT >= 26)
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription(CHANNEL_DESCRIPTION);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(channel);
startForeground(SERVICE_ID, notification);
private void stopForegroundService()
stopLocationUpdates();
Log.d(TAG_FOREGROUND_SERVICE, "Stop foreground service.");
if (mTimer != null)
mTimer.cancel();
else
mTimer = null;
// Stop foreground service and remove the notification.
stopForeground(true);
// Stop the foreground service.
stopSelf();
public static boolean isServiceRunningInForeground(Context context, Class<?> serviceClass)
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE))
if (serviceClass.getName().equals(service.service.getClassName()))
if (service.foreground)
return true;
return false;
private void startLocationUpdates()
// create location request object
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
// initialize location setting request builder object
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(mLocationRequest);
LocationSettingsRequest locationSettingsRequest = builder.build();
// initialize location service object
SettingsClient settingsClient = LocationServices.getSettingsClient(this);
Task<LocationSettingsResponse> task = settingsClient.checkLocationSettings(locationSettingsRequest);
task.addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>()
@Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse)
registerLocationListner();
);
private void registerLocationListner()
locationCallback = new LocationCallback()
@Override
public void onLocationResult(LocationResult locationResult)
super.onLocationResult(locationResult);
onLocationChanged(locationResult.getLastLocation());
;
//location permission
LocationServices.getFusedLocationProviderClient(this).requestLocationUpdates(mLocationRequest, locationCallback, null);
private void onLocationChanged(Location location)
if (location != null)
latitude = location.getLatitude();
longitude = location.getLongitude();
latitudeTemp = latitude;
longitudeTemp = longitude;
【问题讨论】:
为什么不能使用 JobScheduler ?为了让服务在 Android Oreo 中继续运行,我们需要显示通知 @Rahul Patil JobScheduler 在设备处于睡眠模式或打盹模式时不起作用。 前台服务不能保证永久驻留该服务。它只是将它放在杀死优先级链上的较低位置。 @RahulPatil 感谢您的快速回复。以前我们使用过jobschduler,但它不能在锁定屏幕和打盹模式下工作。这就是我们从作业调度程序切换到带有通知的前台服务的原因。 @GabeSechan - 感谢分享知识。除前台服务外,哪个是解决我的问题的最佳解决方案? 【参考方案1】:请参阅here 对类似问题的回答以及链接网站dontkillmyapp,它为开发人员提供了非常有用的摘要,以帮助了解不同手机制造商和 Android 操作系统版本的此问题。
【讨论】:
以上是关于Android - 前台在 Oreo 中不起作用。操作系统在一段时间后终止服务的主要内容,如果未能解决你的问题,请参考以下文章
Android Oreo onTaskRemoved 事件不起作用(Android 版本 Oreo)