文件下载(实现断点续传) Android 文件下载(实现断点续传) Android 希望给代码,【有用的多给分。】 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 下载时,记录一下下载了的数据,然后下次从哪里再开始下载就行了。以下代码就可以从文件的第4096字节的位置开始下载。URL url = new URL("http://target.com/test.zip"); HttpURLConnection httpConnection = (HttpURLConnection)url.openConnection(); //设置User-Agent httpConnection.setRequestProperty("User-Agent","NetFox"); //设置断点续传的开始位置 httpConnection.setRequestProperty("RANGE","bytes=4096"); //获得输入流 InputStream input = httpConnection.getInputStream(); 我原封不动的复制的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; }} 去了那个代码的原站看,讨论里面有jacson 发表于:八月 28th, 2010 2:21 上午 剩下的余数downloadSizeMore没有被下载吧 ideasandroid 发表于:八月 29th, 2010 8:55 上午 请大家积极讨论余数是否下载完的问题!不知道是不是真的有下载完呢=。=有人试试给个结果看看么。 Mark 一下 顺便 每天回帖即可获得10分可用分! hao, xie xie 如何在ddms导出超过64M的hprof文件? ANDROID打不开网页 关于addview()有点莫名其妙的问题,费解中 浏览器与手机交互的问题 调试android 系统时, 想看java 中的调试信息, 如何看? 求助:ubuntu下编译opencore出现问题 如何实现多个应用程序间的调用 提一个android的问题 Android移动网络下能使用Socket通信吗 求助:关于TCP传输不稳定(估计是丢包)的问题 小妹请教一个LinearLayout布局问题! 求教为什么service接受到的值是空?
HttpURLConnection httpConnection = (HttpURLConnection)url.openConnection(); //设置User-Agent
httpConnection.setRequestProperty("User-Agent","NetFox");
//设置断点续传的开始位置
httpConnection.setRequestProperty("RANGE","bytes=4096");
//获得输入流
InputStream input = httpConnection.getInputStream();
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;
}
}
jacson
发表于:八月 28th, 2010 2:21 上午
剩下的余数downloadSizeMore没有被下载吧 ideasandroid
发表于:八月 29th, 2010 8:55 上午
请大家积极讨论余数是否下载完的问题!不知道是不是真的有下载完呢=。=有人试试给个结果看看么。
xie xie