package com.nevin.downloader;
import java.io.File;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import com.nevin.downloader.DownlaodStateListener.*;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;
public class DownloadFileAsync extends AsyncTask<String, String, String> {
private final static String TAG = "Downloader";
private String SDCARD = Environment.getExternalStorageDirectory().getAbsolutePath();
private String MYDOWNLOAD = "MyDownload";
private String mDownloadUrl = null;
private String mFileName = null;
private String mFilePath;
private boolean mDownloading = true;
private DownloadDB mDownLoadDB;
private int mCompleteSize =0;
private OnDownloadStartedListener mOnDownloadStartedListener = null;
private OnProgressUpdateListener mOnProgressUpdateListener = null;
private OnDownloadFinishedListener mOnDownloadFinishedListener = null;
public DownloadFileAsync(Context context,String fileName, String downloadUrl){
mFileName = fileName;
File file = new File(SDCARD+"/"+MYDOWNLOAD);
if( !file.exists() ){
file.mkdirs();
}
mFilePath = SDCARD+"/"+MYDOWNLOAD+"/"+mFileName;
mDownloadUrl = downloadUrl;
mDownLoadDB = new DownloadDB(context);
}
public void setOnDownloadStartedListener(OnDownloadStartedListener l){
mOnDownloadStartedListener = l;
}
public void setOnProgressUpdateListener(OnProgressUpdateListener l){
mOnProgressUpdateListener = l;
}
public void setOnDownloadFinishedListener(OnDownloadFinishedListener l){
mOnDownloadFinishedListener = l;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
if(mOnDownloadStartedListener != null){
mOnDownloadStartedListener.onDownloadStarted(mFileName, mDownloadUrl,0);
}
}
public void stopDownload(){
mDownloading = false;
mDownLoadDB.updataInfo(mDownloadUrl, mCompleteSize, getFileMd5String(new File(mFilePath)));
mDownLoadDB.closeDb();
}
@Override
protected String doInBackground(String... params) {
DownloadInfo info = getDownloadInfo(mDownloadUrl);
if(info==null){
Log.e(TAG,"error, downloadInfo is null !");
return null;
}
int totalSize = info.getFileSize();
mCompleteSize = info.getCompeleteSize();
mFilePath = info.getFilePath();
publishProgress(mFileName, mDownloadUrl, "" + (int)((mCompleteSize*100)/totalSize));
HttpURLConnection c = null;
RandomAccessFile randomAccessFile = null;
InputStream is = null;
try {
//connecting to url
Log.e(TAG,"do in Background ...."+mDownloadUrl);
URL u = new URL(mDownloadUrl);
c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setRequestProperty("Range", "bytes="+info.getCompeleteSize() + "-" + info.getFileSize());
c.setDoOutput(true);
c.connect();
randomAccessFile = new RandomAccessFile(mFilePath, "rwd");
randomAccessFile.seek(info.getCompeleteSize());
// 将要下载的文件写到保存在保存路径下的文件中
is = c.getInputStream();
byte[] buffer = new byte[4098];
int length = -1;
while ((length = is.read(buffer)) != -1 && mDownloading) {
randomAccessFile.write(buffer, 0, length);
mCompleteSize += length;
publishProgress(mFileName, mDownloadUrl, ""+(int)((mCompleteSize*100)/totalSize));
// 更新数据库中的下载信息
if(mCompleteSize>=totalSize){
delete(mDownloadUrl);
}
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if(is!=null){
is.close();
}
if(randomAccessFile != null){
randomAccessFile.close();
}if(c != null){
c.disconnect();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onProgressUpdate(String... progress) {
if(mOnProgressUpdateListener != null){
mOnProgressUpdateListener.onProgressUpdate(progress[0],progress[1],Integer.parseInt(progress[2]));
}
}
@Override
protected void onPostExecute(String unused) {
//dismiss the dialog after the file was downloaded
if(mOnDownloadFinishedListener != null){
mOnDownloadFinishedListener.onDownloadFinished(mFileName, mDownloadUrl);
}
}
//删除数据库中urlstr对应的下载器信息
public void delete(String url) {
mDownLoadDB.delete(url);
}
private String checkFileName(String fileDir, String fileName){
File file = new File(fileDir+"/"+fileName);
String newFileName = fileName;
if(file.exists()){
for(int i=1; i<1024; i++){
newFileName = String.format("%s(%d)",fileName,i);
file = new File(fileDir+"/"+newFileName);
if(!file.exists()){
return newFileName;
}
}
}
return newFileName;
}
private DownloadInfo getDownloadInfo(String url){
DownloadInfo info=null;
if(isFirstDownlaod(url)){
info = firstDownloadInit();
}else{
Log.e(TAG,"has download before...");
info = mDownLoadDB.getDownloadInfo(url);
if(info!=null){
Log.e(TAG,"compeleted: "+info.getCompeleteSize());
}
}
return info;
}
/**
* 判断是否是第一次 下载
*/
private boolean isFirstDownlaod(String downloadUrl) {
return mDownLoadDB.hasInfo(downloadUrl);
}
/**
* 初始化
*/
private DownloadInfo firstDownloadInit() {
Log.e(TAG, "firstDownloadInit.....");
DownloadInfo downloadInfo=null;
try {
URL url = new URL(mDownloadUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(5000);
connection.setRequestMethod("GET");
int fileSize = connection.getContentLength();
mFileName = checkFileName(SDCARD+"/"+MYDOWNLOAD,mFileName);
mFilePath = SDCARD+"/"+MYDOWNLOAD+"/"+mFileName;
File file = new File(mFilePath);
if (!file.exists()) {
file.createNewFile();
}else{
}
// 本地访问文件
RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");
accessFile.setLength(fileSize);
accessFile.close();
downloadInfo = new DownloadInfo(mDownloadUrl,fileSize,0,mFilePath,getFileMd5String(file));
mDownLoadDB.saveDwonloadInfo(downloadInfo);
connection.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
return downloadInfo;
}
private String getFileMd5String(File file ){
return "";
/*
try{
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
FileInputStream in = new FileInputStream(file);
FileChannel ch = in.getChannel();
MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, 0, file.length());
messageDigest.update(byteBuffer);
return new String(messageDigest.digest());
}catch(Exception e){
e.printStackTrace();
}
return "";
*/
}
}