5

Ich habe einen IntentService, der eine Datei hochlädt. Alles funktioniert gut, aber ich bin ein wenig verwirrt darüber, wie mit den Benachrichtigungen umzugehen ist. Wenn ich die Benachrichtigung starte, benutze ich startForeground(), weil die Dateien ziemlich groß sein können und ich möchte nicht, dass der Upload getötet wird, wenn es absolut notwendig ist. Wenn ich startForeground() verwenden zeigt es zwei Meldungen im Infobereich (ein unter Laufende und einem unter Notifications):Wie startForegrounds zwei Benachrichtigungen korrekt behandeln

Example:

ich durch eine Reihe von verschiedenen Stack-Überlauf-Beiträge und Web-Artikel gelesen haben, aber keiner von sie beantworten die Frage, die ich habe ... hoffentlich habe ich nicht einen vermisst, der über ths spricht.

Ich verstehe, dass die laufende Benachrichtigung im Bild oben (das ohne den Fortschrittsbalken) dort gesetzt wird, da dieser im Vordergrund läuft (Services documentation). Das ist alles gut und gut, wenn Sie mich fragen, und ich verstehe warum. Allerdings brauche ich nicht zwei Benachrichtigungen angezeigt und ich bin mir ziemlich sicher, dass die meisten Menschen nicht wollen, dass zwei Benachrichtigungen den Benachrichtigungsbereich überfluten. Ich würde gerne wissen, wie man die Benachrichtigung richtig behandelt, so dass nur eine angezeigt wird und den Benachrichtigungsbereich nicht überfüllt.

Die einzige Möglichkeit, die ich haben konnte, ist, wenn ich die Ganzzahl-ID für startForeground (int id, Notification notification) (ONGOING_NOTIFICATION_ID10 in meinem Code unten) auf Null setzen. Allerdings sagt die Dokumentation ich oben zitieren:

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

auf 0 deaktiviert die laufende Benachrichtigung Einstellung und zeigt dann nur die regelmäßige Benachrichtigung mit dem Fortschrittsbalken. Ich denke, ich könnte das irgendwie "reparieren", indem ich .setOngoing(true) setze, bis es fertig ist, die Datei hochzuladen und dann .setOngoing(false) einzustellen, sobald es fertig ist, also kann es entlassen werden. Ich bin mir nicht sicher, wie genau "Vorsichtig" man sein muss, wenn man die Integer-ID auf 0 setzt. Für mich scheint es irgendwie ein fauler Weg zu sein, das Problem, das ich habe, zu umgehen, aber ich tue es nicht weiß, ob es weitere Konsequenzen für die Einstellung auf 0 gibt. Das funktioniert auch nur, wenn ich nur eine Benachrichtigung habe, mit der ich es zu tun habe. Wenn ich mehrere verschiedene Benachrichtigungen habe, brauche ich für jedes eine andere ID, und das funktioniert nicht. Update: Es sieht aus wie setting the ID to 0 won't work in Android 4.3, so jetzt bin ich wieder auf Platz eins.

Was ist ein gültiger Weg, um beide Benachrichtigungen anzuzeigen?

Update/Lösung: Duh, ich nahm mir eine Auszeit und kam dann zurück und überprüfte, was ich aufgrund der Empfehlung von @dsandler getan hatte, half mir herauszufinden, was ich falsch gemacht hatte. Ich habe die korrekte ID nicht festgelegt, als ich die Fortschrittsaktualisierung durchführte. Aus diesem Grund wurden zwei Benachrichtigungen erstellt und eine wurde nicht aktualisiert. Die Verwendung der gleichen ID (ONGOING_NOTIFICATION_ID) für alle Benachrichtigungen löste das Problem für mich. Sehen Sie den Code unten für die zusätzlichen Stücke, die ich vorher nicht eingeschlossen hatte und wo ich den Fehler gemacht hatte.

Relevante Code von 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 
    }      

.... 

} 

Antwort

1

Zunächst einmal, indem Sie Ihre Beschreibung zu urteilen, könnten Sie in der Lage sein, mit einem regelmäßigen Service wegzukommen zu erkennen, dass der Out-of-Memory-Killer gewonnen‘ t rufen Sie an, es sei denn, die Dinge werden auf dem Gerät schrecklich und Ihr Service hat wirklich eine sehr lange Zeit.

Wenn Sie den Dienst in den Vordergrund stellen müssen, besteht die typische Strategie hier darin, Ihren Fortschritt anhand der Benachrichtigung anzuzeigen, die Sie bei der Bereitstellung des Dienstes im Vordergrund verwendet haben. Mit NotificationManager.notify können Sie so viele Aktualisierungen an diese Benachrichtigung senden, wie Sie möchten, z. B. Anpassungen für Fortschrittsbalken über Notification.Builder.setProgress.

Auf diese Weise zeigen Sie dem Benutzer nur eine Benachrichtigung an, die von startForeground angefordert wird.

+0

Dank für die Antwort. Ich ging zurück und überprüfte, was ich tat (was genau das tat, was Sie empfohlen hatten) und stellte fest, dass ich nicht die korrekte Benachrichtigungs-ID verwendete, wenn ich den Fortschritt posten wollte. Es funktioniert jetzt wie ein Zauber! – Jason

+0

Ich habe eine Frage bezüglich der Benachrichtigung: Welches Symbol sollte für "setLargeIcon" verwendet werden, wenn Sie das von Android (wie Sie es für "setSmallIcon" getan haben) verwenden möchten? –

+0

Warum wird ** NotificationManager.notify ** benötigt? 'startForegroundService()' zeigt bereits die Benachrichtigung an. –

-1

Wenn Sie eine von startForeground() festgelegte Benachrichtigung aktualisieren möchten, erstellen Sie einfach eine neue Benachrichtigung und benachrichtigen Sie sie dann mit NotificationManager.

Der Schlüsselpunkt besteht darin, dieselbe Benachrichtigungs-ID zu verwenden.

Ich habe das Szenario des wiederholten Aufrufs von startForeground() nicht getestet, um die Benachrichtigung zu aktualisieren, aber ich denke, dass die Verwendung von NotificationManager.notify besser wäre.

Durch das Aktualisieren der Benachrichtigung wird der Dienst NICHT aus dem Vordergrundstatus entfernt (dies kann nur durch Aufrufen von stopForground erfolgen);

Beispiel:

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); 
} 
Verwandte Themen