/** * picture whether need to update * this class call downloadhelper to download picture * @author WMB */ public class PicCheckHelper { private static PicCheckHelper instance = null; private BaseTimer mTimer = null; private static final int REQUESTINTERVAL = 60 * 1000; // 2 * 60 * 60 * 1000 public static PicCheckHelper getInstance(){ if(null == instance){ instance = new PicCheckHelper(); } return instance; } /** * start 2h Timer */ public void start(){ if(null == mTimer){ mTimer = new BaseTimer(); } mTimer.startInterval(REQUESTINTERVAL, mTimerCallback); } /** * close Timer */ public void close(){ if(null != mTimer){ mTimer.killTimer(); } } /** * check right now */ public void checkNow(){ checkPic(); } /** * check picture whether need to update by cloud request */ private void checkPic() { GeneralHttpHelper.getInstance().requestScreenPicUpdate(mHttpCallback); } /** * 定时器回调接口 */ private TimerCallBack mTimerCallback = new TimerCallBack() { @Override public void callback() { checkPic(); } }; private HttpCallback mHttpCallback = new HttpCallback() { @Override public void onState(HTTP_STATE state) { switch (state) { case STATE_SUCCESS: syncPic(); break; default: break; } } }; /** * 执行图片同步入口 */ private void syncPic() { PicSyncHelper.getInstance().syncPicture(); } }外部调用checkNow,立刻去云端检查是否有新的屏保,在网络请求成功回调中执行syncPic方法开始同步逻辑。
/** * 屏保同步解析类 */ public class ScreenSyncParser extends BaseParser { @Override public void run() { parserScreenData(); } private void parserScreenData() { try { JSONObject jsonObj = new JSONObject(mParseData); if(jsonObj.optInt("status") < 0){ sendMessage(HTTP_STATE.STATE_ERROR); LogHelper.releaseLog(PicCons.SCREEN_TAG, "ScreenSyncParser -- http request status < 0"); return; } JSONObject data = jsonObj.optJSONObject("data"); String timestamp = data.optString("updatetimes"); LogHelper.releaseLog(PicCons.SCREEN_TAG, "ScreenSyncParser -- parserScreenData cloudtimestamp : "+ timestamp); Utils.setCloudTimestamp(timestamp); boolean needsync = compareTimeStamp(timestamp);// 比较云端时间戳与本地时间戳 if(needsync){ // 云端时间新,则保存云端Json信息,为下载做准备(另一种情况:时间戳相等,上次下载80%,则保持之前存的Json不变,继续下载未成功的部分,后面会提到) JSONArray jsonData = data.optJSONArray("pics"); if(null == jsonData || jsonData.length() == 0){ return; } INFO_DL item = null; ArrayList<INFO_DL> resultList = new ArrayList<INFO_DL>(); for (int i = 0; i < jsonData.length(); i++) { item = new INFO_DL(); JSONObject jsonItem = jsonData.optJSONObject(i); item.dlIndex = i; item.md5 = jsonItem.optString("fileHash"); item.url = jsonItem.optString("url"); item.fileType = Utils.getPicTypeByUrl(item.url); resultList.add(item); } LogHelper.releaseLog(PicCons.SCREEN_TAG, "ScreenSyncParser -- parserScreenData needsync is true ,resultList size: "+resultList.size()); saveDLJson(resultList); // 存到文件中,为下载做准备 Utils.setFullDLFlag(true);// 若云端时间新,则默认上次同步已经完全成功,开始新的同步 } else{ LogHelper.releaseLog(PicCons.SCREEN_TAG, "ScreenSyncParser -- parserScreenData needsync is false don't need save DLJson"); } sendMessage(HTTP_STATE.STATE_SUCCESS); } catch (Exception e) { sendMessage(HTTP_STATE.STATE_ERROR); LogHelper.releaseLog(PicCons.SCREEN_TAG, "ScreenSyncParser -- http request error!"); } } /** * compare cloud and local timestamp * @param cloudTimestamp * @return true: cloud > local ,false:otherwise */ public boolean compareTimeStamp(String cloudTimestamp){ String localTimestamp = Utils.getScreenTimestamp(); if(TextUtils.isEmpty(localTimestamp)){ LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper -- compareTimeStamp localTimestamp is empty, need to sync"); return true; } if(TextUtils.isEmpty(cloudTimestamp)){ LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper -- compareTimeStamp cloudTimestamp is empty, don't need to sync"); return false; } try { long localTime = Long.parseLong(localTimestamp); long cloudTime = Long.parseLong(cloudTimestamp); LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper -- compareTimeStamp cloudTimestamp is : "+cloudTimestamp+",localTimestamp is: "+localTimestamp); return cloudTime > localTime; } catch (Exception e) { e.printStackTrace(); return false; } } /** * save download json * @param list */ public void saveDLJson(ArrayList<INFO_DL> list){ if(null == list){ LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper -- saveDLJson ArrayList<INFO_DL> is null"); return; } JSONArray jsonArray = new JSONArray(); JSONObject jsonObj = null; INFO_DL infoItem = null; for (int i = 0; i < list.size(); i++) { jsonObj = new JSONObject(); infoItem = new INFO_DL(); infoItem = list.get(i); try { jsonObj.put("md5", infoItem.md5); jsonObj.put("url", infoItem.url); jsonObj.put("savePath", infoItem.savePath); jsonObj.put("DLFlag", infoItem.DLFlag); jsonObj.put("dlIndex", infoItem.dlIndex); jsonObj.put("reTry", infoItem.reTry); jsonObj.put("copyPath", infoItem.copyPath); jsonObj.put("fileType", infoItem.fileType); jsonArray.put(jsonObj); } catch (JSONException e) { e.printStackTrace(); LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper -- saveDLJson has an exception"); return; } } LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper -- saveDLJson :"+jsonArray.toString()); Utils.setDLJson(jsonArray.toString()); } }
/** * this class is responsible for sync picture include download and copy, * @author WMB * */ public class PicSyncHelper { private static PicSyncHelper instance = null; private ArrayList<INFO_DL> DLJsonList = new ArrayList<INFO_DL>(); // 同步所用list(DLFlag为false) private ArrayList<INFO_DL> AllDLList = new ArrayList<INFO_DL>(); // 所有dlList不区分DLFlag(用于向硬盘中写下载数据) private ArrayList<INFO_DL> UsingJsonList = new ArrayList<INFO_DL>(); // 屏保图片展示所用list private String picCopyPath = ""; // 图片copy路径 private boolean isDownloadEnd = false; // 下载完毕标志位 private boolean isCopyEnd = false; // copy完毕标志位 private String filePath = ""; public static PicSyncHelper getInstance(){ if(null == instance){ instance = new PicSyncHelper(); } return instance; } private PicSyncHelper(){ filePath = Common.getContext().getFilesDir().getPath(); } private Handler mHandle = new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.what) { case PicCons.MESSAGE_DL: case PicCons.MESSAGE_CP: setScreenPath(true); break; case PicCons.MESSAGE_DL_PARTOK: isDownloadEnd = true; setScreenPath(false); break; case PicCons.MESSAGE_CP_PARTOK: isCopyEnd = true; setScreenPath(false); default: break; } } }; /** * 执行图片同步逻辑 */ public void syncPicture(){ isDownloadEnd = false; isCopyEnd = false; if(DLJsonList == null || DLJsonList.size() <= 0){ initDLJson(); // 初始化下载List } if(DLJsonList == null || DLJsonList.size() <= 0){ // 下载List为空,不做处理,退出 LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper -- syncPicture , DLJsonList is empty ,do nothing ,exist!"); return; } String usingJson = Utils.getUsingJson(); // 获取正在使用的Json信息 Utils.setScreenTimestamp(Utils.getCloudTimestamp()); // 保存本地同步时间戳 if(TextUtils.isEmpty(usingJson)){ // 全量下载 LogHelper.releaseLog(PicCons.SCREEN_TAG, "--begin All download , download size is:"+DLJsonList.size()); new Thread(new PicDownloadManager(DLJsonList, mHandle ,PicCons.MESSAGE_DL)).start(); } else{ // 已存在则copy,不存在则下载 try { JSONArray jsonArray = new JSONArray(usingJson); if(null != UsingJsonList && UsingJsonList.size() == 0){ initUsingJsonList(jsonArray); } ArrayList<INFO_DL> dlList = new ArrayList<INFO_DL>(); final ArrayList<INFO_DL> cpList = new ArrayList<INFO_DL>(); INFO_DL Item = null; for (int i = 0; i < DLJsonList.size(); i++) { Item = DLJsonList.get(i); if(picisExist(Item.md5)){ //加入复制 if(!TextUtils.isEmpty(picCopyPath)){ Item.copyPath = picCopyPath; Item.savePath = getSavePath(picCopyPath); cpList.add(Item); } } else{ // 加入下载 dlList.add(Item); } } if(dlList.size() > 0){ // 下载 if(cpList.size() > 0){ LogHelper.releaseLog(PicCons.SCREEN_TAG, "--begin Part of download , download size is:"+dlList.size()); new Thread(new PicDownloadManager(dlList,mHandle,PicCons.MESSAGE_DL_PARTOK)).start(); } else{ LogHelper.releaseLog(PicCons.SCREEN_TAG, "--begin All download ,using json exist, download size is:"+dlList.size()); new Thread(new PicDownloadManager(dlList,mHandle,PicCons.MESSAGE_DL)).start(); } } if(cpList.size() > 0){ // 复制 if(dlList.size() > 0){ LogHelper.releaseLog(PicCons.SCREEN_TAG, "--begin Part copy, copy size is:"+cpList.size()); new Thread(new Runnable() { @Override public void run() { copy(cpList, PicCons.MESSAGE_CP_PARTOK); } }).start(); } else{ LogHelper.releaseLog(PicCons.SCREEN_TAG, "--begin All copy, copy size is:"+cpList.size()); new Thread(new Runnable() { @Override public void run() { copy(cpList, PicCons.MESSAGE_CP); } }).start(); } } } catch (JSONException e) { e.printStackTrace(); } } } /** * update download json info * @param index * @param data */ public void updateDLJson(int index, INFO_DL data){ if(null == AllDLList || AllDLList.size() == 0){ String DLJsonStr = Utils.getDLJson(); try { JSONArray DLJsonArr = new JSONArray(DLJsonStr); JSONObject updateItem = new JSONObject(); updateItem.put("md5", data.md5); updateItem.put("url", data.url); updateItem.put("savePath", data.savePath); updateItem.put("DLFlag", data.DLFlag); updateItem.put("dlIndex", data.dlIndex); updateItem.put("reTry", data.reTry); updateItem.put("copyPath", data.copyPath); updateItem.put("fileType", data.fileType); DLJsonArr.put(index, updateItem); LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper -- updateDLJson,DLJsonList is empty ,updata index : "+index+", jsonObj :"+updateItem.toString()); Utils.setDLJson(DLJsonArr.toString()); } catch (JSONException e) { LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper -- updateDLJson has an Exception"); e.printStackTrace(); return; } } else{ if(index >= 0 && index < AllDLList.size()){ AllDLList.remove(index); AllDLList.add(index, data); saveDLJson(AllDLList); } } } /** * save download json * @param list */ public void saveDLJson(ArrayList<INFO_DL> list){ if(null == list){ LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper -- saveDLJson ArrayList<INFO_DL> is null"); return; } JSONArray jsonArray = new JSONArray(); JSONObject jsonObj = null; INFO_DL infoItem = null; for (int i = 0; i < list.size(); i++) { jsonObj = new JSONObject(); infoItem = new INFO_DL(); infoItem = list.get(i); try { jsonObj.put("md5", infoItem.md5); jsonObj.put("url", infoItem.url); jsonObj.put("savePath", infoItem.savePath); jsonObj.put("DLFlag", infoItem.DLFlag); jsonObj.put("dlIndex", infoItem.dlIndex); jsonObj.put("reTry", infoItem.reTry); jsonObj.put("copyPath", infoItem.copyPath); jsonObj.put("fileType", infoItem.fileType); jsonArray.put(jsonObj); } catch (JSONException e) { e.printStackTrace(); LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper -- saveDLJson has an exception"); return; } } DLJsonList = list; LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper -- saveDLJson :"+jsonArray.toString()); Utils.setDLJson(jsonArray.toString()); } /** * 获取下载路径,如果上次未下载完全,则还将图片下载到之前使用的目录中 * @return DLPath */ public String getDLPath(){ boolean isFullDownload = Utils.getFullDLFlag(); String usingPath = Utils.getScreenPath(); LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper -- now screenPath is:"+usingPath); String DLPath; if(TextUtils.isEmpty(usingPath)){ DLPath = PicCons.SCREEN_PATH_A; } else{ if(isFullDownload){ LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper -- isFUllDownload is true"); DLPath = PicCons.SCREEN_PATH_A.equals(usingPath)? PicCons.SCREEN_PATH_B : PicCons.SCREEN_PATH_A; } else{ LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper -- isFUllDownload is false"); DLPath = PicCons.SCREEN_PATH_A.equals(usingPath)? PicCons.SCREEN_PATH_A : PicCons.SCREEN_PATH_B; } } LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper -- getDLPath : "+ filePath+DLPath); return filePath+DLPath; } /** * 判断图片是否在本地存在 * @param md5 * @return */ private boolean picisExist(String md5){ if(null == UsingJsonList || UsingJsonList.size() <= 0){ return false; } INFO_DL jsonItem = null; for (int i = 0; i < UsingJsonList.size(); i++) { jsonItem = UsingJsonList.get(i); if(md5.equals(jsonItem.md5)){ picCopyPath = jsonItem.savePath; return true; } } return false; } /** * 初始化下载使用Json信息 */ private void initDLJson(){ String dlStr = Utils.getDLJson(); if(!TextUtils.isEmpty(dlStr)){ try { JSONArray jsonArray = new JSONArray(dlStr); if(null != jsonArray){ ArrayList<INFO_DL> allDLList = Utils.transJsonToList(jsonArray); if(null != allDLList){ int size = allDLList.size(); INFO_DL item = null; if(size > 0){ for (int i = 0; i < size; i++) { item = allDLList.get(i); AllDLList.add(item); if(!item.DLFlag){ // 将下载或copy失败的加进来 DLJsonList.add(item); } } LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper -- initDLJson success , DLJsonList size:"+DLJsonList.size()); } } else{ LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper -- initDLJson allDLList is null, so DLJsonList is empty"); } } } catch (Exception e) { LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper -- initDLJson has an Exception"); e.printStackTrace(); } } } /** * 初始化屏保图片使用Json信息 * @param jsonArray */ private void initUsingJsonList(JSONArray jsonArray) { if(null == jsonArray){ return; } UsingJsonList = Utils.transJsonToList(jsonArray); } /** * 根据图片拷贝路径,获得图片保存路径 * @param copyPath 图片拷贝路径 * @return 图片保存路径 */ private String getSavePath(String copyPath){ String usingPath = Utils.getScreenPath(); LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper -- getScreenPath --"+copyPath); String newPath = ""; if(usingPath.contains(PicCons.SCREEN_PATH_A)){ // 从A到B newPath = copyPath.replace(PicCons.SCREEN_PATH_A, PicCons.SCREEN_PATH_B); } else if(usingPath.contains(PicCons.SCREEN_PATH_B)){ // 从B到A newPath = copyPath.replace(PicCons.SCREEN_PATH_B, PicCons.SCREEN_PATH_A); } LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper -- getCopyFilePath --"+newPath); return newPath; } //复制图片,利用管道流提升效率 private boolean copyAToB(String fileFrom , String fileTo){ File from = new File(fileFrom); if(from.exists()){ File to = new File(fileTo); if(!to.exists()){ try { to.createNewFile(); LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper -- copyAToB --create New file :" +to.getPath()); } catch (IOException e) { e.printStackTrace(); LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper -- copyAToB --create file has an Exception"); return false; } } FileInputStream in = null; FileOutputStream out = null; FileChannel infc = null; FileChannel outfc = null; try { in = new FileInputStream (from); out = new FileOutputStream (to); infc = in.getChannel(); outfc = out.getChannel(); // int temp = 0; // while ((temp=in.read ())!=-1) // { // out.write (temp); // } infc.transferTo(0, infc.size(), outfc); LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper -- copyAToB success from :"+ fileFrom+", to:"+fileTo); return true; } catch (Exception e) { e.printStackTrace(); LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper -- copyAToB has an Exception"); return false; } finally { try { if(null != in){ in.close(); } if(null != out){ out.close(); } if(null != infc){ infc.close(); } if(null != outfc){ outfc.close(); } } catch (Exception e) { e.printStackTrace(); } } } else{ LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper -- copyAToB fileFrom:"+fileFrom+" is not exists"); return false; } } private void copy(ArrayList<INFO_DL> cpList ,int messageType){ if(null == cpList){ return; } createFolder(); INFO_DL Item = null; for (int i = 0; i < cpList.size(); i++) { Item = cpList.get(i); boolean copysuccess = copyAToB(Item.copyPath, Item.savePath); if(copysuccess){ if(Utils.MD5Check(Item.savePath, Item.md5)){ Item.DLFlag = true; LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper -- copy file MD5 check success , update Json Item"); updateDLJson(Item.dlIndex, Item); } } } mHandle.sendEmptyMessage(messageType); } /** * 复制之前保证,PathA、PathB都存在 */ private void createFolder(){ File pathA = new File(filePath+PicCons.SCREEN_PATH_A); File pathB = new File(filePath+PicCons.SCREEN_PATH_B); if(!pathA.exists()){ pathA.mkdirs(); } if(!pathB.exists()){ pathB.mkdirs(); } } /** * 修改fullDLFlag的值,是否完全下载 */ private void setFullDLFlag(boolean fullDLFlag) { Utils.setFullDLFlag(fullDLFlag); LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper -- setFullDLFlag: "+fullDLFlag); } /** * 清空DLJsonList信息 */ private void cleanDLJson(){ if(null != DLJsonList){ DLJsonList.clear(); } } /** * 设置screenPath,图片成功数量大于约定上线,则设置,否则不设置 * @param setNow 是否直接设置,用于限制下载和copy都完成,则执行该逻辑 * @param isDownload */ private void setScreenPath(boolean setNow){ if(!setNow){ if(!isDownloadEnd || !isCopyEnd){ return; } } cleanDLJson(); String DLJsonStr = Utils.getDLJson(); int dlSuccessSize = 0; float dlTotalSize = 0; if(!TextUtils.isEmpty(DLJsonStr)){ try { JSONArray DLJsonArr= new JSONArray(DLJsonStr); JSONObject DLJsonItem = null; dlTotalSize = DLJsonArr.length(); for (int i = 0; i < dlTotalSize; i++) { DLJsonItem = DLJsonArr.optJSONObject(i); boolean dlSuccess = DLJsonItem.optBoolean("DLFlag"); if(dlSuccess){ dlSuccessSize++; } } if(dlTotalSize > 0){ float DLSuccessRate = (float) dlSuccessSize / dlTotalSize; LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper --setScreenPath DLSuccessRate is:"+DLSuccessRate); if(DLSuccessRate >= PicCons.SHOW_LIMIT){ String screenPath = getDLPath(); if(screenPath.contains(PicCons.SCREEN_PATH_A)){ Utils.setScreenPath(PicCons.SCREEN_PATH_A); // 设置显示目录为A LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper --setScreenPath PATH_A"); } else{ Utils.setScreenPath(PicCons.SCREEN_PATH_B); // 设置显示目录为B LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper --setScreenPath PATH_B"); } Utils.setUsingJson(DLJsonStr); // 设置使用Json LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicSyncHelper -- setUsingJson :"+DLJsonStr); } if(DLSuccessRate == 1.0f){ setFullDLFlag(true); } else{ setFullDLFlag(false); } } } catch (Exception e) { } } } }
public class Utils { public static String getPicTypeByUrl(String url){ String picType = ""; if(TextUtils.isEmpty(url)){ return picType; } int lastPointIndex = url.lastIndexOf("."); if(-1 == lastPointIndex){ return picType; } return url.substring(lastPointIndex, url.length()); } public static boolean MD5Check(String filepath, String md5){ if(TextUtils.isEmpty(filepath) || TextUtils.isEmpty(md5)){ return false; } try { String fileMd5 = MD5Util.getFileMD5String(new File(filepath)); return md5.equalsIgnoreCase(fileMd5); } catch (IOException e) { e.printStackTrace(); } return false; } /** * JSONArray数组转为ArrayList * @param dlFlag * @param jsonArray * @return */ public static ArrayList<INFO_DL> transJsonToList(JSONArray jsonArray){ if(null == jsonArray){ return null; } ArrayList<INFO_DL> jsonList = new ArrayList<INFO_DL>(); INFO_DL infoItem = null; JSONObject jsonObj = null; for (int i = 0; i < jsonArray.length(); i++) { infoItem = new INFO_DL(); jsonObj = jsonArray.optJSONObject(i); infoItem.md5 = jsonObj.optString("md5"); infoItem.url = jsonObj.optString("url"); infoItem.DLFlag = jsonObj.optBoolean("DLFlag"); infoItem.savePath = jsonObj.optString("savePath"); infoItem.dlIndex = jsonObj.optInt("dlIndex"); infoItem.reTry = jsonObj.optInt("reTry"); infoItem.copyPath = jsonObj.optString("copyPath"); infoItem.fileType = jsonObj.optString("fileType"); jsonList.add(infoItem); } return jsonList; } /** * 根据固件版本获取序列号 * @param version * @return */ public static String getServiceByVersion(String version){ String service = ""; if(TextUtils.isEmpty(version)){ return service; } int index = version.indexOf("-"); if(-1 == index){ return service; } return version.substring(0, index); } /** * 存云端时间 * * @param cloudTimestamp */ public static void setCloudTimestamp(String cloudTimestamp) { saveGlobalData(Define.KEY_SCREEN_CLOUDTIMESTAMP, cloudTimestamp); } /** * 获取云端时间戳 * * @return 云端时间戳 */ public static String getCloudTimestamp() { String cloudTimestamp = getGlobalData(Define.KEY_SCREEN_CLOUDTIMESTAMP); if (!TextUtils.isEmpty(cloudTimestamp)) { return cloudTimestamp; } return ""; } /** * 存屏保同步的时间戳,用于和云端时间戳比较 * * @param timestamp */ public static void setScreenTimestamp(String timestamp) { saveGlobalData(Define.KEY_SCREEN_TIMESTAMP, timestamp); } /** * 获取屏保同步时间戳 * * @return 上次同步时间,第一次为"" */ public static String getScreenTimestamp() { String timestamp = getGlobalData(Define.KEY_SCREEN_TIMESTAMP); if (!TextUtils.isEmpty(timestamp)) { return timestamp; } return ""; } /** * 存当前屏保正在使用的图片目录 * * @param screenUsingPath * 正在使用的图片目录 */ public static void setScreenPath(String screenUsingPath) { saveGlobalData(Define.KEY_SCREEN_USINGPATH, screenUsingPath); } /** * 获取当前屏保正在使用的图片目录 * * @return 屏保正在使用的目录,第一次为"",第一次进入屏保后该值应设置为PathA */ public static String getScreenPath() { String screenPath = getGlobalData(Define.KEY_SCREEN_USINGPATH); if (!TextUtils.isEmpty(screenPath)) { return screenPath; } return ""; } /** * 存屏保当前使用Json * * @param usingJson */ public static void setUsingJson(String usingJson) { saveGlobalData(Define.KEY_SCREEN_JSONUSING, usingJson); } /** * 获取屏保当前使用Json * * @return 当前使用的Json文件信息,第一次为"" */ public static String getUsingJson() { String usingJson = getGlobalData(Define.KEY_SCREEN_JSONUSING); if (!TextUtils.isEmpty(usingJson)) { return usingJson; } return ""; } /** * 存下载图片使用Json * * @param DLJson */ public static void setDLJson(String DLJson) { saveGlobalData(Define.KEY_SCREEN_JSONDL, DLJson); } /** * 获取下载图片使用Json * * @return 下载图片用到的Json文件 */ public static String getDLJson() { String DLJson = getGlobalData(Define.KEY_SCREEN_JSONDL); if (!TextUtils.isEmpty(DLJson)) { return DLJson; } return ""; } /** * 存图片是否完全下载成功 * * @param fullDL * true: 100%下载 ,false:未完全下载 */ public static void setFullDLFlag(boolean fullDL) { String fullDLFlag = "0"; if (fullDL) { fullDLFlag = "1"; } saveGlobalData(Define.KEY_SCREEN_FULLDL, fullDLFlag); } /** * 获取图片是否完全下载成功 * * @return true:完全下载,false:未完全下载 */ public static boolean getFullDLFlag() { String fullDLFlag = getGlobalData(Define.KEY_SCREEN_FULLDL); if (!TextUtils.isEmpty(fullDLFlag) && "1".equals(fullDLFlag)) { return true; } return false; } private static void saveGlobalData(String key, String value){ Common.getGlobalData().setGlobalData(key, value); } private static String getGlobalData(String key){ return Common.getGlobalData().getGlobalData(key); } }
public class PicDownloadManager implements Runnable{ private int dlIndex = 0; private INFO_DL dlInfo = null; private String dlPath = ""; private Handler mHandler = null; private int messageType = 1; // 消息类型,用于区分是否全量下载(无copy) private ArrayList<INFO_DL> dlList = new ArrayList<INFO_DL>(); /** * 下载管理类,负责从云端下载图片,包括下载成功后Md5Check,以及下载失败后最多3次重试 * @param dlList 下载List * @param handler 下载完成后发送消息到主线程 * @param messageType 发送消息类型(包括全量下载、部分下载) */ public PicDownloadManager(ArrayList<INFO_DL> dlList, Handler handler, int messageType){ this.messageType = messageType; this.dlList = dlList; mHandler = handler; initDLPath(); } /** * 初始化下载路径(绝对路径/data/data../PathA或PathB) */ private void initDLPath(){ dlPath = PicSyncHelper.getInstance().getDLPath(); } public void dlStart(){ dlInfo = dlList.get(dlIndex); PicDownloader pic = new PicDownloader(dlPath ,dlInfo ,mDLListener); pic.download(); } @Override public void run() { dlStart(); } /** * 下载监听,用于响应下载成功、下载失败以后的处理 */ private IDLListener mDLListener = new IDLListener() { @Override public void onFinish(INFO_DL info) { // md5 check // error retry,success dl next if(Utils.MD5Check(info.savePath, info.md5)){ // check success LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicDownloadManager -- onFinish Md5check success"); info.DLFlag = true; PicSyncHelper.getInstance().updateDLJson(info.dlIndex, info); // update dlJson if(dlIndex < dlList.size() - 1){ dlIndex++; dlInfo = dlList.get(dlIndex); PicDownloader pic = new PicDownloader(dlPath, dlInfo, mDLListener); pic.download(); } else{ mHandler.sendEmptyMessage(messageType); } } else{ // download error dealError(info); LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicDownloadManager -- onFinish Md5check error"); } } @Override public void onError(INFO_DL info) { // retry limit , download next dealError(info); LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicDownloadManager -- onError"); } }; /** * 处理下载失败的情况(包括下载成功但MD5 check失败的情况) * @param info */ private void dealError(INFO_DL info){ if(info.reTry < PicCons.MAX_RETRY){ info.reTry ++; PicDownloader pic = new PicDownloader(dlPath, info, mDLListener); pic.download(); } else{ if(dlIndex < dlList.size() - 1){ dlIndex++; dlInfo = dlList.get(dlIndex); PicDownloader pic = new PicDownloader(dlPath, dlInfo, mDLListener); pic.download(); } else{ mHandler.sendEmptyMessage(messageType); } } } public interface IDLListener { void onError(INFO_DL info); void onFinish(INFO_DL info); } } }
public class PicDownloader{ private String savePath; private INFO_DL DLInfo; private IDLListener listener; private String picName; /** * 执行图片下载类 * @param savePath 图片保存的路径 * @param DLInfo 下载封装信息体 * @param listener 下载状态回调 */ public PicDownloader(String savePath,INFO_DL DLInfo,IDLListener listener){ this.savePath = savePath; this.DLInfo = DLInfo; this.listener = listener; picName = DLInfo.md5+DLInfo.fileType; } /** * 开始下载 */ public void download() { HttpURLConnection conn = null; try { conn = (HttpURLConnection) new URL(DLInfo.url).openConnection(); conn.setConnectTimeout(PicCons.DEFAULT_TIMEOUT); conn.setReadTimeout(PicCons.DEFAULT_TIMEOUT); addRequestHeaders(conn); final int code = conn.getResponseCode(); LogHelper.releaseLog(PicCons.SCREEN_TAG,"PicDownloader -- run getResponseCode : " + code); if (PicCons.HTTP_OK == code) { dlInit(conn, code); } else{ LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicDownloader -- run listener.onError"); if(null != listener){ listener.onError(DLInfo); } return; } } catch (Exception e) { e.printStackTrace(); if(null != listener){ listener.onError(DLInfo); } LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicDownloader -- run has an Exception"); } finally { if (null != conn) conn.disconnect(); } } private void dlInit(HttpURLConnection conn, int code){ if (!createFile(savePath, picName)){ LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicDownloader -- dlInit Can not create file:"+savePath+"picName"); if(null != listener){ listener.onError(DLInfo); } return; } dlData(conn); } private void dlData(HttpURLConnection conn){ InputStream is = null; FileOutputStream fos = null; try { is = conn.getInputStream(); fos = new FileOutputStream(new File(savePath, picName)); byte [] b = new byte[4096]; int len; while((len = is.read(b)) != -1){ fos.write(b, 0, len); } LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicDownloader -- dlData download finish : "+savePath+"-"+DLInfo.md5); if(null != listener){ listener.onFinish(DLInfo); } } catch (IOException e) { e.printStackTrace(); if(null != listener){ listener.onError(DLInfo); } LogHelper.releaseLog(PicCons.SCREEN_TAG, "PicDownloader -- dlData has an Exception"); return; } finally { try { if(null != is){ is.close(); } if(null != fos){ fos.close(); } } catch (IOException e) { e.printStackTrace(); } } } private synchronized boolean createFile(String path, String fileName) { boolean hasFile = false; try { File dir = new File(path); boolean hasDir = dir.exists() || dir.mkdirs(); if (hasDir) { File file = new File(dir, fileName); hasFile = file.exists() || file.createNewFile(); DLInfo.savePath = file.getPath(); } } catch (IOException e) { e.printStackTrace(); } return hasFile; } private void addRequestHeaders(HttpURLConnection conn) { conn.addRequestProperty("Accept", "image/gif, image/jpeg, image/pjpeg, image/pjpeg," + "application/x-shockwave-flash, application/xaml+xml," + "application/vnd.ms-xpsdocument, application/x-ms-xbap," + "application/x-ms-application, application/vnd.ms-excel," + "application/vnd.ms-powerpoint, application/msword, */*"); conn.addRequestProperty("Charset", "UTF-8"); conn.addRequestProperty("Connection", "Keep-Alive"); conn.addRequestProperty("Accept-Encoding", "identity"); } }
原文:http://blog.csdn.net/adayabetter/article/details/51193386