RFFileUploadModule.java 11.2 KB
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();
            }
        }
    }
}