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();
}

Спасибо

2 ответа

Решение

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

Причина ваша Notification уходит немедленно, потому что сервис уходит немедленно.

В качестве документации для IntentService состояния:

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

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


Поскольку заголовок вопроса - "StartForeground for IntentService", я хотел бы уточнить некоторые вещи:

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

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

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

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


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();
        }
    }
}
Другие вопросы по тегам