布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="30dp"
android:layout_marginLeft="15dp"
android:gravity="center_vertical"
android:text="下载地址"
android:textSize="15sp" />
<EditText
android:id="@+id/downURL"
android:layout_width="fill_parent"
android:layout_height="80dp"
android:layout_marginLeft="15dp"
android:gravity="center_vertical"
android:text="http://img1.imgtn.bdimg.com/it/u=1212833245,963852114&fm=21&gp=0.jpg"
android:textSize="20sp" >
</EditText>
<TextView
android:layout_width="fill_parent"
android:layout_height="30dp"
android:layout_marginLeft="15dp"
android:gravity="center_vertical"
android:text="下载文件名"
android:textSize="15sp" />
<EditText
android:id="@+id/FileName"
android:layout_width="fill_parent"
android:layout_height="45dp"
android:layout_marginLeft="15dp"
android:gravity="center_vertical"
android:textSize="20sp" />
<TextView
android:layout_width="fill_parent"
android:layout_height="30dp"
android:layout_marginLeft="15dp"
android:gravity="center_vertical"
android:text="下载线程数"
android:textSize="15sp" />
<EditText
android:id="@+id/ThreadNumber"
android:layout_width="fill_parent"
android:layout_height="45dp"
android:layout_marginLeft="15dp"
android:gravity="center_vertical"
android:text="3"
android:textSize="20sp" />
<Button
android:id="@+id/btn_down"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:text="开始下载"
android:textSize="20sp" />
<TextView
android:id="@+id/view_downfile"
android:layout_width="fill_parent"
android:layout_height="30dp"
android:layout_marginLeft="15dp"
android:gravity="center_vertical"
android:textSize="15sp" />
<!-- 进度条 -->
<ProgressBar
android:id="@+id/ProgressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="fill_parent"
android:layout_height="5dp"
android:layout_marginTop="15dp" />
</LinearLayout>
</LinearLayout>
源码
package com.example.filedownload;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import android.R.integer;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
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;
import android.widget.Toast;
public class MainActivity extends Activity {
private EditText downURL, ThreadNumber, FileName;
/** 显示下载状态 */
private TextView view_downfile;
private Button btn_down;
private ProgressBar ProgressBar;
/** 文件总大小 */
public int FileSize;
/** 当前文件下载大小 */
public int nowDownSize;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){
Toast.makeText(this, "sd卡可用", 1000).show();
}else{
Toast.makeText(this, "sd卡不可用", 1000).show();
}
init();
btn_down.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
DownLoad();
}
});
}
private void init() {
view_downfile = (TextView) findViewById(R.id.view_downfile);
downURL = (EditText) findViewById(R.id.downURL);
FileName = (EditText) findViewById(R.id.FileName);
ThreadNumber = (EditText) findViewById(R.id.ThreadNumber);
btn_down = (Button) findViewById(R.id.btn_down);
ProgressBar = (ProgressBar) findViewById(R.id.ProgressBar);
//进度条设置显示
ProgressBar.setVisibility(View.VISIBLE);
//进度条设置最大最小值
ProgressBar.setMax(100);
ProgressBar.setProgress(0);
}
/** 1、下载 */
private void DownLoad() {
URL url = null;
try {
url = new URL(downURL.getText().toString());
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 下载路径
String strurl = Environment.getExternalStorageDirectory()
+ "/MyDownload/";
File strfile=new File(strurl);
if(!strfile.exists()){
strfile.mkdirs();//不存在则创建
}
// 获取文件名
String filename = null;
if (FileName.getText().toString().equals("") | FileName.getText().toString().equals(null)) {
int count = downURL.getText().toString().lastIndexOf("/");
filename = downURL.getText().toString()
.substring(count);
} else {
filename = FileName.getText().toString();
}
Log.e(">>>>>>>>>>>>>", filename);
File file = new File(strurl + filename);
// 线程数
int threadnumber = 0;
if (ThreadNumber.getText().toString().equals("")
| ThreadNumber.getText().toString().equals(null)) {
ThreadNumber.setText("1");
}
threadnumber = Integer.valueOf(ThreadNumber.getText().toString());
//进度条设为0
ProgressBar.setProgress(0);
//下载按钮不可用
btn_down.setClickable(false);
new DownThread(url, file, threadnumber).start();
}
/** 4、handler通知进度条 */
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
int press=Double.valueOf(nowDownSize*1.0/FileSize*100).intValue();
if(press==100){
btn_down.setClickable(true);
view_downfile.setText("下载完成!");
}else{
view_downfile.setText(press+"%");
}
ProgressBar.setProgress(press);
}
};
/** 3、文件下载线程 */
public class DownThread extends Thread {
private int locksize, downsizemore;
private URL url;
private File file;
private int threadnumber;
public DownThread(URL url, File file, int threadnumber) {
// TODO Auto-generated constructor stub
this.url = url;
this.file = file;
this.threadnumber = threadnumber;
}
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
FileDownThread[] fdt1 = new FileDownThread[threadnumber];
try {
URLConnection conn = url.openConnection();
// 获取文件长度
FileSize = conn.getContentLength();
// 计算每个线程的下载数据量
locksize = FileSize / threadnumber;
// 解决整除后百分比计算误差
downsizemore = (FileSize % threadnumber);
for (int i = 0; i < threadnumber; i++) {
// 启动线程,分别下载自己需要下载的部分
FileDownThread fdt2 = new FileDownThread(url, file, i
* locksize, (i + 1) * locksize - 1);
fdt2.setName("thread" + i);
fdt2.start();
fdt1[i] = fdt2;
}
boolean finished = false;
while (!finished) {
nowDownSize = downsizemore;
finished = true;
for (int i = 0; i < fdt1.length; i++) {
nowDownSize += fdt1[i].nowDownLoad();
if (!fdt1[i].isfinished()) {
finished = false;
}
}
//通知handler更新视图
handler.sendEmptyMessage(0);
sleep(1000);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/** 2、文件断点下载线程 */
public class FileDownThread extends Thread {
private URL url;
private File file;
private int startwhere, nowwhere, endwhere;
// 标示当前文件下载大小
private boolean finshed;
private int nowDownSize;
public FileDownThread(URL url, File file, int startwhere, int endwhere) {
super();
this.url = url;
this.file = file;
this.startwhere = startwhere;
this.nowwhere = startwhere;
this.endwhere = endwhere;
}
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
byte[] bytes = new byte[1024];
URLConnection conn = null;
RandomAccessFile raf = null;
BufferedInputStream bis = null;
try {
conn = url.openConnection();
// 允许用户交互
conn.setAllowUserInteraction(true);
// 设置当前线程下载的起点,终点
conn.setRequestProperty("Range", "bytes=" + startwhere + "-"
+ endwhere);
// 使用java中的RandomAccessFile 对文件进行随机读写操作
raf = new RandomAccessFile(file, "rw");
// 设置文件开始位置
raf.seek(startwhere);
bis = new BufferedInputStream(conn.getInputStream());
// 开始循环以流的形式读写文件
while (nowwhere < endwhere) {
int len = bis.read(bytes, 0, 1024);
if (len == -1) {
break;
}
raf.write(bytes, 0, 1024);
nowwhere += len;
if (nowwhere > endwhere) {
nowDownSize += len - (nowwhere - endwhere) + 1;
} else {
nowDownSize += len;
}
}
finshed = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (raf != null) {
try {
raf.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public boolean isfinished() {
return finshed;
}
public int nowDownLoad() {
return nowDownSize;
}
}
}