2012-03-29 10 views
7

Mam IntentService i chcę, aby była lepka z bieżącym powiadomieniem. Problem polega na tym, że powiadomienie pojawia się, a następnie natychmiast znika. Usługa nadal działa. W jaki sposób powinienem użyć startForeground w IntentService?StartForeground for 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(); 
} 

Dzięki

+2

zawierać kod zbyt – waqaslam

Odpowiedz

9

To nie powinno być IntentService. Jak napisano, Twój IntentService będzie działać przez milisekundę. Po zwróceniu onHandleIntent() usługa zostanie zniszczona. Powinno to być regularne Service, w którym można rozwidlić własny wątek i zarządzać czasem życia wątku i usługi.

Powodem natychmiastowego zniknięcia numeru Notification jest fakt, że usługa od razu się wyłączy.

+1

Dzięki, przekształcono go w Google, a teraz pracuje. – Matroska

+2

Dochód za udział, ponieważ: Prawdopodobnie jest to niepoprawna odpowiedź. Fragment z dokumentacji IntentService: "Wszystkie żądania są obsługiwane w jednym wątku roboczym - * mogą trwać tak długo, jak to konieczne * (i nie będą blokować głównej pętli aplikacji), ale tylko jedno żądanie będzie przetwarzane na raz." Nic nie mówiło o milisekundy. https://developer.android.com/reference/android/app/IntentService.html – GregoryK

+1

Jak napisano, ta 'IntentService' będzie działać przez milisekundę, z tego prostego powodu, że kod w' onHandleIntent() 'zajmie tylko milisekundę lub więcej. – CommonsWare

1

Jak documentation dla IntentService stanów:

... usługa jest uruchomiona w miarę potrzeb, obsługuje każdy woli w kolei przy użyciu nici pracownika i zatrzymuje się, gdy zabraknie pracy.

Zakładam, że problem polega na tym, że po zakończeniu onHandleIntent() usługa jest wyłączona z pracy. W związku z tym usługa zatrzymuje się, a powiadomienie zostaje wycofane. Tak więc koncepcja IntentService prawdopodobnie nie jest najlepszym rozwiązaniem dla twojego zadania.


W tytule pytanie jest „StartForeground dla IntentService”, chciałbym wyjaśnić kilka rzeczy:

To naprawdę proste, aby dokonać IntentService do uruchomienia w pierwszym planie (patrz kod poniżej), ale na pewno należy wziąć pod uwagę kilka rzeczy:

  • Nie uruchamiaj usługi na pierwszym planie, jeśli zajmie to tylko kilka sekund - może to spowodować błędy u użytkowników. Wyobraź sobie, że okresowo wykonujesz krótkie zadania - to spowoduje, że powiadomienie pojawi się i zniknie - Być może będziesz musiał sprawić, by Twoja usługa była w stanie utrzymać urządzenie w stanie uśpienia (ale to już inna historia, która jest dobrze opisana na stackoverflow) *

  • Jeśli ustawiłeś w kolejce kilka Intencji do IntentService, poniższy kod zakończy się wyświetlaniem/ukrywaniem powiadomienia. (Może więc być lepsze rozwiązanie dla twojej sprawy - jak @CommonsWare sugeruje rozszerzenie usługi i zrobić wszystko samemu, jednak chciałbym wspomnieć - w javadoc nie ma nic dla IntentService mówiącego, że działa tylko kilka sekund - działa tak długo, jak długo to musi coś zrobić.)


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

Ogólna zasada dotycząca programowania komputerowego: nigdy nie zakładaj założenia o zasobie, który coś innego nabył w twoim imieniu. Nie utworzyłeś wątku tła używanego przez 'IntentService'; w związku z tym nie należy przyjmować żadnych założeń dotyczących tego, jak długo można z niego bezpiecznie korzystać. Natknęliśmy się na ten problem z 'AsyncTask', gdzie Google zmienił reguły' execute() ', ograniczając cię do pojedynczego wątku we wszystkich zadaniach. Jeśli chcesz zatrzymać wątek dłużej niż przez krótki okres, utwórz własny wątek. Obalenie za rekomendowanie zawstydzających praktyk programistycznych. – CommonsWare

+1

@ConsonsWare Widzę twój punkt i rozumiem to. To ma sens. W rzeczywistości nie zgadzałem się co do tego stwierdzenia: "Jak napisano, Twoja IntentService będzie działać przez milisekundę". Nie próbuję przyjmować założeń, API java mówi: "IntentService jest klasą podstawową dla Usług, które obsługują żądania asynchroniczne (wyrażone jako Intents) na żądanie. Klienci wysyłają żądania przez wywołania startService (Intent), usługa jest uruchamiana w razie potrzeby, traktuje każdy zamiar po kolei za pomocą wątku roboczego i zatrzymuje się, gdy zabraknie mu pracy. " – GregoryK

Powiązane problemy