断点续传下载的实现

实现断点续传的思路

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;
        }
    }
}

加上用户权限

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

效果如下:
这里写图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值