Android断点续传与本地下载实现教程

1 下载量 87 浏览量 更新于2024-09-01 收藏 71KB PDF 举报
“Android实现简单断点续传和下载到本地功能” 在Android开发中,实现断点续传和文件下载到本地是常见的需求,这通常用于大文件下载,确保用户即使在下载过程中中断,也能在之后继续从上次停止的地方开始下载。本教程将介绍如何在Android应用中实现这一功能。 首先,我们需要在项目中引入依赖库。这里使用的是`android-async-http`库,它是一个轻量级的异步HTTP客户端,支持文件下载。在项目的`build.gradle`文件中添加以下依赖: ```groovy dependencies { compile 'com.loopj.android:android-async-http:1.4.9' } ``` 接着,确保在AndroidManifest.xml文件中添加必要的权限,以便应用程序能够访问网络和外部存储: ```xml <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> ``` 在布局文件中,我们可以创建一个简单的用户界面,包含一个按钮用于启动下载,并显示进度信息。例如,一个基本的`activity_main.xml`布局可能如下所示: ```xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.lv.mama.test004.MainActivity"> <Button android:id="@+id/button_start_download" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="开始下载" /> <ProgressBar android:id="@+id/progress_bar" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/button_start_download" /> <TextView android:id="@+id/text_view_status" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/progress_bar" /> </RelativeLayout> ``` 在`MainActivity`中,我们需要处理按钮点击事件并开始下载。首先,初始化UI组件,并在按钮点击时启动下载任务: ```java public class MainActivity extends AppCompatActivity { private Button startDownloadButton; private ProgressBar progressBar; private TextView statusTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); startDownloadButton = findViewById(R.id.button_start_download); progressBar = findViewById(R.id.progress_bar); statusTextView = findViewById(R.id.text_view_status); startDownloadButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startDownload(); } }); } private void startDownload() { // 这里实现下载逻辑 } } ``` 下载逻辑的核心在于使用`AsyncHttpClient`创建一个下载任务,该任务能够检查已下载的文件大小,然后从上次中断的位置继续下载。这需要实现一个`AsyncHttpResponseHandler`,并在其中处理下载进度和完成情况: ```java private void startDownload() { final String downloadUrl = "http://example.com/file.mp4"; final File outputFile = new File(Environment.getExternalStorageDirectory(), "file.mp4"); if (outputFile.exists()) { // 检查已下载的文件大小 long fileSize = outputFile.length(); // 创建请求,设置从已下载的字节数开始 RequestParams params = new RequestParams(); params.setOffset(fileSize); AsyncHttpClient client = new AsyncHttpClient(); client.get(downloadUrl, params, new AsyncHttpResponseHandler() { @Override public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) { // 将接收到的数据写入文件 FileOutputStream fos = null; try { fos = new FileOutputStream(outputFile, true); fos.write(responseBody); fos.flush(); updateProgress(responseBody.length); } catch (IOException e) { e.printStackTrace(); } finally { if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } @Override public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) { // 处理下载失败的情况 } @Override public void onProgress(long bytesWritten, long totalSize) { // 更新进度条 updateProgress(bytesWritten + fileSize); } }); } else { // 如果文件不存在,从头开始下载 // 创建请求 AsyncHttpClient client = new AsyncHttpClient(); client.get(downloadUrl, new AsyncHttpResponseHandler() { // ... 实现成功、失败和进度更新的回调 }); } } private void updateProgress(long bytesRead) { int progress = (int) (bytesRead * 100 / totalFileSize); progressBar.setProgress(progress); statusTextView.setText("已下载:" + bytesRead + " / " + totalFileSize); } ``` 以上代码实现了简单的断点续传和下载到本地的功能。当用户点击“开始下载”按钮时,程序会检查目标文件是否存在以及已下载的字节数。如果文件存在,它会从已下载的字节数开始继续下载;如果不存在,就从头开始。在下载过程中,通过`onProgress`回调更新进度条和状态文本。 请注意,实际应用中还需要考虑更多细节,如错误处理、线程同步、网络状态检测等。此外,由于Android 6.0以后需要动态申请`WRITE_EXTERNAL_STORAGE`和`READ_EXTERNAL_STORAGE`权限,因此在运行时需要检查并请求这些权限。