5

我的應用程序啓動AsyncTask,它從URL下載文件。同時它會創建一個狀態欄Notification,告訴用戶完成下載的百分比。Android:我如何從由狀態欄通知創建的PendingIntent訪問AsyncTask?

我試圖讓我的應用程序響應點擊通知。 如果下載仍在進行中,我想要顯示一個DialogInterface,詢問他們是否要停止下載。點擊是應該停止下載。

我遇到的問題是我不確定如何訪問我爲通知設置的PendingIntent中的異步任務。我可以讓DialogInterface顯示得夠簡單,但我不確定如何顯示下載停止的活動。

我試着製作一個可以訪問通知的Helper類以及引用可下載文件的File對象,但是我得到一個錯誤,提示該對象不可序列化(它實現了Serializable)。幫助類還包括一個會保存下載進度的成員,這是我將用於是否顯示對話框的條件。

我正在考慮使用Brodcast動作和接收器,但我不知道把接收器放在哪裏。它會延長AsyncTask的課程嗎?

任何幫助,將不勝感激。 這是連接到NotificationPendingIntent。如果您想查看更多代碼,只需詢問。

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 
    } 

} 
} 

所以要清楚,我有一個ViewDetailActivity類。它有一個名爲DownloadFile的內部類,它擴展了AsyncTask並在用戶單擊屏幕上的按鈕時執行。在doInBackground()方法DownloadFile中,從URL開始下載mp3,並且基於下載的文件量創建和更新狀態欄NotificationNotificationPendingIntent使用DownloadNotificationActivity(顯示的代碼)創建,它應顯示一個對話框,選擇「是」,應該取消AsyncTask中的下載。

我的問題是,我需要回到DownloadFile任務,下載已取消,我不知道如何訪問 以取消它。

在此先感謝!

回答

1

在您的asynctask中,您需要檢查isCancelled()中的doInBackground(),並在取消時中止。從您的通知中,您撥打asynctask致電cancel()

爲此,您需要將對AsyncTask的引用傳遞給您的通知活動。

例如:

您創建的AsyncTask是這樣的:

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

然後在你的主Activity創建AsyncTask這樣的:

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

然後,當你創建通知並且想要取消異步任務,只需將其稱爲zeTask即可。 MyAsyncTask需要與通知處於同一活動狀態,並且zeTask可以是一個變量,用於保存對AsyncTask的引用。

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

這就是我遇到的問題實際上是將'AsyncTask'的引用傳遞給上面的活動。我嘗試在'AsyncTask'上實現'Serializable',並在我設置爲'PendingIntent'的'Intent'上使用'putExtra()',但是我得到一個異常說該對象不可序列化。有沒有另外一種方法可以將AsyncTask的引用傳遞給我的活動? – Shino

+0

好吧,我認爲我這樣做的方式是行不通的。我發佈的通知任務僅用於在單擊狀態欄通知時用作PendingIntent。 「AsyncTask」實際上是在處理屏幕的類中,您可以單擊該按鈕下載文件。聽起來像我需要將我的'AsyncTask'移動到'DownloadNotificationActivity'並在該類的'onCreate'中執行它。然後處理通知的'onClick'事件。我會讓你知道發生了什麼。 – Shino

+0

試着在我以前的評論中說過的話沒有奏效。我感謝你的幫助@Motes。我已經更新了更多信息的主題(在底部)。我覺得我正在以這種錯誤的方式去做。我需要尋找其他選擇。我想過嘗試一個'Broadcast'和'BraodcastReceiver',但我不確定將一個接收器放在一個'AsyncTask'上的效果如何。 – Shino