65.9K
CodeProject 正在变化。 阅读更多。
Home

Android 下载管理器教程:如何使用下载管理器从互联网下载文件

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2投票s)

2016年7月17日

CPOL

3分钟阅读

viewsIcon

89565

Android 下载管理器教程:如何使用下载管理器从互联网下载文件

我们推出了另一个关于如何使用Android下载管理器下载一个或多个文件的精彩教程。 下载管理器在 Android 2.3 (API level 9) 中被引入。 Android下载管理器的一个巨大优势在于它优化了后台运行的长时间下载的处理。下载管理器处理 HTTP 连接,监控连接变化,重新启动,并确保每个下载成功完成。 如果您想下载大文件/流媒体,那么您不能使用 Retrofit 或 Volley,两者都建议使用 DownloadManager,它支持恢复和进度通知。

在本教程中,我们将涵盖以下主题

  1. 使用Android下载管理器同时下载图片和音乐。
  2. 使用开关随时显示所有下载的状态。
  3. 将它们保存到外部驱动器中的特定位置。
  4. 下载完成后发送通知。
  5. 取消所有下载的能力。

我们将从以下 URL 下载图片和音乐

图片 URL http://androidtutorialpoint.comli.com/DownloadManager/Beauty.jpg
音乐 URL http://androidtutorialpoint.comli.com/DownloadManager/AndroidDownloadManager.mp3

先决条件

  1. 您的 PC(Unix 或 Windows)上安装了 Android Studio。
  2. 配备 Android Studio 的实时安卓设备(智能手机或平板电脑)。
  3. 对 Android 生命周期以及 Android Studio 中使用的不同类和函数的基本了解。

创建新项目

添加权限

将以下权限添加到您的 AndroidManifest.xml 文件中

AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

现在,我们将通过每个函数详细描述每个主题,这些函数可以通过 Android 下载管理器实现。 我们为下载数据、显示状态、完成下载通知和取消下载创建了单独的函数。

生成 URI

首先,我们必须从 URL 生成 URI。 因此,在这里,我们将为图片和音乐 URL 生成两个 URI。

Uri image_uri = Uri.parse("http://androidtutorialpoint.comli.com/DownloadManager/Beauty.jpg");
Uri music_uri = Uri.parse
("http://androidtutorialpoint.comli.com/DownloadManager/AndroidDownloadManager.mp3");

使用 Android 下载管理器从 URL 下载数据

DownloadData() 函数将用于从 Internet 下载数据。

DownloadData

private long DownloadData (Uri uri, View v) {

        long downloadReference;

        // Create request for android download manager
        downloadManager = (DownloadManager)getSystemService(DOWNLOAD_SERVICE);
        DownloadManager.Request request = new DownloadManager.Request(uri);

        //Setting title of request
        request.setTitle("Data Download");

        //Setting description of request
        request.setDescription("Android Data download using DownloadManager.");

        //Set the local destination for the downloaded file to a path 
        //within the application's external files directory
        if(v.getId() == R.id.DownloadMusic)
          request.setDestinationInExternalFilesDir(MainActivity.this, 
          Environment.DIRECTORY_DOWNLOADS,"AndroidTutorialPoint.mp3");
        else if(v.getId() == R.id.DownloadImage)
          request.setDestinationInExternalFilesDir(MainActivity.this, 
          Environment.DIRECTORY_DOWNLOADS,"AndroidTutorialPoint.jpg");

        //Enqueue download and save into referenceId
        downloadReference = downloadManager.enqueue(request);

        Button DownloadStatus = (Button) findViewById(R.id.DownloadStatus);
        DownloadStatus.setEnabled(true);
        Button CancelDownload = (Button) findViewById(R.id.CancelDownload);
        CancelDownload.setEnabled(true);

        return downloadReference;
    }

以上代码的描述

  1. downloadReference: 这是一个唯一的 ID,我们将引用它来请求特定的下载。
  2. request: 通过传递 DOWNLOAD_SERVICE 来使用 getSystemService 创建 DownloadManager 的实例。 在下一条语句中使用 DownloadManager.Request(uri) 生成一个新请求。
  3. setDestinationInExternalFilesDir: 这将用于将文件保存在外部下载文件夹中。
  4. downloadManager.enqueue(request): 将与请求对应的新下载排队。 一旦下载管理器准备好执行它并且连接可用,下载将自动开始。

检查下载状态

Check_Image_Status() 函数将用于获取图片下载的状态。 参考以下代码

Check_Image_Status

private void Check_Image_Status(long Image_DownloadId) {

        DownloadManager.Query ImageDownloadQuery = new DownloadManager.Query();
        //set the query filter to our previously Enqueued download
        ImageDownloadQuery.setFilterById(Image_DownloadId);

        //Query the download manager about downloads that have been requested.
        Cursor cursor = downloadManager.query(ImageDownloadQuery);
        if(cursor.moveToFirst()){
            DownloadStatus(cursor, Image_DownloadId);
        }
    }

以上代码的描述

  1. DownloadManager.Query(): 这用于过滤 Android 下载管理器查询。 在这里,我们在 setFilterById() 中提供 Image_DownloadId 以仅包含具有给定 ID 的下载。
  2. downloadManager.query(ImageDownloadQuery): 这用于查询 Android 下载管理器关于已请求的下载。
  3. 游标: 在下载结果集上的 游标 ,其列由所有 COLUMN_* 常量组成。 现在,此游标将用于在 DownloadStatus() 函数中获取下载状态。

DownloadStatus

private void DownloadStatus(Cursor cursor, long DownloadId){

        //column for download  status
        int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS);
        int status = cursor.getInt(columnIndex);
        //column for reason code if the download failed or paused
        int columnReason = cursor.getColumnIndex(DownloadManager.COLUMN_REASON);
        int reason = cursor.getInt(columnReason);
        //get the download filename
        int filenameIndex = cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME);
        String filename = cursor.getString(filenameIndex);

        String statusText = "";
        String reasonText = "";

        switch(status){
            case DownloadManager.STATUS_FAILED:
                statusText = "STATUS_FAILED";
                switch(reason){
                    case DownloadManager.ERROR_CANNOT_RESUME:
                        reasonText = "ERROR_CANNOT_RESUME";
                        break;
                    case DownloadManager.ERROR_DEVICE_NOT_FOUND:
                        reasonText = "ERROR_DEVICE_NOT_FOUND";
                        break;
                    case DownloadManager.ERROR_FILE_ALREADY_EXISTS:
                        reasonText = "ERROR_FILE_ALREADY_EXISTS";
                        break;
                    case DownloadManager.ERROR_FILE_ERROR:
                        reasonText = "ERROR_FILE_ERROR";
                        break;
                    case DownloadManager.ERROR_HTTP_DATA_ERROR:
                        reasonText = "ERROR_HTTP_DATA_ERROR";
                        break;
                    case DownloadManager.ERROR_INSUFFICIENT_SPACE:
                        reasonText = "ERROR_INSUFFICIENT_SPACE";
                        break;
                    case DownloadManager.ERROR_TOO_MANY_REDIRECTS:
                        reasonText = "ERROR_TOO_MANY_REDIRECTS";
                        break;
                    case DownloadManager.ERROR_UNHANDLED_HTTP_CODE:
                        reasonText = "ERROR_UNHANDLED_HTTP_CODE";
                        break;
                    case DownloadManager.ERROR_UNKNOWN:
                        reasonText = "ERROR_UNKNOWN";
                        break;
                }
                break;
            case DownloadManager.STATUS_PAUSED:
                statusText = "STATUS_PAUSED";
                switch(reason){
                    case DownloadManager.PAUSED_QUEUED_FOR_WIFI:
                        reasonText = "PAUSED_QUEUED_FOR_WIFI";
                        break;
                    case DownloadManager.PAUSED_UNKNOWN:
                        reasonText = "PAUSED_UNKNOWN";
                        break;
                    case DownloadManager.PAUSED_WAITING_FOR_NETWORK:
                        reasonText = "PAUSED_WAITING_FOR_NETWORK";
                        break;
                    case DownloadManager.PAUSED_WAITING_TO_RETRY:
                        reasonText = "PAUSED_WAITING_TO_RETRY";
                        break;
                }
                break;
            case DownloadManager.STATUS_PENDING:
                statusText = "STATUS_PENDING";
                break;
            case DownloadManager.STATUS_RUNNING:
                statusText = "STATUS_RUNNING";
                break;
            case DownloadManager.STATUS_SUCCESSFUL:
                statusText = "STATUS_SUCCESSFUL";
                reasonText = "Filename:\n" + filename;
                break;
        }

        if(DownloadId == Music_DownloadId) {

            Toast toast = Toast.makeText(MainActivity.this,
                    "Music Download Status:" + "\n" + statusText + "\n" +
                            reasonText,
                    Toast.LENGTH_LONG);
            toast.setGravity(Gravity.TOP, 25, 400);
            toast.show();

        }
        else {

            Toast toast = Toast.makeText(MainActivity.this,
                    "Image Download Status:"+ "\n" + statusText + "\n" +
                            reasonText,
                    Toast.LENGTH_LONG);
            toast.setGravity(Gravity.TOP, 25, 400);
            toast.show();

            // Make a delay of 3 seconds so that next toast (Music Status) will not merge with this one.
            final Handler handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                }
            }, 3000);
        }
    }

以上代码的解释性很强。 我们只是根据 Android 下载管理器返回的 COLUMN_REASON 的值来打印状态。

同样,我们已经创建了用于检查音乐文件状态的函数,即 Check_Music_Status()

取消所有下载

要取消下载,我们只需使用

downloadManager.remove(Image_DownloadId);
downloadManager.remove(Music_DownloadId);

广播接收器

我们教程的最后一部分是广播接收器。 Android DownloadManager 在下载完成后发送 ACTION_DOWNLOAD_COMPLETE 广播意图。 因此,我们将在下载完成时设置过滤器并注册接收器

IntentFilter filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
registerReceiver(downloadReceiver, filter);

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(referenceId == Image_DownloadId) {

                Toast toast = Toast.makeText(MainActivity.this,
                        "Image Download Complete", Toast.LENGTH_LONG);
                toast.setGravity(Gravity.TOP, 25, 400);
                toast.show();
            }
            else if(referenceId == Music_DownloadId) {

                Toast toast = Toast.makeText(MainActivity.this,
                        "Music Download Complete", Toast.LENGTH_LONG);
                toast.setGravity(Gravity.TOP, 25, 400);
                toast.show();
            }
        }
    };

因此,在上面的代码中,接收到广播 Intent,比较其 referenceId,并相应地显示 Toast 消息。

因此,最后,我们涵盖了 Android 下载管理器的所有方面。 如果您还有任何疑问或建议,请评论或给我们发邮件。

© . All rights reserved.