Предварительные условия: В рамках требования к моему приложению мне необходимо убедиться, что приложение не будет закрыто (уничтожено) системой Android в фоновом режиме. Для этого я реализовал службу Foreground, хотя я не выполняю никаких реальных процессов в фоновом режиме, просто поддерживаю состояние приложения. Все работает просто отлично, кроме одной вещи, которая мне не совсем понятна, как исправить.
Проблема: Иногда (только один раз, на данный момент) я получаю это исключение:
android.app.RemoteServiceException: Context.startForegroundService() did not then call Service.startForeground():
Это исключение выдается, когда я пытаюсь остановить службу переднего плана, пока она фактически не запущена.
Итак, мой вопрос - есть ли способ остановить службу переднего плана правильно, чтобы убедиться, что он не работает, прежде чем его остановить? На данный момент я обнаружил, что могу иметь экземпляр stati c для моей службы и сравнивать его со значением null до остановки службы или получить список всех служб, запущенных в данный момент. Но все они выглядят как «обходные» обходные пути.
Вот код: MyForegroundService:
public class ForegroundService extends Service {
public static final int NOTIFICATION_ID = 1;
public static final String CHANNEL_ID = "SessionForegroundServiceChannel";
public static final String ACTION_FOREGROUND_START = "ACTION_FOREGROUND_START";
public static final String ACTION_FOREGROUND_STOP = "ACTION_FOREGROUND_STOP";
public static void startForegroundService(Context context) {
Intent intent = new Intent(context, ForegroundService.class);
intent.setAction(ForegroundService.ACTION_FOREGROUND_START);
ContextCompat.startForegroundService(context, intent);
}
public static void stopForegroundService(Context context) {
Intent intent = new Intent(context, ForegroundService.class);
intent.setAction(ForegroundService.ACTION_FOREGROUND_STOP);
ContextCompat.startForegroundService(context, intent);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (ACTION_FOREGROUND_START.equals(intent.getAction())) {
createNotificationChannel();
Intent stopForegroundIntent = new Intent(this, ForegroundServiceBroadcastReceiver.class);
PendingIntent pendingLogoutIntent = PendingIntent.getBroadcast(this,
0, stopForegroundIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
? null
: getString(R.string.app_short_name))
.setContentText(getString(R.string.foreground_description))
.setColor(getResources().getColor(R.color.color))
.setSmallIcon(R.drawable.ic_notification)
.addAction(R.drawable.ic_logout, getString(R.string.logout), pendingLogoutIntent)
.build();
startForeground(NOTIFICATION_ID, notification);
} else if (ACTION_FOREGROUND_STOP.equals(intent.getAction())) {
stopForeground(true);
stopSelf();
}
return START_STICKY;
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel serviceChannel = new NotificationChannel(
CHANNEL_ID,
getString(R.string.app_name),
NotificationManager.IMPORTANCE_LOW
);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(serviceChannel);
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
<service
android:name=".ui.ForegroundService"
android:exported="false"
android:stopWithTask="true"/>
Я также есть BroadcastReceiver и EventBus для прослушивания некоторых событий и остановки переднего плана в зависимости от этих событий.
Не могли бы вы помочь мне, ребята?