Android 下载支持断点续传

作为一名经验丰富的开发者,我将教会你如何实现“Android 下载支持断点续传”。在开始之前,我们先来了解整个实现的流程。

实现步骤

下面是实现该功能的步骤表格:

步骤 描述
步骤一 检查网络连接和权限
步骤二 创建下载任务
步骤三 启动下载任务
步骤四 监听下载进度
步骤五 保存已下载的文件
步骤六 实现断点续传

现在我们逐步来看每一步需要做什么,并给出相应的代码。

步骤一:检查网络连接和权限

在开始下载之前,我们需要检查设备是否连接到网络,并且需要在 AndroidManifest.xml 文件中添加网络权限。

// 检查网络连接
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo == null || !networkInfo.isConnected()) {
    // 没有网络连接
    return;
}

// 添加网络权限
<uses-permission android:name="android.permission.INTERNET" />

步骤二:创建下载任务

我们需要创建一个下载任务,指定下载的 URL 和存储路径。

String url = " // 下载的文件 URL
String outputFile = "/sdcard/file.zip"; // 下载的文件存储路径

DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setDestinationUri(Uri.fromFile(new File(outputFile)));

步骤三:启动下载任务

使用 DownloadManager 发起下载任务,并获取下载任务的唯一 ID。

DownloadManager downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
long downloadId = downloadManager.enqueue(request);

步骤四:监听下载进度

我们需要注册一个 BroadcastReceiver 来监听下载进度,并更新 UI。

BroadcastReceiver receiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
            // 下载完成
        } else if (DownloadManager.ACTION_NOTIFICATION_CLICKED.equals(action)) {
            // 通知被点击
        } else if (DownloadManager.ACTION_VIEW_DOWNLOADS.equals(action)) {
            // 查看下载列表
        } else {
            // 下载进度更新
            long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
            DownloadManager.Query query = new DownloadManager.Query();
            query.setFilterById(downloadId);
            Cursor cursor = downloadManager.query(query);
            if (cursor.moveToFirst()) {
                int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
                int progress = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
                int total = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
                // 更新下载进度
            }
            cursor.close();
        }
    }
};

registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_NOTIFICATION_CLICKED));
registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_VIEW_DOWNLOADS));
registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_STATUS));

步骤五:保存已下载的文件

在下载完成后,我们需要将下载的文件保存到指定的位置。

public void saveDownloadedFile(long downloadId, String outputFile) {
    DownloadManager.Query query = new DownloadManager.Query();
    query.setFilterById(downloadId);
    Cursor cursor = downloadManager.query(query);
    if (cursor.moveToFirst()) {
        int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
        if (status == DownloadManager.STATUS_SUCCESSFUL) {
            String uriString = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
            if (uriString != null) {
                Uri uri = Uri.parse(uriString);
                InputStream inputStream = null;
                OutputStream outputStream = null;
                try {
                    inputStream = getContentResolver().openInputStream(uri);
                    outputStream = new FileOutputStream(outputFile);
                    byte[] buffer = new byte[1024];
                    int length;
                    while ((length = inputStream.read(buffer)) != -1) {
                        outputStream.write(buffer, 0, length);
                    }
                } catch (IOException e) {
                    // 保存文件失败
                } finally {
                    if (inputStream != null) {
                        try {
                            inputStream.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (outputStream != null) {