5

Meine Anwendung startet eine AsyncTask, die eine Datei von einer URL herunterlädt. Gleichzeitig wird eine Statusleiste Notification erstellt, die dem Benutzer den Prozentsatz des Downloads anzeigt.Android: Wie greife ich auf eine AsyncTask von einem PendingIntent zu, das durch eine Benachrichtigung in der Statusleiste erstellt wurde?

Ich versuche, meine Anwendung auf das Klicken der Benachrichtigung zu reagieren. Wenn der Download noch läuft, möchte ich eine DialogInterface zeigen, die sie fragt, ob sie den Download stoppen wollen. Durch Klicken auf "Ja" sollte der Download gestoppt werden.

Das Problem, das ich habe, ist ich bin nicht sicher, wie auf meine Async-Aufgabe von der PendingIntent zugreifen, die ich für die Benachrichtigung eingerichtet habe. Ich kann die DialogInterface zeigen, um einfach zu zeigen, aber ich bin mir nicht sicher, wie man die Aktivität zeigt, die abgeht, wo der Download ist, um es zu stoppen.

Ich habe versucht, eine Helper-Klasse, die Zugriff auf die Benachrichtigung sowie das Dateiobjekt bezogen auf die herunterladbare Datei hatte, aber ich bekomme eine Fehlermeldung, dass das Objekt nicht serialisierbar ist (es implementiert Serializable). Die Hilfsklasse enthielt auch ein Mitglied, das den Fortschritt des Downloads halten würde, was ich für die Bedingung verwenden würde, ob der Dialog angezeigt werden soll oder nicht.

Ich dachte an eine Brodcast Action und einen Empfänger, aber ich bin mir nicht sicher, wo ich den Empfänger hinstellen soll. Würde es in der Klasse gehen, die die AsyncTask erweitert?

Jede Hilfe wäre willkommen. Dies ist die PendingIntent an die Notification angeschlossen. Wenn Sie mehr Code sehen möchten, fragen Sie einfach.

public class DownloadNotificationActivity extends Activity { 

/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    Intent i = getIntent(); 

    DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() { 

     @Override 
     public void onClick(DialogInterface dialog, int which) { 
      switch (which) { 
       case DialogInterface.BUTTON_POSITIVE : 
        // Yes button clicked 
        // Stop download 
        finish(); 
        break; 

       case DialogInterface.BUTTON_NEGATIVE : 
        // No button clicked 
        finish(); 
        break; 
      } 
     } 
    }; 

    if (/* download not complete */) { 
     AlertDialog.Builder builder = new AlertDialog.Builder(this); 
     builder.setMessage(R.string.stop_download). 
       setPositiveButton(R.string.yes, dialogClickListener). 
       setNegativeButton(R.string.no, dialogClickListener).show(); 
    } 
    else { 
     // Access file 
    } 

} 
} 

Also um klar zu sein, habe ich eine ViewDetailActivity Klasse. Es hat eine innere Klasse namens DownloadFile, die AsyncTask erweitert und ausgeführt wird, wenn der Benutzer auf eine Schaltfläche auf dem Bildschirm klickt. In der doInBackground() Methode von DownloadFile wird ein Download einer MP3 von einer URL gestartet und eine Statusleiste Notification wird basierend auf der Menge der heruntergeladenen Datei erstellt und aktualisiert. Die PendingIntent der Notification wird mit der DownloadNotificationActivity (Code angezeigt) erstellt und es sollte einen Dialog anzeigen, der von "Ja" ausgewählt ist, sollte den Download in AsyncTask abbrechen.

Mein Problem ist, dass ich Wort an die DownloadFile Aufgabe zurück zu erhalten, dass der Download abgebrochen wurde, und ich bin nicht sicher, wie die DownloadFile zuzugreifen vom DownloadNotificationActivity um es zu löschen.

Vielen Dank im Voraus!

Antwort

1

In Ihrer asynctask müssen Sie nach isCancelled() in der doInBackground() suchen und abbrechen, wenn abgebrochen. Von Ihrer Benachrichtigung aus rufen Sie cancel() über die asynctask an.

Um dies zu tun, müssen Sie einen Verweis auf die AsyncTask zu Ihrer Benachrichtigung Aktivität übergeben.

Zum Beispiel:

Sie erstellen die AsyncTask wie folgt aus:

class MyAsyncTask extends AsyncTask<Void, Integer, Void> { 
     @Override 
     protected Void doInBackground(Void... unused) { //be sure to check isCancelled here, i.e. if (isCancelled()) break; 

dann in der Haupt Activity Sie schaffen die AsyncTask wie:

public class MyActivity extends Activity { 
    private MyAsyncTask zeTask; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
       zeTask= new MyAsyncTask(); 
       zeTask.execute(); 

Dann, wenn Sie die Meldung erstellen und die async-Aufgabe abbrechen wollen, bezeichne sie einfach als zeTask. Die MyAsyncTask muss sich in derselben Aktivität wie die Benachrichtigung befinden, und zeTask kann eine Variable sein, die den Verweis auf Ihre AsyncTask enthält.

switch (which) { 
       case DialogInterface.BUTTON_POSITIVE : 
        zeTask.cancel(); 
        finish(); 
        break; 
+0

Das ist das Problem, das ich tatsächlich die Referenz der 'AsyncTask' an die obige Aktivität weitergibt. Ich habe versucht, 'Serializable' auf der' AsyncTask' zu implementieren und 'putExtra()' auf der 'Intent' zu verwenden, die ich als 'PendingIntent' eingerichtet habe, aber ich habe eine Ausnahme erhalten, die besagt, dass das Objekt nicht serialisierbar ist. Gibt es eine andere Möglichkeit, einen Verweis auf die AsyncTask an meine Aktivität zu übergeben? – Shino

+0

Ok Ich denke, dass die Art, wie ich es mache, einfach nicht funktionieren wird. Die Benachrichtigungsaufgabe, die ich gepostet habe, war NUR zur Verwendung als "PendingIntent", wenn auf die Benachrichtigung in der Statusleiste geklickt wurde. Die 'AsyncTask' war tatsächlich in der Klasse, die den Bildschirm bearbeitet hat, wo Sie klicken können, um die Datei herunterzuladen. Klingt so, als müsste ich meine 'AsyncTask' in die' DownloadNotificationActivity' verschieben und im 'onCreate' dieser Klasse ausführen. Behandeln Sie dann das Ereignis "onClick" für die Benachrichtigung. Ich werde dich wissen lassen, was passiert. – Shino

+0

Versuchen, was ich in meinem vorherigen Kommentar gesagt habe, hat nicht funktioniert. Ich danke Ihnen für Ihre Hilfe @Motes. Ich habe das Thema mit mehr Informationen aktualisiert (unten). Ich fühle mich, als würde ich das falsch machen. Ich muss nach anderen Optionen suchen. Ich dachte darüber nach, Broadcast und BraodcastReceiver auszuprobieren, aber ich bin mir nicht sicher, wie gut es ist, einen Empfänger auf eine AsyncTask zu setzen. – Shino

Verwandte Themen