断点续传下载的实现:1. 当客户端发出 HTTP 请求时如果请求头是需要获取整个文件数据,那么成功时从服务器端得到的响应码为 200。如果只需要获取其中部分数据,成功时得到的响应码为 206。
setRequestProperty("Accept-Encoding", "identity");// 避免得到的服务器端文件字节数为零
setRequestProperty("Range", "bytes=" + bytes + "-" + lastIndex); // 分段请求头信息
2. 使用 RandomAccessFile 创建一个与服务器端的文件大小相同的空文件。当按下暂停按钮后需要记录下当前文件指针所指位置,继续下载时从记录位置开始写入。下载完毕后删除记录文件。
3. 将下载过程放在服务中并开启一个新线程。
MainActivity.java
- package com.example.breakpointdownload;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.os.Environment;
- import android.os.SystemClock;
- import android.support.v7.app.AppCompatActivity;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.View;
- import android.widget.Button;
- import android.widget.ProgressBar;
- import android.widget.Toast;
- public class MainActivity extends AppCompatActivity {
- private com.daimajia.numberprogressbar.NumberProgressBar pb;
- static final String MY_ACTION = "com.marszhou.breakpointdownload"; //自定义一个action private int count = 0; private Button bt; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); pb = (com.daimajia.numberprogressbar.NumberProgressBar) findViewById(R.id.pb); pb.setMax(100); //设置进度条最大值 findViewById(R.id.bt_stop); bt = (Button) findViewById(R.id.bt); registBroadcastReceiver(); bt.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (count % 2 == 0){ //开启一个服务执行下载任务 DlService.flag = false; startService(new Intent(getApplicationContext(), DlService.class)); count ++; bt.setText("暂停"); } else { //暂停下载的业务逻辑 DlService.flag = true; count ++; bt.setText("下载"); } } }); Log.e("getFilesDir()", getFilesDir().getPath()); Log.e("Environment", Environment.getExternalStorageDirectory().getPath()); Log.e("package", getPackageName()); } public void registBroadcastReceiver() { //动态注册广播接受器 IntentFilter intentFilter = new IntentFilter(MY_ACTION); registerReceiver(new MyReceiver(), intentFilter); } public class MyReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { int value = intent.getIntExtra("value", 0); switch (value) { case 0xfffffffd: Toast.makeText(getApplicationContext(), "网络连接异常!", Toast.LENGTH_LONG).show(); count --; bt.setText("下载"); break; case 0xfffffffe: //开始下载 Toast.makeText(getApplicationContext(), "开始下载...", Toast.LENGTH_SHORT).show(); break; case 0xffffffff: //下载完成 stopService(new Intent(getApplicationContext(), DlService.class)); Toast.makeText(getApplicationContext(), "下载停止", Toast.LENGTH_SHORT).show(); break; default: pb.setProgress(value); //更新进度条 break; } } }}
DownloadService.java
- package com.example.breakpointdownload;
- import android.app.Service;
- import android.content.Context;
- import android.content.Intent;
- import android.content.SharedPreferences;
- import android.os.AsyncTask;
- import android.os.Environment;
- import android.os.IBinder;
- import android.text.TextUtils;
- import android.util.Log;
- import java.io.BufferedReader;
- import java.io.File;
- import java.io.FileNotFoundException;
- import java.io.FileReader;
- import java.io.FileWriter;
- import java.io.InputStream;
- import java.io.RandomAccessFile;
- import java.net.HttpURLConnection;
- import java.net.URL;
- public class DlService extends Service {
- static boolean flag = false;@Override public void onCreate() {
- super.onCreate();
- Log.i("service", "服务启动了");
- }@Override public int onStartCommand(Intent intent, int flags, int startId) {
- MyTask myTask = new MyTask();
- myTask.execute();
- return super.onStartCommand(intent, flags, startId);
- }@Override public void onDestroy() {
- super.onDestroy();
- Log.i("service", "服务销毁了");
- }@Override public IBinder onBind(Intent intent) {
- return null;
- }
- public class MyTask extends AsyncTask {
- String MY_ACTION = MainActivity.MY_ACTION;@Override protected void onPostExecute(Object o) { //发送0xff表示下载完成 super.onPostExecute(o); Intent in = new Intent(MY_ACTION); in.putExtra("value", 0xffffffff); sendBroadcast(in); } @Override protected void onPreExecute() { //发送0x11表示开始下载 super.onPreExecute(); Intent in = new Intent(MY_ACTION); in.putExtra("value", 0xfffffffe); sendBroadcast(in); } @Override protected Object doInBackground(Object[] params) { //执行下载任务 try { File file = new File(Environment.getExternalStorageDirectory(), "163music.exe"); RandomAccessFile accessFile = new RandomAccessFile(file, "rw"); SharedPreferences sp = getSharedPreferences("index", Context.MODE_PRIVATE); int bytes = sp.getInt("bytes", 0); if (bytes <= 0) { //第一次下载 URL url = new URL("http://sw.bos.baidu.com/sw-search-sp/software/1fe4c5b865602/cloudmusicsetup_2.1.1.30494_baidupc.exe"); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); urlConnection.setRequestMethod("GET"); urlConnection.setDoInput(true); urlConnection.setRequestProperty("Accept-Encoding", "identity"); //设置请求参数 urlConnection.setConnectTimeout(1000*10); Log.e("code", urlConnection.getResponseCode() + ""); if (urlConnection.getResponseCode() == 200) { int total = urlConnection.getContentLength(); //获取网络资源大小 accessFile.setLength(total); int lastIndex = (int) file.length(); InputStream inputStream = urlConnection.getInputStream(); int i, count = 0; byte buffer[] = new byte[1024]; while ((i = inputStream.read(buffer)) != -1) { if (flag) break; count += i; int progress = (int) (count * 100.0 / total); accessFile.write(buffer, 0, i); Intent in = new Intent(MY_ACTION); in.putExtra("value", progress); sendBroadcast(in); } Log.e("index中的内容", accessFile.getFilePointer() + ""); SharedPreferences.Editor editor = sp.edit(); editor.putInt("bytes", (int) accessFile.getFilePointer()); editor.commit(); if (count == lastIndex){ //删除计数文件 File file3= new File("/data/data/" + getPackageName() + "/shared_prefs","index.xml"); if (file3.exists()) file3.delete(); } } } else { //断点下载 // Log.e("index内容", index_str); // int index = Integer.parseInt(index_str); Log.e("index内容", bytes + ""); int lastIndex = (int) file.length(); //获取原始资源长度 Log.e("lastindex内容", lastIndex + ""); accessFile.seek(bytes); URL url = new URL("http://sw.bos.baidu.com/sw-search-sp/software/1fe4c5b865602/cloudmusicsetup_2.1.1.30494_baidupc.exe"); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); urlConnection.setRequestMethod("GET"); urlConnection.setDoInput(true); urlConnection.setRequestProperty("Accept-Encoding", "identity"); //设置请求参数 urlConnection.setRequestProperty("Range", "bytes=" + bytes + "-" + lastIndex); //设置分段下载的头信息。 Range:做分段数据请求用的。 urlConnection.setConnectTimeout(1000*10); Log.e("code---", urlConnection.getResponseCode() + ""); if (urlConnection.getResponseCode() == 206) { //200:请求全部资源成功, 206代表部分资源请求成功 InputStream inputStream = urlConnection.getInputStream(); int i, count = bytes; byte buffer[] = new byte[1024]; while ((i = inputStream.read(buffer)) != -1) { if (flag) break; accessFile.write(buffer, 0, i); count += i; int progress = (int) (count * 100.0 / lastIndex); Intent in = new Intent(MY_ACTION); in.putExtra("value", progress); sendBroadcast(in); } Log.e("lastIndex", String.valueOf(lastIndex)); Log.e("count", String.valueOf(count));SharedPreferences.Editor editor = sp.edit(); editor.putInt("bytes", (int) accessFile.getFilePointer()); editor.commit(); if (count == lastIndex){ //删除计数文件 File file3= new File("/data/data/" + getPackageName() + "/shared_prefs","index.xml"); if (file3.exists()) file3.delete(); } } } } catch (Exception e) { Intent in = new Intent(MY_ACTION); in.putExtra("value", 0xfffffffd); sendBroadcast(in); e.printStackTrace(); } return null; } }}
加上用户权限
效果如下:
就爱阅读 www.92to.com 网友整理上传, 为您提供最全的知识大全, 期待您的分享,转载请注明出处。
来源: