package com.example.qingyangdemo.thread; import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.net.Socket; import java.util.HashMap; import java.util.Map; import android.os.Handler; import android.os.Message; import android.util.Log; import com.example.qingyangdemo.base.AppException; import com.example.qingyangdemo.base.BaseApplication; import com.example.qingyangdemo.common.DownLoadManager; import com.example.qingyangdemo.common.FileUtil; import com.example.qingyangdemo.net.Constant; import com.example.qingyangdemo.net.URL; /** * 下载的线程 * * @author 赵庆洋 * */ public class DownLoadThread extends Thread { private Socket socket; private String filePath; private String fileName; public final static int BUFFER = 8 * 1024; private Handler handler; private boolean start = true; private BaseApplication application; public DownLoadThread(BaseApplication application, Handler handler, String filePath, String fileName) { this.handler = handler; this.filePath = filePath; this.fileName = fileName; this.application = application; } /* * 服务器提出下载请求,返回文件长度 */ private long request() throws IOException { DataInputStream in = new DataInputStream(socket.getInputStream()); DataOutputStream out = new DataOutputStream(socket.getOutputStream()); String params = filePath + "@" + fileName; // 发出下载请求 out.writeUTF(params); out.flush(); // 返回文件长度 return in.readLong(); } /** * 接收保存文件 * * @param message * * @param localFile * 文件 * @param tempFile * 临时文件 * @param fileLength * 文件长度 * @param message */ private void receiveFile(File localFile, File tempFile, long fileLength) throws IOException { // 获取socket的输入流包装成bufferedInputStream BufferedInputStream in = new BufferedInputStream( socket.getInputStream()); // 获取本地关联的临时文件流 FileOutputStream out = new FileOutputStream(tempFile); byte[] buf = new byte[BUFFER]; // 每次下载的长度 int len; // 累计下载的长度 int count = 0; while (start && ((len = in.read(buf)) >= 0)) { out.write(buf, 0, len); out.flush(); count += len; Message message = new Message(); message.what = DownLoadManager.DOWNLOAD_UPDATE; // 当前进度值 int progress = (int) (((float) count / fileLength) * 100); // 当先下载文件大小 String currentSize = FileUtil.formatFileSize(count); Map<String, Object> map = new HashMap<String, Object>(); map.put("progress", progress); map.put("currentSize", currentSize); map.put("fileSize", FileUtil.formatFileSize(fileLength)); message.obj = map; handler.sendMessage(message); } out.close(); in.close(); // 如果下载完成 if (count == fileLength) { // 临时文件重命名 if (tempFile.renameTo(localFile)) { Message message = new Message(); message.what = DownLoadManager.DOWNLOAD_SUCCESS; message.obj = localFile.getAbsolutePath(); handler.sendMessage(message); Log.v(AppException.LOG_TAG, "下载完毕"); } else { handler.sendEmptyMessage(DownLoadManager.DOWNLOAD_RENAME); } } // 如果暂停下载 删除已有的临时文件 if (!start) { if (tempFile.exists()) { tempFile.delete(); } } } // 从服务器下载文件 private void download() { try { String localFilePath = FileUtil.fileDirectory(Constant.DOWN_PATH, fileName); String tempFilePath = FileUtil.fileDirectory(Constant.DOWN_PATH, fileName.substring(0, fileName.indexOf(".")) + ".tmp"); File file = new File(localFilePath); if (file.exists()) { Message message = new Message(); message.what = DownLoadManager.DOWNLOAD_EXITS; message.obj = localFilePath; handler.sendMessage(message); return; } // 临时文件 File tempFile = new File(tempFilePath); socket = new Socket(application.getIpAdress(), URL.PC_DOWN_PORT); // 文件长度 long fileLength = request(); if (fileLength > 0) { Log.v(AppException.LOG_TAG, "文件大小" + FileUtil.formatFileSize(fileLength)); Log.v(AppException.LOG_TAG, "开始下载"); // 保存到本地 receiveFile(file, tempFile, fileLength); } else { Log.v(AppException.LOG_TAG, "下载出错"); handler.sendEmptyMessage(DownLoadManager.DOWNLOAD_FAILL); } } catch (IOException e) { Log.v(AppException.LOG_TAG, "下载出错"); e.printStackTrace(); handler.sendEmptyMessage(DownLoadManager.DOWNLOAD_FAILL); } finally { try { if (socket != null) { socket.close(); } } catch (IOException e) { e.printStackTrace(); } } } @Override public void run() { download(); } public boolean isStart() { return start; } public void setStart(boolean start) { this.start = start; } }