1

我正在尝试通过使用下载管理器下载 apk 来更新我的应用程序。我已经注册了广播接收器来收听并DownloadManager.ACTION_DOWNLOAD_COMPLETE在方法中MainActivity打开 apk onReceive。以下是代码:

public class MainActivity extends CordovaActivity {
private long downloadReference;
private DownloadManager downloadManager;
private IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    registerReceiver(downloadReceiver, intentFilter);

}

public void updateApp(String url) {
    //start downloading the file using the download manager
    downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
    Uri Download_Uri = Uri.parse(url);
    DownloadManager.Request request = new DownloadManager.Request(Download_Uri);
    request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
    request.setAllowedOverRoaming(false);
    request.setDestinationInExternalFilesDir(MainActivity.this, Environment.DIRECTORY_DOWNLOADS, "myapk.apk");
    downloadReference = downloadManager.enqueue(request);
}


@Override
public void onDestroy() {
    //unregister your receivers
    this.unregisterReceiver(downloadReceiver);
    super.onDestroy();
}

private BroadcastReceiver downloadReceiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {

        //check if the broadcast message is for our Enqueued download
        long referenceId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
        if (downloadReference == referenceId) {

            //start the installation of the latest version
                    Intent installIntent = new Intent(Intent.ACTION_VIEW);
                installIntent.setDataAndType(downloadManager.getUriForDownloadedFile(downloadReference),
                        "application/vnd.android.package-archive");
                installIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(installIntent);

        }

    }

};

}

updateApp(url)在 UI 中单击按钮时调用。现在点击按钮后,下载开始。假设应用程序在启动下载后关闭(接收方未注册),当应用程序再次启动时,我遇到了两种情况。

  1. 我的应用程序重新启动后之前的下载完成 -
    downloadReference丢失并且当我的接收器接收到广播时,referenceId不会与 相同downloadReference,因此installIntent永远不会启动。所以我必须再次点击更新按钮并开始下载。有没有办法避免这个问题?

  2. 上一次下载在我的应用程序重新启动之前完成 - 在新启动的活动中无法知道我上一次下载是否完成。我必须再次单击按钮并重新启动下载。有没有办法为下载管理器启用粘性广播?

4

1 回答 1

1

为此,您必须将下载参考存储在您的偏好中。然后,您可以使用DownloadManager.Query()查询 DownloadManager ,这将返回一个光标,其中包含DownloadManager您的应用发布的所有下载请求。然后你可以匹配downloadReferenceid 然后检查你的下载状态。如果它已完成,那么您可以从DownloadManager.COLUMN_LOCAL_FILENAME.

private void updateDownloadStatus(long downloadReference) {      
  DownloadManager.Query query = new DownloadManager.Query();

  // if you have stored the downloadReference. Else you have to loop through the cursor.
  query.setFilterById(downloadReference); 

  Cursor cursor = null;

  try {
    cursor = DOWNLOAD_MANAGER.query(query);
    if (cursor == null || !cursor.moveToFirst()) {
      // restart download
      return;
    }
    float bytesDownloaded =
        cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
    float bytesTotal =
        cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
    int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS);
    int downloadStatus = cursor.getInt(columnIndex);
    int columnReason = cursor.getColumnIndex(DownloadManager.COLUMN_REASON);
    int failureStatus = cursor.getInt(columnReason);
    int filePathInt = cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME);
    String filePath = cursor.getString(filePathInt);

    switch (downloadStatus) {
      case DownloadManager.STATUS_FAILED:
      case DownloadManager.ERROR_FILE_ERROR:
        // restart download
        break;

      case DownloadManager.STATUS_SUCCESSFUL:
        if (filePath != null) {
          //got the file 
        } else {
          //restart
        }
        break;

      case DownloadManager.STATUS_PENDING:
      case DownloadManager.STATUS_RUNNING:
      case DownloadManager.STATUS_PAUSED:
        /// wait till download finishes
        break;
    }
  } catch (Exception e) {
    Log.e("Error","message" + e.getMessage(), e);
  } finally {
    if (cursor != null) {
      cursor.close();
    }
  }
}
于 2016-06-29T13:19:37.403 回答