StartForeground для IntentService

У меня есть IntentService, и я хочу сделать его липким с текущим уведомлением. Проблема в том, что уведомление появляется, а затем немедленно исчезает. Служба продолжает работать. Как использовать startForeground в IntentService?

@Override public int onStartCommand(Intent intent, int flags, int startId) { super.onStartCommand(intent, flags, startId); Notification notification = new Notification(R.drawable.marker, "Notification service is running", System.currentTimeMillis()); Intent notificationIntent = new Intent(this, DashboardActivity.class); notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP| Intent.FLAG_ACTIVITY_SINGLE_TOP); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); notification.setLatestEventInfo(this, "App", "Notification service is running", pendingIntent); notification.flags|=Notification.FLAG_NO_CLEAR; startForeground(1337, notification); return START_STICKY; } @Override protected void onHandleIntent(Intent intent) { String id = intent.getStringExtra(ID); WebSocketConnectConfig config = new WebSocketConnectConfig(); try { config.setUrl(new URI("ws://" + App.NET_ADDRESS + "/App/socket?id="+id)); } catch (URISyntaxException e) { e.printStackTrace(); } ws = SimpleSocketFactory.create(config, this); ws.open(); } 

благодаря

Это не должно быть IntentService . Как написано, ваш IntentService будет жить миллисекундой или около того. Как только onHandleIntent() возвращается, служба уничтожается. Это должна быть обычная Service , в которой вы создаете собственный поток и управляете временем жизни потока и службы.

Причина, по которой ваше Notification немедленно уходит, – это то, что служба немедленно уходит.

Поскольку документация для IntentService гласит:

… услуга запускается по мере необходимости, обрабатывает каждое намерение по очереди с помощью рабочего потока и останавливается, когда заканчивается работа.

Итак, я полагаю, проблема в том, что ваш сервис не работает после onHandleIntent() . Следовательно, сервис останавливается, и уведомление прерывается. Таким образом, концепция IntentService, вероятно, не самый лучший вариант для вашей задачи.


Поскольку название вопроса – «StartForeground для IntentService», я хотел бы уточнить некоторые вещи:

Очень просто сделать IntentService запущенным на переднем плане (см. Код ниже), но наверняка вам нужно рассмотреть несколько вещей:

  • Не запускайте службу на переднем плане, если требуется несколько секунд – это может привести к ошибкам ваших пользователей. Представьте, что вы периодически выполняете короткие задания – это приведет к появлению и исчезновению уведомления – uhhhh *

  • Возможно, вам понадобится сделать вашу службу способной поддерживать работоспособность устройства (но это еще одна история, которая довольно хорошо покрывается stackoverflow) *

  • Если вы поставили в очередь несколько Intents для вашего IntentService, приведенный ниже код будет показывать / скрывать уведомление. (Таким образом, может быть лучшее решение для вашего случая – поскольку @CommonsWare предлагает расширить Service и делать все сами, однако хотелось бы упомянуть – в IntaService ничего не говорится о том, что он работает всего несколько секунд – он работает до тех пор, пока Он должен что-то сделать.)


 public class ForegroundService extends IntentService { private static final String TAG = "FrgrndSrv"; public ForegroundService() { super(TAG); } @Override protected void onHandleIntent(Intent intent) { Notification.Builder builder = new Notification.Builder(getBaseContext()) .setSmallIcon(R.drawable.ic_foreground_service) .setTicker("Your Ticker") // use something from something from R.string .setContentTitle("Your content title") // use something from something from .setContentText("Your content text") // use something from something from .setProgress(0, 0, true); // display indeterminate progress startForeground(1, builder.build()); try { doIntesiveWork(); } finally { stopForeground(true); } } protected void doIntesiveWork() { // Below should be your logic that takes lots of time try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } } }