package com.usai.util; import android.content.Context; import android.content.SharedPreferences; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.Bundle; import android.util.Base64; import android.util.Log; import com.usai.redant.raimage.RedAntApplication; import org.json.JSONException; import org.json.JSONObject; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.List; import static com.usai.util.Network.URL_UPLOAD; /** * Created by ray on 13/06/2017. */ public class RAUploadManager { public int maxThread=3; public int activeThread; public int maxRetry=5; public int retryWaiting=300; public Boolean wifiOnly=false; // public Boolean autoStart=true; // public Boolean removeFinish=true; // public Boolean removeError=false; public QueueStatus queue_status; public static final int RESULT_BARCODE_ERROR=-50; public TaskStatus newtaskStatus= TaskStatus.TaskStatusWait; private ArrayList arr_queue; public ArrayList get_arr_queue() { return arr_queue; } // private List operation_queue; // private ExecutorService es = Executors.newFixedThreadPool(3);// // .newFixedThreadPool(); // private CountDownLatch latch = new CountDownLatch(maxThread); private RAOperationQueue operation_queue; public enum QueueStatus { QueueStatusDefault, QueueStatusAdd, QueueStatusError, QueueStatusFinishWithError, QueueStatusFinish } public enum TaskStatus { TaskStatusStop, TaskStatusStart, TaskStatusError, TaskStatusWait, TaskStatusFinish, //TaskStatusCancel, } public UIUpdateListener uiUpdateListener; public interface UIUpdateListener { // void onProgress(long index, double percentage); void updateCell(long index, Bundle taskinfo); // void updateList(); void updateList(ArrayList newlist); // void addTasks(ArrayList tasks); // void RemoveTasks(ArrayList tasks); // void onFinish(int code, String res/*, HashMap> headers*/); } // class Poll implements Runnable { // public void run() { // // while (queue.size()>0) { // while (!operation_queue.isEmpty()) { // System.out.println(operation_queue.poll()); // } // latch.countDown(); // } // } public RAUploadManager() { queue_status = QueueStatus.QueueStatusDefault; SharedPreferences UMSetting = RedAntApplication.getInstance() .getSharedPreferences("UploadManager", 0); if(UMSetting!=null) { // autoStart = UMSetting.getBoolean("auto_upload",false); // removeFinish = UMSetting.getBoolean("auto_rm_finish",false); // removeError = UMSetting.getBoolean("auto_rm_error",false); maxRetry = UMSetting.getInt("retry_count",5); newtaskStatus = TaskStatus.values()[UMSetting.getInt("newtask_status",TaskStatus.TaskStatusWait.ordinal())]; maxThread = UMSetting.getInt("max_thread",3); wifiOnly = UMSetting.getBoolean("wifi_only",false); } operation_queue = new RAOperationQueue(); operation_queue.setCallback(new RAOperationQueue.OperationCallback() { @Override public Boolean operate(final Bundle taskinfo) { // // ConnectivityManager connManager = (ConnectivityManager) context // .getSystemService(Context.CONNECTIVITY_SERVICE); // // NetworkInfo networkInfo = connManager // .getActiveNetworkInfo(); // if (networkInfo == null) // { // dbgUtil.Logd( // "Current Network info", // "can not get Active NetworkInfo!"); // false; // } // NetworkInfo.State netState = networkInfo // .getState(); // if (netState != NetworkInfo.State.CONNECTED) // { // dbgUtil.Logd( // "Current Network info", // "not Connected!State=" // + netState); // return; // } // int iconntype = -1; // iconntype = networkInfo // .getType(); // SharedPreferences pref = RedAntApplication // .getInstance() // .getSharedPreferences( // "UploadManager", // 0); // //// String aa = pref //// .getString( //// "aa", //// null); //// String ea = pref //// .getString( //// "ea", //// null); //// if (iconntype == ConnectivityManager.TYPE_WIFI) //// { //// if (!TextUtils //// .isEmpty(aa)) //// RedAntApplication.active_address = aa; //// } //// else //// { //// if (!TextUtils //// .isEmpty(ea)) //// RedAntApplication.active_address = ea; //// } // boolean // wifi_only // =pref.getBoolean("wifi_only", // true); // // if // (wifi_only // == true // && iconntype != // ConnectivityManager.TYPE_WIFI // && iconntype != // 9/* earthnet */) // boolean ret=false; String path=taskinfo.getString("path"); taskinfo.putInt("status",TaskStatus.TaskStatusStart.ordinal()); String url=taskinfo.getString("url")+""+URL_UPLOAD; int waiting=taskinfo.getInt("retry_waiting",0); int newwaiting = waiting; if(newwaiting/60.0<20) newwaiting+=retryWaiting; if(newwaiting>1200) newwaiting = 1200; taskinfo.putInt("retry_waiting",newwaiting); // try{ try { Thread.currentThread().sleep(waiting*1000); } catch (InterruptedException e) { e.printStackTrace(); } // }catch(InterruptedException ie){ // ie.printStackTrace(); // } JSONObject result=Network.UploadImage(path, taskinfo.getBundle("params"), url, new Network.FileUploadListener() { @Override public double percent_step() { //进度刷新步进 3% return 3.0; } @Override public boolean interupt() { // if(taskinfo.getBoolean("iscancel",false)) // return false; return taskinfo.getBoolean("iscancel",false); } @Override public void onProgress(long pro, double percentage) { synchronized(this){ Log.d("_synchronized", "UploadImage onProgress: " + percentage); long timeStart = System.currentTimeMillis(); taskinfo.putDouble("progress",percentage); if (uiUpdateListener!=null) { int index = arr_queue.indexOf(taskinfo); // uiUpdateListener.onProgress(index,percentage); uiUpdateListener.updateCell(index,taskinfo); } Log.d("_synchronized", "UploadImage onProgress: end" + (System.currentTimeMillis() - timeStart)); } } @Override public void onFinish(int code, String res) { Log.d("", "onFinish: "); } }); int r = 0; try { r = result.getInt("result"); if(r==2|| r==RESULT_BARCODE_ERROR) { taskinfo.putInt("status",TaskStatus.TaskStatusFinish.ordinal()); if(r==2) taskinfo.putString("msg","upload successful"); else { String rmsg=result.getString("msg"); taskinfo.putString("msg", "warning: " + rmsg); } } else { if(taskinfo.getInt("retry",0)>=maxRetry) { taskinfo.putInt("status",TaskStatus.TaskStatusError.ordinal()); taskinfo.putDouble("progress",0.0); String rmsg=result.getString("msg"); taskinfo.putString("msg",rmsg); } else { taskinfo.putInt("retry",taskinfo.getInt("retry",0)+1); taskinfo.putInt("status",TaskStatus.TaskStatusWait.ordinal()); taskinfo.putDouble("progress",0.0); taskinfo.putString("msg","connection lost, retry..."); ret=true; } } } catch (JSONException e) { // String rmsg=result.getString("msg"); taskinfo.putInt("status",TaskStatus.TaskStatusError.ordinal()); taskinfo.putDouble("progress",0.0); taskinfo.putString("msg","can not upload, please contact administrator."); e.printStackTrace(); } finally { synchronized (this) { Log.d("_synchronized", "UploadImage finally " ); long timeStart = System.currentTimeMillis(); if (uiUpdateListener!=null) { int index = arr_queue.indexOf(taskinfo); uiUpdateListener.updateCell(index,taskinfo); } Log.d("_synchronized", "UploadImage finally finish" + (System.currentTimeMillis() - timeStart)); } } return ret; // int a=0; // System.out.println(a+"running tid="+Thread.currentThread().getId()); // int min=1000; // int max=5000; // int sleep=new Random().nextInt(max)%(max-min+1) + min; // try{ // Thread.currentThread().sleep(sleep); // }catch(InterruptedException ie){ // ie.printStackTrace(); // } // System.out.println(a+" "+sleep+" finish tid="+Thread.currentThread().getId()); } @Override public void operateFinish(Bundle taskinfo) { TaskStatus status= TaskStatus.values()[taskinfo.getInt("status",0)]; //新增逻辑,对于成功上传的图片,从书记删除 //taskinfo.getString("msg").indexOf("warning:")<0 没有匹配错误 String path = filePath(taskinfo); File file = new File(path); //只有finish的task 可以删除图片 if(file.exists()&&taskinfo.getInt("status")== TaskStatus.TaskStatusFinish.ordinal()&&taskinfo.getString("msg").indexOf("warning:")<0) { String filepath=file.getAbsolutePath(); file.delete(); RAUtil.updateGallery(filepath); } /////////////////////////////////////////////// boolean removefromlist=false; // if (status==TaskStatus.TaskStatusFinish&&removeFinish) // removefromlist=true; // else if (status==TaskStatus.TaskStatusError&&removeError) // removefromlist=true; synchronized (this) { Log.d("_synchronized", "OperationCallback operateFinish: " ); long timeStart = System.currentTimeMillis(); if(removefromlist) { removeTask(taskinfo); // arr_queue.remove(taskinfo); // if(uiUpdateListener!=null) // uiUpdateListener.updateList(); } else { saveTasks(); } Log.d("_synchronized", "OperationCallback operateFinish: end" + (System.currentTimeMillis() - timeStart)); // saveTasks(); } } }); // operation_queue = new List() {}; loadTask(); } private void loadTask() { stopAllTasks(); arr_queue = new ArrayList(); Log.d("_RAIMAGE", "saveTasks: RAUploadManager"); SharedPreferences pref = RedAntApplication.getInstance() .getSharedPreferences("RA Image", 0); try { String tasksBase64 = pref.getString("task_list", ""); // ArrayList wrap_arr = new ArrayList(); // for( Bundle b:arr_queue) // { // String sjson=RAUtil.Bundle2Json(b).toString(); // Log.d("_RAIMAGE", "saveTasks: "+sjson); // wrap_arr.add(sjson); // } // // ByteArrayOutputStream baos = new ByteArrayOutputStream(); // ObjectOutputStream oos = new ObjectOutputStream(baos); // oos.writeObject(wrap_arr); // // String tasksBase64 = android.util.Base64.encodeToString(baos.toByteArray(), android.util.Base64.DEFAULT);//new String(Base64.encodeBase64(baos.toByteArray())); // // // editor.putString("task_list", tasksBase64); // // // editor.commit(); if(tasksBase64.length()>0) { byte[] decode=Base64.decode(tasksBase64,Base64.DEFAULT); ByteArrayInputStream bais= new ByteArrayInputStream(decode); ObjectInputStream ois = null; ois = new ObjectInputStream(bais); ArrayList arr_load=(ArrayList)ois.readObject(); for(String s:arr_load) { Log.d("_RAIMAGE", "loadTask: "+s); JSONObject jsobj = new JSONObject(s); Bundle b=RAUtil.Json2Bundle(jsobj); arr_queue.add(b); // String sjson=RAUtil.Bundle2Json(b).toString(); // wrap_arr.add(sjson); } } } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (JSONException e) { e.printStackTrace(); } for(Bundle b:arr_queue) { TaskStatus status= TaskStatus.values()[b.getInt("status",0)]; if (status!=TaskStatus.TaskStatusFinish&&status!=TaskStatus.TaskStatusError) startTask(b); } // int a = 0; // 此处缺少读取持久话保存任务队列的实现。 } public void addTask(Bundle task) { synchronized (this) { Log.d("_synchronized", "addTask: "); long timeStart = System.currentTimeMillis(); arr_queue.add(task); saveTasks(); Log.d("_synchronized", "addTask: end" + (System.currentTimeMillis() - timeStart)); } if(newtaskStatus== TaskStatus.TaskStatusWait) { startTask(task); } }; public void addTasks(ArrayList tasks) { synchronized (this) { Log.d("_synchronized", "addTasks: "); long timeStart = System.currentTimeMillis(); arr_queue.addAll(tasks); saveTasks(); Log.d("_synchronized", "addTasks: end" + (System.currentTimeMillis() - timeStart)); } if(newtaskStatus== TaskStatus.TaskStatusWait) { for (Bundle task:tasks) { startTask(task); } } }; public void startTask(Bundle task) { task.putBoolean("iscancel",false); boolean canstart = true; ConnectivityManager connManager = (ConnectivityManager) RedAntApplication.getInstance() .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connManager .getActiveNetworkInfo(); if (networkInfo == null) { dbgUtil.Logd( "Current Network info", "can not get Active NetworkInfo!"); canstart = false; } else { NetworkInfo.State netState = networkInfo .getState(); if (netState != NetworkInfo.State.CONNECTED) { dbgUtil.Logd( "Current Network info", "not Connected!State=" + netState); canstart = false; } int iconntype = -1; iconntype = networkInfo .getType(); if(wifiOnly == true && iconntype != ConnectivityManager.TYPE_WIFI && iconntype != 9/* earthnet */) { canstart = false; } } if(canstart) { task.putInt("retry_waiting",0); task.putInt("status", TaskStatus.TaskStatusWait.ordinal()); operation_queue.addOperation(task); } else { task.putInt("status", TaskStatus.TaskStatusStop.ordinal()); if (uiUpdateListener!=null) { int index = arr_queue.indexOf(task); // uiUpdateListener.onProgress(index,percentage); uiUpdateListener.updateCell(index,task); } } }; public void clearTask() { ArrayList remove = new ArrayList(); for(Bundle b:arr_queue) { // if(TaskStatus.values()[b.getInt("status",0)]==TaskStatus.TaskStatusStart||TaskStatus.values()[b.getInt("status",0)]==TaskStatus.TaskStatusWait) // continue; if(TaskStatus.values()[b.getInt("status",0)]==TaskStatus.TaskStatusFinish||TaskStatus.values()[b.getInt("status",0)]==TaskStatus.TaskStatusError) remove.add(b); // removeTask(b); } removeTasks(remove); } public void removeTask(Bundle task) { synchronized (this) { Log.d("_synchronized", "removeTask"); long timeStart = System.currentTimeMillis(); arr_queue.remove(task); saveTasks(); String path = filePath(task); File file = new File(path); //只有finish的task 可以删除图片 if(file.exists()&&task.getInt("status")== TaskStatus.TaskStatusFinish.ordinal()) { String filepath=file.getAbsolutePath(); file.delete(); RAUtil.updateGallery(filepath); } if(uiUpdateListener!=null) uiUpdateListener.updateList(arr_queue); Log.d("_synchronized", "removeTask: end" + (System.currentTimeMillis() - timeStart)); } }; public void removeTasks(List tasks) { synchronized (this) { Log.d("_synchronized", "removeTasks: " ); long timeStart = System.currentTimeMillis(); arr_queue.removeAll(tasks); saveTasks(); for(Bundle task:tasks) { String path = filePath(task); File file = new File(path); if(file.exists()&&task.getInt("status")== TaskStatus.TaskStatusFinish.ordinal()) { String filepath = file.getAbsolutePath(); file.delete(); RAUtil.updateGallery(filepath); } } if(uiUpdateListener!=null) uiUpdateListener.updateList(arr_queue); Log.d("_synchronized", "removeTasks: end" + (System.currentTimeMillis() - timeStart)); } }; public void stopAllTasks() { if(arr_queue==null) return; for (Bundle task:arr_queue) { stopTask(task); } }; public void stopTask(Bundle task) { if(task.getInt("status")!= TaskStatus.TaskStatusStart.ordinal()&&task.getInt("status")!= TaskStatus.TaskStatusWait.ordinal()) return; task.putBoolean("iscancel",true); // long tid=task.getLong("tid",-1); // if(tid>0) // { // // // } // task.tet("tid",Thread.currentThread().getId()); // RAUploadOperation } public void saveTasks() { Log.d("_RAIMAGE", "saveTasks: RAUploadManager"); SharedPreferences pref = RedAntApplication.getInstance() .getSharedPreferences("RA Image", 0); SharedPreferences.Editor editor = pref.edit(); try { ArrayList wrap_arr = new ArrayList(); for( Bundle b:arr_queue) { String sjson=RAUtil.Bundle2Json(b).toString(); Log.d("_RAIMAGE", "saveTasks: "+sjson); wrap_arr.add(sjson); } ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(wrap_arr); String tasksBase64 = android.util.Base64.encodeToString(baos.toByteArray(), android.util.Base64.DEFAULT);//new String(Base64.encodeBase64(baos.toByteArray())); editor.putString("task_list", tasksBase64); editor.commit(); // byte[] decode=Base64.decode(personBase64,Base64.DEFAULT); // ByteArrayInputStream bais= new ByteArrayInputStream(decode); // // ObjectInputStream ois = new ObjectInputStream(bais); // ArrayList arr_load=(ArrayList)ois.readObject(); // int a = 0; } catch (Exception e) { e.printStackTrace(); } // if (m_swSave.isChecked()&&!TextUtils.isEmpty(encryptPass)&&!TextUtils.isEmpty(encryptUser)) // { // editor.putString("user", encryptUser); // editor.putString("password", encryptPass); // editor.putBoolean("kepppass", true); // } // else // { // editor.putString("user", null); // editor.putString("password", null); // editor.putBoolean("kepppass", false); // } // // editor.puts // // editor.commit(); }; private String filePath(Bundle task) { // String path = Environment.getExternalStorageDirectory().getPath(); // path+="/"+task.getString("path"); // path+="/"+task.getString("file"); return task.getString("path",""); } }