Android下载文件的方法网上有好多,找来都不太靠谱,下载的文件经常不全。
我参考了多个方法,写了一个比较靠谱的,实测成功。
下载类代码:
在这个下载类中,我定义了一个回掉,可以回传当前下载的进度。
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import android.os.Environment;
import android.util.Log;
import com.tct.manager.android.file.FileUtils;
/**
* 下载的操作类
* @author drlyee
*/
public class DownloadHelper
{
/**
* 请求的地址
*/
private String sRequestUrl;
/**
* SD卡路径
*/
private String sSDCardPath;
/**
* 连接管理
*/
private HttpURLConnection httpURLConnection;
/**
* 构造函数
* @param url
*/
public DownloadHelper(String url)
{
this.sRequestUrl = url;
//获取设备sd卡目录
this.sSDCardPath = Environment.getExternalStorageDirectory() + "/";
this.httpURLConnection = getConnection();
}
/**
* 读取网络文本
*/
public String downloadAsString()
{
StringBuilder sb = new StringBuilder();
String temp = null;
try
{
InputStream is = httpURLConnection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
while ((temp = br.readLine()) != null)
{
sb.append(temp);
}
br.close();
}
catch (Exception e)
{
e.printStackTrace();
}
return sb.toString();
}
/**
* 获取http连接处理类HttpURLConnection
*/
private HttpURLConnection getConnection()
{
URL url;
HttpURLConnection urlcon = null;
try
{
url = new URL(sRequestUrl);
urlcon = (HttpURLConnection) url.openConnection();
}
catch (Exception e)
{
e.printStackTrace();
}
return urlcon;
}
/**
* 获取连接文件长度。
*/
public int getLength()
{
return httpURLConnection.getContentLength();
}
/**
* 下载文件到SD卡
* @param dir 下载后存放的文件夹路径,不需要SD卡路径
* @param filename 文件名称
* @param handler 回掉事件
*/
public synchronized void downloadToSDCard(String dir, String filename, DownLoadHandler handler)
{
String sFolderName = sSDCardPath + dir + "/";
String sFileName = sSDCardPath + dir + "/" + filename;
File file = new File(sFolderName.toString());
//如果文件夹不存在 创建文件夹
if (!file.exists())
{
file.mkdirs();
Log.d("log", sFolderName.toString());
}
//获取文件
file = new File(sFileName);
FileOutputStream fos = null;
BufferedInputStream in = null;
BufferedOutputStream out = null;
int totalSize = 0;
try
{
//创建文件
fos = new FileOutputStream(file);
byte[] buffer = new byte[1024 * 8];
totalSize = httpURLConnection.getContentLength();
in = new BufferedInputStream(httpURLConnection.getInputStream(), 1024 * 8);
out = new BufferedOutputStream(fos, 1024 * 8);
int count = 0, n = 0;
while ((n = in.read(buffer, 0, 1024 * 8)) != -1)
{
out.write(buffer, 0, n);
count += n;
handler.progress(filename, count, totalSize);
}
out.flush();
out.close();
in.close();
fos.flush();
fos.close();
handler.onFinished(totalSize, sFileName);
}
catch (IOException e)
{
// TODO Auto-generated catch block
try
{
out.close();
in.close();
fos.flush();
fos.close();
}
catch (IOException ex)
{
// TODO Auto-generated catch block
ex.printStackTrace();
}
handler.onFail("下载失败");
e.printStackTrace();
}
}
/**
* 内部回调接口类
*/
public abstract class DownLoadHandler
{
public abstract void progress(String name, int hasDownloadSize, int totalSize);
public abstract void onFinished(int totalSize, String path);
public abstract void onFail(String info);
}
}
使用如下:
定义一个下载的Runable,因为网络请求不可以在主线程里边去做。
private class DownLoadRunable implements Runnable
{
@Override
public void run()
{
// TODO Auto-generated method stub
String path = "http://msoftdl.360.cn/mobilesafe/shouji360/360safesis/360MobileSafe.apk";
DownloadHelper downloadHelper = new DownloadHelper(path);
downloadHelper.downloadToSDCard("MyDownload", "360MobileSafe.apk", downloadHelper.new DownLoadHandler()
{
@Override
public void progress(String name, int hasDownloadSize, int totalSize)
{
// TODO Auto-generated method stub
Log.i("progress ", name + " down:" + hasDownloadSize + " Total:" + totalSize);
}
@Override
public void onFinished(int totalSize, String path)
{
// TODO Auto-generated method stub
Log.i("onFinished ", "下载成功 Total:" + totalSize);
}
@Override
public void onFail(String info)
{
// TODO Auto-generated method stub
Log.e("onFail ", "下载成失败");
}
});
}
}
调用的方法,比如点击按钮下载:
btnDownLoad.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
// TODO Auto-generated method stub
Thread thread = new Thread(new DownLoadRunable());
thread.start();
}
});
执行的Log如下: