package com.sunvote.xpadcomm; import android.os.Handler; import android.os.HandlerThread; import com.sunvote.util.LogUtil; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; /** * Created by Elvis on 2018/3/21 16:13 * Email:Eluis@psunsky.com * 版权所有:长沙中天电子设计开发有限公司 * Description: 文件上传模块 */ public class RFFileUploadModule { public static final byte PACKTYPE = 5 ; public static final int SLEEP_TIME = 25 ; public static byte index = 0 ; private RFFileUploadModule(){ handlerThread = new HandlerThread(RFFileUploadModule.class.getSimpleName()); handlerThread.start(); handler = new Handler(handlerThread.getLooper()); } private static RFFileUploadModule instance ; public static RFFileUploadModule getInstance() { if(instance == null){ synchronized (RFFileUploadModule.class){ if(instance == null){ instance = new RFFileUploadModule(); } } } return instance; } private IUploadListener uploadListener = new IUploadListener() { @Override public void onUploadStart() { System.out.println("onUploadStart"); } @Override public void onUploadProcess(double process) { System.out.println("onUploadProcess:" + process); } @Override public void onUploadStop() { System.out.println("onUploadStop"); } @Override public void onFail() { System.out.println("onFail"); } }; private String filename; private byte[] datas = new byte[1024]; private int length = 1024; private HandlerThread handlerThread ; private Handler handler ; private byte[] keyid = new byte[2]; private Runnable task; private int packTotal ; private boolean isStop = false ; /** * 文件名不能超过16个字符(中文不能超过8个),超过16个字符将会出现截断。 * 文件长度不能超过65535个字节 * @param file 文件 * @return 是否成功发起上传 */ public boolean uploadFile(File file){ LogUtil.i("RFFileUploadModule","uploadFile" + file); if(file != null){ length = (int)file.length(); filename = file.getName(); datas = new byte[length+4]; FileInputStream fis = null ; try { fis = new FileInputStream(file); int start = 0 ; // 把文件数据读入字节数组。 while(start < length){ int ret = fis.read(datas,start,length-start); if(ret < 0){ break; } start += ret ; } datas[length] = 0x13 ; datas[length + 1] = 0x0 ; datas[length + 2] = 0x10 ; datas[length + 3] = 0x0 ; if(start >= length){ task = new A0(filename,length); handler.removeCallbacks(task); handler.post(task); // packetConfirmation((byte)0); return true; } } catch (Exception e) { e.printStackTrace(); }finally { if(fis != null){ try { fis.close(); } catch (IOException e) { e.printStackTrace(); } fis = null; } } } return false; } public void setKeyid(byte[] keyid) { setKeyid(keyid,0); } public void setKeyid(byte[] keyid,int start) { this.keyid[0] = keyid[start]; this.keyid[1] = keyid[start+1]; } public void onUploadFile(byte data, byte[] keyid, byte packid, byte packH, byte[] packLs) { if (data == 1) { setKeyid(keyid); packetConfirmation(packid); } if (data == 2) { uploadData(packid, packH, packLs); } if (data == 3) { packetReceptionConfirmed(packid, packH); } } public void uploadData(byte packid, byte packH, byte[] packLs){ System.out.println("uploadData"); handler.removeCallbacks(task); if(task instanceof A2){ ((A2)task).setStop(true); } task = new A2(keyid,packid,packH,datas,packLs); handler.post(task); if(uploadListener != null){ double process = 0 ; if(packTotal > 0){ int count = 0 ; int sen = (packLs[1] & 0xFF) * 256 + (packLs[0] & 0XFF); for(int i = 0 ; i < 16 ; i++){ if((sen & (1 << i)) == 0){ count ++ ; } } int been = packH * 16 + count ; if(been > packTotal){ been = packTotal ; } process = (double)(been) / packTotal ; } uploadListener.onUploadProcess(process); } } public void packetConfirmation(byte packid){ System.out.println("packetConfirmation"); handler.removeCallbacks(task); byte[] names = null; if(filename != null){ try { names = filename.getBytes("GB2312"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } task = new A1(keyid,(byte)((length + 4 ) / 65535), (byte)(((length + 4) % 65535) / 256),(byte)((length + 4) % 256),names); handler.post(task); } public void packetReceptionConfirmed(byte packid,byte packH){ System.out.println("packetReceptionConfirmed"); handler.removeCallbacks(task); task = new A3(keyid,packid,packH); handler.post(task); } public boolean uploadFile(byte[] datas){ System.out.println("uploadFile" + datas); if(datas != null){ length = datas.length ; filename = null ; this.datas = new byte[length + 4]; System.arraycopy(datas,0,this.datas,0,length); datas[length] = 0x13 ; datas[length + 1] = 0x0 ; datas[length + 2] = 0x10 ; datas[length + 3] = 0x0 ; task = new A0(filename,length); handler.removeCallbacks(task); handler.post(task); // packetConfirmation((byte)0); return true; } return false; } public void setUploadListener(IUploadListener uploadListener) { this.uploadListener = uploadListener; } class A0 implements Runnable{ private int length ; private String filename; private int times ; public A0(String filename,int length){ this.length = length ; this.filename = filename; packTotal = length / 16 + 1; times = 0 ; index++; } @Override public void run() { LogUtil.i("RFFileUploadModule","A0 run"); XPadApi.getInstance().applyFileUpload(this.length,this.filename,PACKTYPE,index); times ++ ; if(task != null && times < 5){ handler.removeCallbacks(task); handler.postDelayed(task,5000); } } } class A1 implements Runnable{ private byte[] keyid; private byte packid ; private byte packH ; private byte packL ; private byte[] names ; private int times ; public A1(byte[] keyid, byte packid,byte packH,byte packL,byte[] names) { LogUtil.i("RFFileUploadModule","A1"); this.keyid = keyid; this.packid = packid; this.packH = packH ; this.packL = packL ; this.names = names ; times = 0 ; } @Override public void run() { LogUtil.i("RFFileUploadModule","A1 run"); XPadApi.getInstance().packetConfirmation(this.keyid,this.packid,this.packH,this.packL,this.names,PACKTYPE); times ++ ; if(task != null && times < 5){ handler.removeCallbacks(task); handler.postDelayed(task,5000); } if(uploadListener != null){ uploadListener.onUploadStart(); isStop = false; } } } class A2 implements Runnable{ private byte[] keyid; private byte packid; private byte packH; private byte[] datas ; private byte[] packLs; private int times ; private boolean stop = false; public void setStop(boolean stop) { this.stop = stop; } public A2(byte[] keyid, byte packid, byte packH, byte[] datas, byte[] packLs) { LogUtil.i("RFFileUploadModule","A2"); this.keyid = keyid; this.packid = packid; this.packH = packH; this.datas = datas; this.packLs = packLs; times = 0 ; } @Override public void run() { LogUtil.i("RFFileUploadModule","A2 run"); int packLsi = (packLs[1] & 0xFF) * 256 + (packLs[0] & 0xFF); int offset = 0 ; int length = 16; System.out.println("packLsi:" + packLsi); for(byte packL = 0 ;packL < 16 && !stop ;packL ++) { if((packLsi & (1 << packL)) != 0){ offset = ((packid * 65535) + (packH) * 256 + 16 * (packL)) & 0xFFFF; XPadApi.getInstance().uploadFileData(this.keyid, this.packid, this.packH, (byte)(packL ), this.datas, offset, length,PACKTYPE); // need sleep ???? try{ Thread.sleep(SLEEP_TIME); } catch (Exception e) { e.printStackTrace(); } } } // datas = "123".getBytes(); // XPadApi.getInstance().uploadFileData(this.keyid, this.packid, this.packH, (byte)0, this.datas, offset, length); times ++ ; if(task != null && times < 5){ handler.removeCallbacks(task); handler.postDelayed(task,5000); } } } class A3 implements Runnable{ private byte[] keyid; private byte packid ; private byte packH; private int times ; public A3(byte[] keyid, byte packid, byte packH) { LogUtil.i("RFFileUploadModule","A3"); this.keyid = keyid; this.packid = packid; this.packH = packH; times = 0 ; } @Override public void run() { LogUtil.i("RFFileUploadModule","A3 run"); XPadApi.getInstance().packetReceptionConfirmed(this.keyid,this.packid,this.packH,PACKTYPE); if(uploadListener != null && !isStop){ isStop = true; uploadListener.onUploadStop(); } } } }