6

Vorrei poter visualizzare più download di file nella barra di notifica che possono anche essere annullati.Servizio di download Android personalizzato: riga di notifica di avanzamento per file

Ho implementato un servizio personalizzato che esegue download multipli in parallelo utilizzando AsyncTasks. OnPublishProgress Sto tentando di aggiornare le singole righe nella barra delle notifiche per mostrare lo stato del download per ogni file. Per due giorni solidi ho cercato di risolvere i problemi con lo sfarfallio delle righe, scambiando l'ordine e talvolta rimanendo in bianco o aggiornando solo una riga. Inoltre, toccare la riga per annullare la routine non sempre funziona.

Ecco il mio codice:

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

quindi sto cercando di impostare l'azione di chiamare il servizio quando toccando la notifica, passando l'id del file per annullare il download. Qualcuno può vedere cosa sto facendo male? Quello che sto cercando è effettivamente possibile? Su un tablet Xoom il tremolio delle notifiche è molto elevato, ma non così spesso sul Nexus 7. Tutti i dispositivi finiscono per scambiare file costantemente, il che significa che è praticamente impossibile annullare il download che si desidera.

Qualsiasi consiglio sarebbe molto apprezzato.

UPDATE 1: Penso che questa potrebbe essere la causa uno dei miei problemi: Android Service.startForeground does NOT respect notification id uniqueness

UPDATE 2: La questione sostituendo è stato fissato dal chiamando builder.setWhen (fixedTime). Ovviamente, la nuova data time stava causando il riordino delle righe ogni volta che veniva aggiornato. Basta correggere lo sfarfallio su Xoom e la funzione "Tocca per annullare".

UPDATE 3: Lo sfarfallio su Xoom è stato corretto limitando le chiamate all'aggiornamento. Il codice alla fine impedisce che la notifica venga aggiornata più di una volta ogni 100 ms. I problemi rimanenti riguardano l'annullamento. Il tocco per annullare funziona la prima volta ma non funziona sui file successivi. Inoltre non riesco a cancellare le righe.

UPDATE 4: Il singolo problema di annullamento era causato dal fatto che il campoIntent era a livello di classe. Quando ne ho creato uno nuovo ogni volta che ho aggiornato la notifica, gli ID hanno legato. Ho anche modificato il flag in Notification.FLAG_ONLY_ALERT_ONCE solo e solo usato .notify() e non startForeground().

+0

Quindi tutti i problemi sono stati risolti ora? In tal caso, si prega di inviare la propria risposta e contrassegnarla come accettata per riferimento futuro! Thnx – Entreco

risposta

1

Tutti i problemi sono stati risolti. Ho aggiunto gli aggiornamenti nel mio post originale. In breve: 1) Prestare attenzione con builder.setWhen (fixedTime). 2) Non aggiornare più di una volta ogni 100 ms 3) Impostare i flag corretti.

+1

L'aggiornamento può ritardare qualsiasi notifica fino alla morte. Ecco alcuni metodi che possono essere utilizzati per l'aggiornamento occasionale: http://stackoverflow.com/questions/16050381/how-do-i-get-an-android-service-to-broadcast-an-intent-every-few- secondi –

Problemi correlati