/**
* Alipay.com Inc.
* Copyright (c) 2005-2009 All Rights Reserved.
*/
package com.external.alipay;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import javax.net.ssl.SSLException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.annotation.SuppressLint;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
/**
* 文件下载类,支持断电续传
*
* @author jianmin.jiang
*
* @version $Id: FileDownloader.java, v 0.1 2012-2-14 下午8:41:05 jianmin.jiang
* Exp $
*/
@SuppressLint("HandlerLeak")
public final class FileDownloader {
private String fileUrl;
private String savePath;
private String tmpPath;
private FileDownloader.IDownloadProgress progressOutput;
private FileFetch fetch;
private boolean showProgress;
public FileDownloader() {
showProgress = false;
}
public FileDownloader(boolean showProgress) {
this.showProgress = showProgress;
}
/**
* @param fileUrl
* 文件下载链接地址
*/
public final void setFileUrl(String fileUrl) {
this.fileUrl = fileUrl;
}
public final void setShowProgress(boolean showProgress) {
this.showProgress = showProgress;
}
protected final boolean showProgress() {
return this.showProgress;
}
/**
* @param savePath
* 文件保存地址,使用绝对路径
*/
public final void setSavePath(String savePath) {
this.savePath = savePath;
this.tmpPath = savePath + ".tmp";
}
/**
* @param progressOutput
* 下载进度输出类
*/
public final void setProgressOutput(
FileDownloader.IDownloadProgress progressOutput) {
if (progressOutput != null) {
this.progressOutput = progressOutput;
}
}
public void start() {
final ProgressOutput output = new ProgressOutput(Looper.getMainLooper());
new Thread(new Runnable() {
public void run() {
fetch = new FileFetch(fileUrl, savePath, FileDownloader.this);
long fileLen = -1;
if (showProgress) {
fileLen = getFileSize();
if (fileLen <= 0) {
output.sendEmptyMessage(0);
return;
}
} else {
deleteFile();
}
if (showProgress) {
readTempFile();
if (fetch.getFileEnd() != fileLen) {
deleteFile();
fetch.setFileStart(0);
fetch.setFileEnd(fileLen);
}
}
new Thread(fetch).start();
output.isFinished = false;
while (!fetch.isStop()) {
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
output.sendEmptyMessage(0);
}
output.sendEmptyMessage(0);
}
}).start();
}
public void stop() {
fetch.stop();
}
private long getFileSize() {
long fileLength = -1;
try {
HttpEntity entity = getHttpEntity(fileUrl, false);
fileLength = entity.getContentLength();
} catch (Exception e) {
// AppErrorException.printException(this.getClass(),
// "can not get file length", e);
e.printStackTrace();
}
return fileLength;
}
private void deleteFile() {
File file = new File(savePath);
if (file.exists()) {
file.delete();
}
file = new File(tmpPath);
if (file.exists()) {
file.delete();
}
}
protected void writeTempFile() {
FileOutputStream out = null;
ObjectOutputStream objOut = null;
try {
out = new FileOutputStream(this.tmpPath);
objOut = new ObjectOutputStream(out);
objOut.writeLong(fetch.getFileStart());
objOut.writeLong(fetch.getFileEnd());
objOut.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (Exception e) {
}
try {
objOut.close();
} catch (Exception e) {
}
}
}
private void readTempFile() {
FileInputStream in = null;
ObjectInputStream objIn = null;
try {
in = new FileInputStream(this.tmpPath);
objIn = new ObjectInputStream(in);
fetch.setFileStart(objIn.readLong());
fetch.setFileEnd(objIn.readLong());
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
in.close();
} catch (Exception e) {
}
try {
objIn.close();
} catch (Exception e) {
}
}
}
public static HttpEntity getHttpEntity(String netAddress, boolean isZip)
throws Exception {
try {
// HttpGet连接对象
HttpGet httpGet = new HttpGet(netAddress);
// 取得HttpClient
HttpClient httpClient = new DefaultHttpClient();
if (isZip) {
httpGet.addHeader("Accept-Encoding", "gzip");
}
// 请求HttpClient,获得HttpResponce
HttpResponse response = httpClient.execute(httpGet);
// 请求成功
int code = response.getStatusLine().getStatusCode();
if (code == HttpStatus.SC_OK) {
HttpEntity entity = response.getEntity();
return entity;
} else {
throw new Exception("net work exception,ErrorCode :"+code);
}
} catch (SSLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private class ProgressOutput extends Handler {
private boolean isFinished;
@SuppressLint("HandlerLeak")
public ProgressOutput(Looper looper) {
super(looper);
isFinished = false;
}
@Override
public void handleMessage(Message msg) {
if (progressOutput == null) {
return;
}
if (progressOutput == null) {
return;
}
try {
float progress = 50;
if (showProgress) {
progress = ((fetch.getFileStart() * 100) / fetch
.getFileEnd());
} else if (fetch.isStop()) {
progress = 100;
}
if (fetch.isStop()) {
if (progress == 100 && !isFinished) {
progressOutput.downloadSucess();
isFinished = true;
} else if (progress > 100) {
deleteFile();
progressOutput.downloadFail();
} else if(!isFinished){
progressOutput.downloadFail();
}
} else {
progressOutput.downloadProgress(progress);
}
} catch (Exception e) {
progressOutput.downloadFail();
}
}
}
public interface IDownloadProgress {
void downloadProgress(float progress);
void downloadSucess();
void downloadFail();
}
}