听大牛们说写博客可以提高自己所以来尝试下,由于毕业不久也第一次写,大家见谅见谅!!!不过功能还是完美实现的。

     先上GitHub地址:https://github.com/1185719419/DuanDianUP


      什么是断点续传呢,简单点理解就是下载一个东西,中途你暂停了或者退出了,下次进来还想继续下载。那要知道哪些东西呢?你第二次下载肯定要知道第一次下载到了什么位置,这样才能从这个地方继续下载。存的话你可以存在本地,那你存的时候也要记录存到了什么位置,下次可以继续往里面存。


      具体思路如下:


      1.先用线程池开启一个线程获取apk的总长度length,并在本地创建一个长度为length的文件存放。这里存储用RandomAccessFile。


      2.再开一个线程下载apk,在这里要用到一个 HttpUrlConnection.setRequestProperty(“Range”,"bytes=0-500")方法:表示的是从文件的0位置开始下载到长度为500位置。


      3.设置文件存放位置,从什么地方开始存。


      4.记录每一次下载的长度并保存在数据库,由于内容较少我放在了SharedPreferences里面。这个长度就是下次开始下载的位置。


      5.当下载完后安装apk,并清除SharedPreferences里面的数据。




     1.先用线程池开启一个线程获取apk的总长度length,并在本地创建一个长度为length的文件存放。这里存储用RandomAccessFile。


ExecutorService cacheService = Executors.newCachedThreadPool();
cacheService.execute(new Runnable() {
    @Override
    public void run() {
        HttpURLConnection urlConnection = null;
        RandomAccessFile randomFile = null;
        try {
            URL url = new URL(Utils.MY_URL);
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setConnectTimeout(3000);
            urlConnection.setRequestMethod("GET");
            int length = -1;
            if (urlConnection.getResponseCode() == 200) {
                // 获得文件长度
                length = urlConnection.getContentLength();
                //创建相同大小的本地文件
                File dir = new File(DOWNLOAD_PATH);
                if (!dir.exists()) {
                    dir.mkdir();
                }
                File file = new File(dir, FILE_NAME);
                randomFile = new RandomAccessFile(file, "rwd");
                randomFile.setLength(length);
            }
            if (length <= 0) {
                return;
            }else{
                Message msg = Message.obtain();
                msg.what = length;
                handler.sendMessage(msg);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally { // 流的回收逻辑略
        }
    }
});


      2.再开一个线程下载apk,在这里要用到一个 HttpUrlConnection.setRequestProperty(“Range”,"bytes=0-500")方法:表示的是从文件的0位置开始下载到长度为500位置。


public void run() {
   super.run();
   
   InputStream inputStream = null; 
      try {
         URL urls = new URL(Utils.MY_URL);
         URLConnection rulConnection=urls.openConnection();//
         HttpURLConnection httConnection = (HttpURLConnection) rulConnection;
         httConnection.setConnectTimeout(3000);
         httConnection.setChunkedStreamingMode(0);
         httConnection.setRequestMethod("GET");
         //设置下载位置
         int start;
         httConnection.setRequestProperty("Range", "bytes="+infos.getNow()+"-"+infos.getLength());

         httConnection.connect();
         int zongLength = infos.getLength();
         int nowLength = infos.getNow();
         //设置文件存储位置
         savePosition(nowLength,zongLength);
         //保存数据总长度
         savaLength(zongLength);
         if (httConnection.getResponseCode() == 206) {
            inputStream = httConnection.getInputStream();  
            byte[] buffer = new byte[512];
            int len = -1;
            long time = System.currentTimeMillis(); 
            while((len = inputStream.read(buffer))!=-1){
               randomFile.write(buffer,0,len);
               int nowLegth = mySharedPreferences.getInt("now", -1)+len;

               Editor editor = mySharedPreferences.edit();
               editor.putString("url",Utils.MY_URL );
               editor.putInt("now",nowLegth );
               editor.commit();

               Message msg = Message.obtain();
               float shu = (float)nowLegth/zongLength;
               DecimalFormat df = new DecimalFormat("0.00");//格式化小数,.后跟几个零代表几位小数
               String s = df.format(shu*100);//返回的是String类型
               //发送下载百分百
               msg.obj = s;
               handler.sendMessage(msg);
               if (Utils.zhant) {
                  Editor editor4 = mySharedPreferences.edit();
                  editor4.putString("now_bfb",s);
                  editor4.commit();
                  return;
               }
            }
            installApk();
            Utils.ones = true;
            //初始化信息
            deleteApkMsg();
         }
         
      } catch (MalformedURLException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      }
}


      3.设置文件存放位置,从什么地方开始存。


private void savePosition(int nowLength,int zongLength){
   File file=new File(DOWNLOAD_PATH,FILE_NAME);
   try {
      randomFile=new RandomAccessFile(file,"rwd");
      randomFile.seek(nowLength);
   } catch (FileNotFoundException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
   } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
   }
   
}


      4.记录每一次下载的长度并保存在数据库,由于内容较少我放在了SharedPreferences里面。这个长度就是下次开始下载的位置。


while((len = inputStream.read(buffer))!=-1){
   randomFile.write(buffer,0,len);
   int nowLegth = mySharedPreferences.getInt("now", -1)+len;

   Editor editor = mySharedPreferences.edit();
   editor.putString("url",Utils.MY_URL );
   editor.putInt("now",nowLegth );
   editor.commit();

   Message msg = Message.obtain();
   float shu = (float)nowLegth/zongLength;
   DecimalFormat df = new DecimalFormat("0.00");//格式化小数,.后跟几个零代表几位小数
   String s = df.format(shu*100);//返回的是String类型
   //发送下载百分百
   msg.obj = s;
   handler.sendMessage(msg);
   if (Utils.zhant) {
      Editor editor4 = mySharedPreferences.edit();
      editor4.putString("now_bfb",s);
      editor4.commit();
      return;
   }
}


      5.当下载完后安装apk,并清除SharedPreferences里面的数据。


/**
 * 安装apk
 * */
private void installApk() {
   File apkfile = new File(DOWNLOAD_PATH, FILE_NAME);
   if (!apkfile.exists()) {
      Toast.makeText(context, "apk不存在", Toast.LENGTH_SHORT).show();
      return;
   }else{
      
   }
   Intent i = new Intent();
   i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   i.setAction(Intent.ACTION_VIEW);
   i.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive");
   context.startActivity(i);
}





/**
 * 清空数据
 * */
private void deleteApkMsg(){
   Editor editor = mySharedPreferences.edit();
   editor.putString("url","");
   editor.putInt("length",0);
   editor.putInt("start",0);
   editor.putInt("now",0);
   editor.commit();
}



代码我就粗略的复制一下了,具体可以在源代码里面看。