5

Mam IntentService, który przesyła plik. Wszystko działa dobrze, ale jestem nieco zdezorientowany, jak radzić sobie z powiadomieniami. Kiedy rozpoczynam powiadomienie, używam startForeground(), ponieważ pliki mogą być dość duże i nie chcę, aby upload został zabity, chyba że jest to absolutnie konieczne. Gdy używam startForeground() wyświetla dwa zawiadomienia w obszarze powiadomień (jeden pod toku i jeden pod Notifications):Jak poprawnie obsługiwać dwa powiadomienia startForegrounds

Example:

Czytałem poprzez szereg różnych stanowisk przepełnienie stosu i artykułów internetowych, ale żaden z odpowiadają na moje pytanie ... mam nadzieję, że nie umknęło mi jedno, które mówi o tys.

Rozumiem, że bieżące powiadomienie na powyższym obrazku (ten bez paska postępu) jest tam umieszczone, ponieważ jest ono wyświetlane na pierwszym planie (Services documentation). Wszystko dobrze i dobrze, jeśli mnie pytasz, i rozumiem dlaczego. Nie potrzebuję jednak dwóch powiadomień i jestem pewien, że większość osób nie życzy sobie dwóch powiadomień zaśmiecających obszar powiadomień. Chciałbym wiedzieć, jak poprawnie obsłużyć powiadomienie, aby tylko jeden wyświetlał i nie zaśmiecał obszaru powiadomień.

Jedynym sposobem, w jaki udało mi się ominąć to, jest ustawienie wartości całkowitej ID dla startForeground (int id, Notification notification) (ONGOING_NOTIFICATION_ID w moim kodzie poniżej) na zero. Jednak dokumentacja cytuję powyżej mówi:

Caution: The integer ID you give to startForeground() must not be 0

Ustawienie na 0 wyłącza trwającego zgłoszenie i po prostu pokazuje regularne powiadomienia za pomocą paska postępu. Sądzę, że mógłbym to "naprawić" ustawiając .setOngoing(true), dopóki nie zakończy się przesyłanie pliku, a następnie ustawienie .setOngoing(false) po zakończeniu, aby można było go odrzucić. Nie wiem dokładnie, jak "Ostrożny" musi być przy ustawianiu ID liczby całkowitej na 0. Wydaje mi się, że to leniwy sposób na obejście problemu, który mam, ale nie wiedzieć, czy istnieją inne konsekwencje dla ustawienia wartości 0. Działa to również tylko wtedy, gdy mam tylko jedno powiadomienie, z którym mam do czynienia. Jeśli mam wiele różnych powiadomień, potrzebuję różnych identyfikatorów dla każdego z nich, a to nie zadziała. Aktualizacja: Wygląda na to, że jest setting the ID to 0 won't work in Android 4.3, więc teraz wracam do pierwszego.

Jaki jest prawidłowy sposób obejścia wyświetlania obu powiadomień?

Aktualizacja/Rozwiązanie: Duh, biorąc trochę czasu wolnego, a następnie wracać do tego i sprawdzając, co zrobiłem na podstawie rekomendacji @dsandler „s pomógł mi dowiedzieć się, co robię źle. Nie ustawiłem prawidłowego identyfikatora podczas aktualizacji postępu, dlatego właśnie tworzyłem dwa powiadomienia, a jeden nie był aktualizowany. Używanie tego samego identyfikatora (ONGOING_NOTIFICATION_ID) we wszystkich powiadomieniach rozwiązało problem. Zobacz kod poniżej dla dodatkowych kawałków, których wcześniej nie zawierałem i gdzie popełniłem błąd.

odpowiedni kod z UploadFile.java:

public class UploadFile extends IntentService { 

    private static final int ONGOING_NOTIFICATION_ID = 1; 

    @Override 
    protected void onHandleIntent(Intent intent) { 
     mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 
     mBuilder = new NotificationCompat.Builder(this); 
     mBuilder.setContentTitle(getText(R.string.upload)) 
      .setContentText("0% " + getText(R.string.upload_in_progress)) 
      .setSmallIcon(android.R.drawable.stat_sys_upload); 

     startForeground(ONGOING_NOTIFICATION_ID, mBuilder.build()); 


.... 

    if (progress > 0){ 
     percent = (Long.valueOf(progress) * 100)/totalSize; 
     mBuilder.setProgress(100, percent.intValue(), false); 
     mBuilder.setContentText(percent.intValue() + "% " + getText(R.string.upload_in_progress)); 
     mNotifyManager.notify(ONGOING_NOTIFICATION_ID, mBuilder.build()); // <-- My problem was that I had set the ID here to 0 and did not make it the same as the ID I set above 
    }      

.... 

} 

Odpowiedz

1

Po pierwsze, sądząc po opisie, możesz być w stanie uciec z usług regularnych, uznając, że out-of-memory zabójca wygrał” dzwoni, chyba że rzeczy stają się okropne na urządzeniu, a twoja usługa naprawdę działa bardzo długo.

To powiedziawszy, jeśli musisz wykonać usługę na pierwszym planie, typową strategią jest pokazanie twoich postępów za pomocą Powiadomienia, którego użyłeś, kiedy ustawiłeś usługę na pierwszym planie. Korzystając z numeru NotificationManager.notify, możesz opublikować dowolną liczbę aktualizacji tego powiadomienia, w tym dostosowywać paski postępu, na przykład za pomocą Notification.Builder.setProgress.

W ten sposób wyświetlasz tylko jedno powiadomienie dla użytkownika i jest to wymagane przez startForeground.

+0

dzięki za odpowiedź. Wróciłem i dokładnie sprawdziłem, co robię (co robiłem, co radziłem) i zdałem sobie sprawę, że nie używam prawidłowego identyfikatora powiadomienia podczas publikowania postępu. Teraz działa jak urok! – Jason

+0

Mam pytanie dotyczące powiadomienia: która ikona powinna być używana dla "setLargeIcon", jeśli chcesz używać systemu Android (tak jak w przypadku "setSmallIcon")? –

+0

Dlaczego ** NotificationManager.notify ** jest potrzebny? 'startForegroundService()' pokazuje już powiadomienie. –

-1

Aby zaktualizować zestaw powiadomień za pomocą funkcji startForeground(), wystarczy utworzyć nową notyfikację, a następnie za pomocą Menedżera powiadomień powiadomić o tym.

Punkt KEY polega na użyciu tego samego identyfikatora powiadomienia.

Nie przetestowałem scenariusza wielokrotnego wywoływania funkcji startForeground() w celu aktualizacji Powiadomienia, ale myślę, że używanie NotificationManager.notify byłoby lepsze.

Aktualizacja powiadomienia NIE spowoduje usunięcia Usługi ze statusu pierwszego planu (można to zrobić tylko przez wywołanie stopForground);

Przykład:

private static final int notif_id=1; 

@Override 
public void onCreate(){ 
    this.startForeground(); 
} 

private void startForeground() { 
     startForeground(notif_id, getMyActivityNotification("")); 
} 

private Notification getMyActivityNotification(String text){ 
     // The PendingIntent to launch our activity if the user selects 
     // this notification 
     CharSequence title = getText(R.string.title_activity); 
     PendingIntent contentIntent = PendingIntent.getActivity(this, 
       0, new Intent(this, MyActivity.class), 0); 

     return new Notification.Builder(this) 
       .setContentTitle(title) 
       .setContentText(text) 
       .setSmallIcon(R.drawable.ic_launcher_b3) 
       .setContentIntent(contentIntent).getNotification();  
} 
/** 
this is the method that can be called to update the Notification 
*/ 
private void updateNotification() { 

       String text = "Some text that will update the notification"; 

       Notification notification = getMyActivityNotification(text); 

       NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 
       mNotificationManager.notify(notif_id, notification); 
}