Android 文件断点续传

import  java.io.File;
import  java.net.URL;
import  java.net.URLConnection;
import  android.app.Activity;
import  android.os.Bundle;
import  android.os.Environment;
import  android.os.Handler;
import  android.os.Message;
import  android.view.View;
import  android.view.View.OnClickListener;
import  android.widget.Button;
import  android.widget.EditText;
import  android.widget.ProgressBar;
import  android.widget.TextView;
/**
  *  Copyright (C) 2010 ideasandroid
  *  演示android多线程下载
  *  欢迎访问http://www.ideasandroid.com
  *  让程序开发不再那么神秘
  */
public  class  FileDownloadDemo  extends  Activity {
  
     private  EditText downloadUrl;
     private  EditText downloadFileName;
     private  EditText downloadThreadNum;
     private  Button downloadBt;
     private  ProgressBar downloadProgressBar;
     private  TextView progressMessage;
     private  int  downloadedSize =  0 ;
     private  int  fileSize =  0 ;
  
     @Override
     public  void  onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.main);
  
         downloadUrl = (EditText) findViewById(R.id.downloadUrl);
         downloadFileName = (EditText) findViewById(R.id.downloadFileName);
         downloadThreadNum = (EditText) findViewById(R.id.downloadThreadNum);
         progressMessage = (TextView) findViewById(R.id.progressMessage);
         downloadBt = (Button) findViewById(R.id.downloadBt);
         downloadProgressBar = (ProgressBar) findViewById(R.id.downloadProgressBar);
         downloadProgressBar.setVisibility(View.VISIBLE);
         downloadProgressBar.setMax( 100 );
         downloadProgressBar.setProgress( 0 );
         downloadBt.setOnClickListener( new  OnClickListener() {
             public  void  onClick(View v) {
                 download();
             }
         });
     }
  
     private  void  download() {
         // 获取SD卡目录
         String dowloadDir = Environment.getExternalStorageDirectory()
                 "/ideasdownload/" ;
         File file =  new  File(dowloadDir);
         //创建下载目录
         if  (!file.exists()) {
             file.mkdirs();
         }
  
         //读取下载线程数,如果为空,则单线程下载
         int  downloadTN = Integer.valueOf( "" .equals(downloadThreadNum.getText()
                 .toString()) ?  "1"  : downloadThreadNum.getText().toString());
         //如果下载文件名为空则获取Url尾为文件名
         int  fileNameStart = downloadUrl.getText().toString().lastIndexOf( "/" );
         String fileName =  "" .equals(downloadFileName.getText().toString()) ? downloadUrl
                 .getText().toString().substring(fileNameStart)
                 : downloadFileName.getText().toString();
         //开始下载前把下载按钮设置为不可用
         downloadBt.setClickable( false );
         //进度条设为0
         downloadProgressBar.setProgress( 0 );
         //启动文件下载线程
         new  downloadTask(downloadUrl.getText().toString(), Integer
                 .valueOf(downloadTN), dowloadDir + fileName).start();
     }
  
     Handler handler =  new  Handler() {
         @Override
         public  void  handleMessage(Message msg) {
             //当收到更新视图消息时,计算已完成下载百分比,同时更新进度条信息
             int  progress = (Double.valueOf((downloadedSize *  1.0  / fileSize *  100 ))).intValue();
             if  (progress ==  100 ) {
                 downloadBt.setClickable( true );
                 progressMessage.setText( "下载完成!" );
             else  {
                 progressMessage.setText( "当前进度:"  + progress +  "%" );
             }
             downloadProgressBar.setProgress(progress);
         }
  
     };
  
     /**
      * @author ideasandroid
      * 主下载线程
      */
     public  class  downloadTask  extends  Thread {
         private  int  blockSize, downloadSizeMore;
         private  int  threadNum =  5 ;
         String urlStr, threadNo, fileName;
  
         public  downloadTask(String urlStr,  int  threadNum, String fileName) {
             this .urlStr = urlStr;
             this .threadNum = threadNum;
             this .fileName = fileName;
         }
  
         @Override
         public  void  run() {
             FileDownloadThread[] fds =  new  FileDownloadThread[threadNum];
             try  {
                 URL url =  new  URL(urlStr);
                 URLConnection conn = url.openConnection();
                 //获取下载文件的总大小
                 fileSize = conn.getContentLength();
                 //计算每个线程要下载的数据量
                 blockSize = fileSize / threadNum;
                 // 解决整除后百分比计算误差
                 downloadSizeMore = (fileSize % threadNum);
                 File file =  new  File(fileName);
                 for  ( int  i =  0 ; i < threadNum; i++) {
                     //启动线程,分别下载自己需要下载的部分
                     FileDownloadThread fdt =  new  FileDownloadThread(url, file,
                             i * blockSize, (i +  1 ) * blockSize -  1 );
                     fdt.setName( "Thread"  + i);
                     fdt.start();
                     fds[i] = fdt;
                 }
                 boolean  finished =  false ;
                 while  (!finished) {
                     // 先把整除的余数搞定
                     downloadedSize = downloadSizeMore;
                     finished =  true ;
                     for  ( int  i =  0 ; i < fds.length; i++) {
                         downloadedSize += fds[i].getDownloadSize();
                         if  (!fds[i].isFinished()) {
                             finished =  false ;
                         }
                     }
                     //通知handler去更新视图组件
                     handler.sendEmptyMessage( 0 );
                     //休息1秒后再读取下载进度
                     sleep( 1000 );
                 }
             catch  (Exception e) {
  
             }
  
         }
     }
}

import  java.io.BufferedInputStream;
import  java.io.File;
import  java.io.IOException;
import  java.io.RandomAccessFile;
import  java.net.URL;
import  java.net.URLConnection;
  
import  android.util.Log;
/**
  *  Copyright (C) 2010 ideasandroid
  *  演示android多线程下载
  *  欢迎访问http://www.ideasandroid.com
  *  让程序开发不再那么神秘
  *  
  *  单个下载线程
  */
public  class  FileDownloadThread  extends  Thread{
     private  static  final  int  BUFFER_SIZE= 1024 ;
     private  URL url;
     private  File file;
     private  int  startPosition;
     private  int  endPosition;
     private  int  curPosition;
     //用于标识当前线程是否下载完成
     private  boolean  finished= false ;
     private  int  downloadSize= 0 ;
     public  FileDownloadThread(URL url,File file, int  startPosition, int  endPosition){
         this .url=url;
         this .file=file;
         this .startPosition=startPosition;
         this .curPosition=startPosition;
         this .endPosition=endPosition;
     }
     @Override
     public  void  run() {
         BufferedInputStream bis =  null ;
         RandomAccessFile fos =  null ;                                               
         byte [] buf =  new  byte [BUFFER_SIZE];
         URLConnection con =  null ;
         try  {
             con = url.openConnection();
             con.setAllowUserInteraction( true );
             //设置当前线程下载的起点,终点
             con.setRequestProperty( "Range" "bytes="  + startPosition +  "-"  + endPosition);
             //使用java中的RandomAccessFile 对文件进行随机读写操作
             fos =  new  RandomAccessFile(file,  "rw" );
             //设置开始写文件的位置
             fos.seek(startPosition);
             bis =  new  BufferedInputStream(con.getInputStream());  
             //开始循环以流的形式读写文件
             while  (curPosition < endPosition) {
                 int  len = bis.read(buf,  0 , BUFFER_SIZE);                
                 if  (len == - 1 ) {
                     break ;
                 }
                 fos.write(buf,  0 , len);
                 curPosition = curPosition + len;
                 if  (curPosition > endPosition) {
                     downloadSize+=len - (curPosition - endPosition) +  1 ;
                 else  {
                     downloadSize+=len;
                 }
             }
             //下载完成设为true
             this .finished =  true ;
             bis.close();
             fos.close();
         catch  (IOException e) {
           Log.d(getName() + " Error:" , e.getMessage());
         }
     }
  
     public  boolean  isFinished(){
         return  finished;
     }
  
     public  int  getDownloadSize() {
         return  downloadSize;
     }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值