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如下: