您的位置:首页 > 移动开发 > Android开发

Android实现文件下载断点续传

2011-05-04 09:57 686 查看
其实在我们日常生活中,断点下载是很正常的,比如你在下载游戏,突然间没有电了,要是你的手机不支持断点下载的话,那就完了,你就得从新下载,这样会很浪费你的流量和时间的。如果有了断点下载的话,我们就不怕这样的事情发生了。下面我们就看看这个断点下载是怎么实现的。

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;
importandroid.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
importandroid.widget.TextView;

public class FileDownloadDemo extends Activity {

private EditTextdownloadUrl;
private EditTextdownloadFileName;
private EditTextdownloadThreadNum;
private ButtondownloadBt;
private ProgressBardownloadProgressBar;
private TextViewprogressMessage;
private int downloadedSize = 0;
private int fileSize = 0;

@Override
public void onCreate(BundlesavedInstanceState) {
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();
}

Handlerhandler = 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);
}

};

public class downloadTask extends Thread {
private int blockSize,downloadSizeMore;
private int threadNum = 5;
String urlStr, threadNo, fileName;

public downloadTask(String urlStr, int threadNum, StringfileName) {
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 (inti = 0; i< threadNum; i++) {
//启动线程,分别下载自己需要下载的部分
FileDownloadThread fdt =new FileDownloadThread(url, file,
i * blockSize, (i + 1)* blockSize - 1);
fdt.setName("Thread"+ i);
fdt.start();
fds =fdt;
}
boolean finished = false;
while (!finished) {
// 先把整除的余数搞定
downloadedSize =downloadSizeMore;
finished = true;
for (inti = 0; i< fds.length; i++) {
downloadedSize +=fds.getDownloadSize();
if (!fds.isFinished()){
finished = false;
}
}
//通知handler去更新视图组件
handler.sendEmptyMessage(0);
//休息1秒后再读取下载进度
sleep(1000);
}
} catch(Exception e) {

}

}
}
}

java代码

import java.io.BufferedInputStream;
importjava.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.URL;
import java.net.URLConnection;

importandroid.util.Log;

publicclass 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,Filefile,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 = newbyte[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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: