6

Chciałbym móc wyświetlać wiele plików do pobrania na pasku powiadomień, które również można anulować.Niestandardowa usługa pobierania Android - dostarczanie wiersza powiadomień o postępach dla pliku

Zaimplementowałem niestandardową usługę, która wykonuje wiele pobrań równolegle przy użyciu AsyncTasks. OnPublishProgress Próbuję zaktualizować poszczególne wiersze na pasku powiadomień, aby wyświetlić postęp pobierania dla każdego pliku. Przez dwa solidne dni próbowałem naprawić problemy z migotaniem wierszy, kolejnością zamiany, a czasami po prostu pustym lub tylko aktualizowaniem jednego wiersza. Także pukanie w rząd w celu anulowania rutyny nie zawsze działa.

Oto mój kod:

protected void showProgressNotification(final File item, int progress, boolean isDownloading) { 
    String message = null; 
    int smallIcon = 0; 
    Bitmap largeIcon = null; 
    int flags = 0; 
    flags |= Notification.FLAG_ONGOING_EVENT; 
    //flags |= Notification.FLAG_FOREGROUND_SERVICE; 
    //flags |= Notification.FLAG_ONLY_ALERT_ONCE; 
    //flags |= Notification.FLAG_AUTO_CANCEL; 

    NotificationCompat.Builder builder = 
      new NotificationCompat.Builder(getApplicationContext()); 
    builder.setAutoCancel(true); 

    if (progress == 100) { 
     largeIcon = BitmapFactory.decodeResource(getResources(), 
       O2FolderListAdapter.getIconForItem(item, false)); 
     smallIcon = R.drawable.ic_cloud_upto_date; 

     if (isDownloading) { 
      message = "Download completed. Tap to clear."; 
     } else { 
      message = "Upload completed. Tap to clear."; 
     } 
    } else if (progress >= 0) { 
     largeIcon = BitmapFactory.decodeResource(getResources(), 
       O2FolderListAdapter.getIconForItem(item, true)); 
     if (isDownloading) { 
      smallIcon = R.drawable.ic_cloud_downloading; 
      message = "Downloading: " + progress + "%. Tap to cancel."; 
     } else { 
      smallIcon = R.drawable.ic_cloud_uploading; 
      message = "Uploading: " + progress + "%. Tap to cancel."; 
     } 
     builder.setProgress(100, progress, false); 
    } else { 
     largeIcon = BitmapFactory.decodeResource(getResources(), 
       O2FolderListAdapter.getIconForItem(item, true)); 
     smallIcon = R.drawable.ic_cloud_conflict; 
     if (isDownloading) 
      message = "Cancelled download. Tap to clear."; 
     else 
      message = "Cancelled upload. Tap to clear."; 
    } 

    if (mResultIntent == null) { 
     mResultIntent = new Intent(getApplicationContext(), CustomDownloadService.class); 
     mResultIntent.addFlags(Notification.FLAG_ONGOING_EVENT); 
    } 
    mResultIntent.putExtra("cancel", item.getPath().hashCode()); 
    Log.d("O2AbstractDownloadService", "Setup task id " + item.GetPath().hashCode()); 
    if (mContentIntent == null) 
     mContentIntent = PendingIntent.getService(getApplicationContext(), PI_REQ_CODE, mResultIntent, PendingIntent.FLAG_UPDATE_CURRENT); 
    builder.setContentIntent(mContentIntent); 

    builder.setLargeIcon(largeIcon); 
    builder.setSmallIcon(smallIcon); 
    builder.setContentTitle(item.GetName()); 
    builder.setContentText(message); 

    //if (progress != 100) 
     //builder.addAction(R.drawable.ic_action_dark_cancel, "Cancel", contentIntent); 

    final Notification notification = builder.build(); 
    notification.flags = flags; 
    notification.defaults = Notification.DEFAULT_LIGHTS; 

    NotificationManager mNotificationManager = 
     (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 
    // Id allows you to update the notification later on. 
    //mNotificationManager.notify(item.getPath().hashCode(), notification); 
    //startForeground(item.getPath().hashCode(), notification); 

    // only update notification every 100ms (unless cancel or complete) 
    long notificationDelay = 100; 
    long now = System.currentTimeMillis(); 
    if (mFutureCallTime == 0 || now > mFutureCallTime || progress == -1 || progress == 100) { 
     startForeground(item.getPath().hashCode(), notification); 
      //mNotificationManager.notify(item.GetPath().hashCode(), notification); 
    } else 
     Log.d("CustomDownloadService", "Called too often to notification"); 

    mFutureCallTime = now + notificationDelay; 
} 

Więc próbuję skonfigurować działanie wezwać serwis po stukając w powiadomieniu, przekazując identyfikator pliku, aby anulować pobieranie. Czy ktoś może zobaczyć, co robię źle? Czy to, o co naprawdę chodzi, jest możliwe? Na tablecie Xoom powiadomienia migają bardzo często, ale nie tak często na Nexusie 7. Wszystkie urządzenia w końcu zamieniają się wierszami, co oznacza, że ​​praktycznie niemożliwe jest anulowanie pobierania.

Każda rada byłaby mile widziana.

UPDATE 1: myślę, że to może być przyczyną jednego z moich sprawach: Android Service.startForeground does NOT respect notification id uniqueness

UPDATE 2: wymieniając problem został rozwiązany przez wywołanie builder.setWhen (fixedTime). Oczywiście nowa funkcja dateTime powodowała zmianę kolejności wierszy za każdym razem, gdy była odświeżana. Wystarczy naprawić migotanie w Xoom i funkcję "Stuknij, aby anulować".

AKTUALIZACJA 3: Migotanie w Xoom zostało naprawione z ograniczeniem wywołań do odświeżenia. Kod na końcu uniemożliwia aktualizację powiadomienia więcej niż raz na 100ms. Pozostałe problemy dotyczą anulowania. Kliknięcie, aby anulować, działa po raz pierwszy, ale nie działa w przypadku kolejnych plików. Również nie mogę usunąć rzędów.

AKTUALIZACJA 4: Pojedynczy problem z anulowaniem był przyczyną wyniku w polu wynikowym na poziomie klasy. Kiedy utworzyłem nowy za każdym razem, gdy odświeżałem powiadomienie, identyfikatory były powiązane. Zmieniłem także flagę tylko na Notification.FLAG_ONLY_ALERT_ONCE i użyłem tylko .notify(), a nie startForeground().

+0

Czy wszystkie problemy zostały teraz naprawione? Jeśli tak, proszę zamieścić własną odpowiedź i oznaczyć ją jako zaakceptowaną do wykorzystania w przyszłości! Thnx – Entreco

Odpowiedz

1

Wszystkie problemy zostały naprawione. Dodałem aktualizacje w moim oryginalnym wpisie. Podsumowując: 1) Uważaj przy builder.setWhen (fixedTime). 2) Nie odświeżaj więcej niż raz co 100ms 3) Ustaw prawidłowe flagi.

+1

Odświeżanie może opóźnić każde powiadomienie na śmierć. Oto kilka metod, które można wykorzystać do okazjonalnej aktualizacji: http://stackoverflow.com/questions/16050381/how-do-i-get-an-android-service-to-broadcast-an-intent-every-few- sekundy –

Powiązane problemy