init
diff --git a/app/src/main/java/com/newcapec/jni/ApduResp.java b/app/src/main/java/com/newcapec/jni/ApduResp.java
new file mode 100644
index 0000000..940be4b
--- /dev/null
+++ b/app/src/main/java/com/newcapec/jni/ApduResp.java
@@ -0,0 +1,9 @@
+package com.newcapec.jni;
+
+public class ApduResp {
+
+ public short LenOut; //????IC??????????????
+ public byte[] DataOut = new byte[512]; //??IC??????????????
+ public byte SWA; //IC??????1
+ public byte SWB; //IC??????2
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/newcapec/jni/ApduSend.java b/app/src/main/java/com/newcapec/jni/ApduSend.java
new file mode 100644
index 0000000..d5dbe30
--- /dev/null
+++ b/app/src/main/java/com/newcapec/jni/ApduSend.java
@@ -0,0 +1,9 @@
+package com.newcapec.jni;
+
+
+public class ApduSend {
+ public byte[] Command = new byte[4]; //CLA, INS, P1, P2
+ public short Lc; //?????IC???????????
+ public byte[] DataIn = new byte[512]; //?????IC????????
+ public short Le; //????????????????
+}
diff --git a/app/src/main/java/com/newcapec/jni/AuxScreen.java b/app/src/main/java/com/newcapec/jni/AuxScreen.java
new file mode 100644
index 0000000..6e7a1cb
--- /dev/null
+++ b/app/src/main/java/com/newcapec/jni/AuxScreen.java
@@ -0,0 +1,197 @@
+package com.newcapec.jni;
+
+public class AuxScreen {
+
+ /**
+ * font code type
+ */
+ public static final int FONT_CODE_UCS2 = 0;
+ public static final int FONT_CODE_GB2312 = 1;
+ public static final int FONT_CODE_UTF8 = 2;
+
+
+ static {
+ try {
+ System.loadLibrary("auxScreen");
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * @return
+ */
+ public int open() {
+ return Native_ScrOpen();
+ }
+
+ /**
+ *
+ */
+ public void close() {
+ Native_ScrClose();
+ }
+
+ /**
+ * 清全屏
+ *
+ * @return
+ */
+ public int cls() {
+ return Native_ScrCls();
+ }
+
+ /**
+ * 清屏
+ *
+ * @param startline 起始行
+ * @param endline 结束行
+ * @return
+ */
+ public int clrLine(int startline, int endline) {
+ return Native_ScrClrLine(startline, endline);
+ }
+
+ /**
+ * 设置前景颜色
+ *
+ * @param fgcolor
+ * @return
+ */
+ public int setFgcolor(int fgcolor) {
+ return Native_ScrSetFgcolor(fgcolor);
+ }
+
+ /**
+ * 设置背景颜色
+ *
+ * @param bgcolor
+ * @return
+ */
+ public int setBgcolor(int bgcolor) {
+ return Native_ScrSetBgcolor(bgcolor);
+ }
+
+ /**
+ * 选择字体
+ *
+ * @param fonttype
+ * @return
+ */
+ public int selectFont(int fonttype) {
+ return Native_ScrSelectFont(fonttype);
+ }
+
+ /**
+ * 设置字体大小
+ *
+ * @param fontsize
+ * @return
+ */
+ public int setFontSize(int fontsize) {
+ return Native_ScrSetFontSize(fontsize);
+ }
+
+ /**
+ * 设置字、行间距
+ *
+ * @param CharSpace
+ * @param LineSpace
+ */
+ public void setSpace(int CharSpace, int LineSpace) {
+ Native_ScrSpaceSet(CharSpace, LineSpace);
+ }
+
+ /**
+ * 设置像素点颜色
+ *
+ * @param x
+ * @param y
+ * @param color
+ */
+ public void drawDot(int x, int y, int color) {
+ Native_ScrDrawDot(x, y, color);
+ }
+
+ /**
+ * 矩形框
+ *
+ * @param left
+ * @param top
+ * @param right
+ * @param bottom
+ * @param color
+ */
+ public void drawRect(int left, int top, int right, int bottom, int color) {
+ Native_ScrDrawRect(left, top, right, bottom, color);
+ }
+
+ /**
+ * 从某个点画字
+ *
+ * @param x
+ * @param y
+ * @param txt
+ * @return
+ */
+ public int textOut(int x, int y, String txt) {
+ return Native_ScrTextOut(x, y, txt);
+ }
+
+ /**
+ * 获取屏幕的宽高
+ *
+ * @param width
+ * @param height
+ * @return
+ */
+ public int getSize(int width[], int height[]) {
+ return Native_ScrGetSize(width, height);
+ }
+
+ public int drawBmp(int width, int height, byte bmp[]) {
+ return Native_ScrDrawBmp(width, height, bmp);
+ }
+
+ public void ScrDrawLogo() {
+ Native_ScrDrawLogo();
+ }
+
+ public void ScrClrRect(int left, int top, int width, int height) {
+ Native_ScrClrRect(left, top, width, height);
+ }
+
+
+ private native final int Native_ScrOpen();
+
+ private native final void Native_ScrClose();
+
+ private native final int Native_ScrCls();
+
+ private native final int Native_ScrClrLine(int startline, int endline);
+
+ private native final int Native_ScrSetFgcolor(int fgcolor);
+
+ private native final int Native_ScrSetBgcolor(int bgcolor);
+
+ private native final int Native_ScrSelectFont(int fonttype);
+
+ private native final int Native_ScrSetFontSize(int fontsize);
+
+ private native final void Native_ScrSpaceSet(int CharSpace, int LineSpace);
+
+ private native final void Native_ScrDrawDot(int x, int y, int color);
+
+ private native final void Native_ScrDrawRect(int left, int top, int right, int bottom, int color);
+
+ private native final int Native_ScrTextOut(int x, int y, String txt);
+
+ private native final int Native_ScrGetSize(int width[], int height[]);
+
+ private native final int Native_ScrDrawBmp(int width, int height, byte bmp[]);
+
+ private native final void Native_ScrDrawLogo();
+
+ private native final void Native_ScrClrRect(int left, int top, int width, int height);
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/newcapec/jni/Icc.java b/app/src/main/java/com/newcapec/jni/Icc.java
new file mode 100644
index 0000000..3a4f197
--- /dev/null
+++ b/app/src/main/java/com/newcapec/jni/Icc.java
@@ -0,0 +1,57 @@
+package com.newcapec.jni;
+
+/**
+ * 接触卡
+ *
+ * @author mayixi
+ */
+public class Icc {
+ static {
+
+ }
+
+ /**
+ * @param version
+ */
+ public Icc(int version) {
+ if (version < 110) {
+ System.loadLibrary("iccV108");
+ } else if (version < 115) {
+ System.loadLibrary("iccV110");
+ } else if (version < 116) {
+ System.loadLibrary("iccV115");
+ } else {
+ System.loadLibrary("iccV116");
+ }
+ }
+
+ public int init(byte slot, byte attr[]) {
+ return Native_Icc_Init(slot, attr);
+ }
+
+ public int close(byte slot) {
+ return Native_Icc_Close(slot);
+ }
+
+ public int autoResp(byte slot, byte autoresp) {
+ return Native_Icc_AutoResp(slot, autoresp);
+ }
+
+ public int sendIsoCommand(byte slot, ApduSend send, ApduResp recv) {
+ return Native_Icc_IsoCommand(slot, send, recv);
+ }
+
+ public int detect(byte slot) {
+ return Native_Icc_Detect(slot);
+ }
+
+ private native final int Native_Icc_Init(byte slot, byte atr[]);
+
+ private native final int Native_Icc_Close(byte slot);
+
+ private native final int Native_Icc_AutoResp(byte slot, byte autoresp);
+
+ private native final int Native_Icc_IsoCommand(byte slot, ApduSend send, ApduResp recv);
+
+ private native final int Native_Icc_Detect(byte slot);
+};
diff --git a/app/src/main/java/com/newcapec/jni/Picc.java b/app/src/main/java/com/newcapec/jni/Picc.java
new file mode 100644
index 0000000..fadb179
--- /dev/null
+++ b/app/src/main/java/com/newcapec/jni/Picc.java
@@ -0,0 +1,195 @@
+/*******************************************************************
+ * PiccInterface.java
+ * PiccInterface 、PICC_PARA、DetectInfo、ErrocCode
+ * A302 射频卡操作接口类
+ * 2014-11-05
+ * v0.1
+ *******************************************************************/
+package com.newcapec.jni;
+
+public class Picc {
+ static {
+
+ }
+
+ public static class PICC_PARA {
+
+ public byte drv_ver[]; // 驱动程序的版本信息,如:”1.01A”;只能读取,写入无效
+ public byte drv_date[]; // 驱动程序的日期信息,如:”2006.08.25”; 只能读取
+ public byte a_conduct_w; // A卡输出电导写入允许:1--允许,其它—不允许
+ public byte a_conduct_val; // A卡输出电导控制变量,有效范围0~63,超出时视为63
+ public byte m_conduct_w; // M1卡输出电导写入允许
+ public byte m_conduct_val; // M1卡输出电导控制变量,有效范围0~63,超出时视为63
+ public byte b_modulate_w; //B卡调制指数写入允许:
+ public byte b_modulate_val; // B卡调制指数控制变量,有效范围0~63,超出时视为63
+ public byte card_buffer_w; //卡片接收缓冲区大小写入允许:
+
+ public short card_buffer_val; //卡片接收缓冲区大小参数(单位:字节),有效值1~256.大于256时,将以256写入;设为0时,将不会写入
+ public byte wait_retry_limit_w; // S(WTX)响应发送次数写入允许(暂不适用)
+ public short wait_retry_limit_val; //S(WTX)响应最大重试次数(暂不适用)
+ public byte card_type_check_w; //卡片类型检查写入允许 */
+ public byte card_type_check_val; // 0-检查卡片类型,其他-不检查卡片类型(默认为检查卡片类型)
+ public byte card_RxThreshold_w; //B卡片接收灵敏度写入允许:1--允许,其它值--不允许。该值不可读
+ public byte card_RxThreshold_val; //B卡片接收灵敏度
+
+ public byte f_modulate_w; //felica调制指数写入允许
+ public byte f_modulate_val;
+ public byte a_modulate_w;
+ public byte a_modulate_val;
+ public byte a_card_RxThreshold_w;
+ public byte a_card_RxThreshold_val; //felica调制指数
+
+ /*A卡调制指数控制变量,有效范围0~63,超出时视为63*/
+ /*A卡接收灵敏度检查写入允许:1--允许,其它值--不允许*/
+ /*A卡接收灵敏度*/
+ public byte a_card_antenna_gain_w;
+ public byte a_card_antenna_gain_val; //A卡的天线增益
+ public byte b_card_antenna_gain_w;
+ public byte b_card_antenna_gain_val; //B卡的天线增益
+ public byte f_card_antenna_gain_w;
+ public byte f_card_antenna_gain_val; //Felica的天线增益
+ public byte f_card_RxThreshold_w;
+ public byte f_card_RxThreshold_val; //Felica的接收灵敏度
+ public byte f_conduct_w;
+ public byte f_conduct_val;
+ public byte user_control_w;
+ public byte user_control_val; //paypass认证需求,指定按键值,按下时强制退出交易*/ /*Felica的电导率*/
+ public byte reserved[]; //保留字节,用于将来扩展;写入时应全清零
+
+ public PICC_PARA() {
+ drv_ver = new byte[5];
+ drv_date = new byte[12];
+ reserved = new byte[72];
+ }
+ }
+
+ public static class DetectInfo {
+ public String CardType;
+ public String SerialInfo;
+ public String Cid;
+ public String Other;
+ public byte Cid_Array[];
+ public byte SerialInfo_Array[];
+
+ public DetectInfo() {
+ CardType = new String();
+ SerialInfo = new String();
+ Other = new String();
+ Cid = new String();
+
+ Cid_Array = new byte[10];
+ SerialInfo_Array = new byte[20];
+ }
+ }
+
+// public class ErrocCode {
+// public final static int PICC_STATUS_SUCCESS = 0x00; //成功
+// public final static int PICC_STATUS_ARGUMENTS_ERROR = 0x01; //参数错误
+// public final static int PICC_STATUS_NOT_OPEN = 0x02; //射频模块未开启
+// public final static int PICC_STATUS_NO_CARD = 0x03; //未搜寻到卡片(感应区内无指定类型的卡片)
+// public final static int PICC_STATUS_MANY_CARD = 0x04; //感应区内卡片过多(出现通讯冲突)
+// public final static int PICC_STATUS_ERROR_PROTOCOL = 0x06; //协议错误(卡片应答中出现违反协议规定的数据)
+// public final static int PICC_STATUS_CARD_NO_ACTIVE = 0x13; //卡片未激活
+// public final static int PICC_STATUS_CARDS_CONFLICT = 0x14; //多卡冲突?
+// public final static int PICC_STATUS_TIMEOUT = 0x15; //超时无响应
+// //public final static int PICC_STATUS_DATA_LONG = 0x16 ; //协议错误
+// public final static int PICC_STATUS_COMMUNICAT_ERROR = 0x17; //通信传输错误
+// public final static int PICC_STATUS_M1_CARD_Authentication_ERROR = 0x18; //M1卡认证失败
+// public final static int PICC_STATUS_SECTION_NO_Authentication = 0x19; //扇区未认证
+// public final static int PICC_STATUS_DATA_FORMAT_ERROR = 0x1A; //数值块数据格式有误
+// public final static int PICC_STATUS_CARD_IN_INDUCTION_ZONE = 0x1B; //卡片仍在感应区内
+// public final static int PICC_STATUS_CARD_STATE_ERROR = 0x1C; //卡片状态错误(如A/B卡调用M1卡接口, 或M1卡调用PiccIsoCommand接口)
+// public final static int PICC_STATUS_CARD_ABORT = 0xFF; //接口芯片不存在或异常
+// }
+
+ /**
+ * @param version
+ */
+ public Picc(int version) {
+ if (version < 110) {
+ System.loadLibrary("piccV108");
+ } else if (version < 116) {
+ System.loadLibrary("piccV115");
+ } else {
+ System.loadLibrary("piccV116");
+ }
+ }
+
+ public int open() {
+ return Native_Picc_Open();
+ }
+
+ public int setup(byte mode, PICC_PARA para) {
+ return Native_Picc_Setup(mode, para);
+ }
+
+ public int sendIsoCommand(byte cid, ApduSend Send, ApduResp Resp) {
+ return Native_Picc_IsoCommand(cid, Send, Resp);
+ }
+
+ public int remove(byte mode, byte cid) {
+ return Native_Picc_Remove(mode, cid);
+ }
+
+ public int close() {
+ return Native_Picc_Close();
+ }
+
+ public int m1Authority(byte Type, byte BlkNo, byte Pwd[], byte SerialNo[]) {
+ return Native_Picc_M1Authority(Type, BlkNo, Pwd, SerialNo);
+ }
+
+ public int readM1Block(byte BlkNo, byte BlkValue[], int BlkLen) {
+ return Native_Picc_M1ReadBlock(BlkNo, BlkValue, BlkLen);
+ }
+
+ public int writeM1Block(byte BlkNo, byte BlkValue[], int BlkLen) {
+ return Native_Picc_M1WriteBlock(BlkNo, BlkValue, BlkLen);
+ }
+
+ public int operateM1(byte Type, byte BlkNo, byte Value[], byte UpdateBlkNo) {
+ return Native_Picc_M1Operate(Type, BlkNo, Value, UpdateBlkNo);
+ }
+
+ public int light(byte ucLedIndex, byte ucOnOff) {
+ return Native_Picc_Light(ucLedIndex, ucOnOff);
+ }
+
+ public int initFelica(byte ucRate, byte ucPol) {
+ return Native_Picc_InitFelica(ucRate, ucPol);
+ }
+
+ public int exchangeCmd(int uiSendLen, String paucInData, int puiRecLen[], String paucOutData) {
+ return Native_Picc_CmdExchange(uiSendLen, paucInData, puiRecLen, paucOutData);
+ }
+
+ public int detect(byte Mode, DetectInfo info) {
+ return Native_Picc_Detect(Mode, info);
+ }
+
+ private native final int Native_Picc_Open();
+
+ private native final int Native_Picc_Setup(byte mode, PICC_PARA para);
+
+ private native final int Native_Picc_IsoCommand(byte cid, ApduSend ApduSend, ApduResp ApduRecv);
+
+ private native final int Native_Picc_Remove(byte mode, byte cid);
+
+ private native final int Native_Picc_Close();
+
+ private native final int Native_Picc_M1Authority(byte Type, byte BlkNo, byte Pwd[], byte SerialNo[]);
+
+ private native final int Native_Picc_M1ReadBlock(byte BlkNo, byte BlkValue[], int BlkLen);
+
+ private native final int Native_Picc_M1WriteBlock(byte BlkNo, byte BlkValue[], int BlkLen);
+
+ private native final int Native_Picc_M1Operate(byte Type, byte BlkNo, byte Value[], byte UpdateBlkNo);
+
+ private native final int Native_Picc_Light(byte ucLedIndex, byte ucOnOff);
+
+ private native final int Native_Picc_InitFelica(byte ucRate, byte ucPol);
+
+ private native final int Native_Picc_CmdExchange(int uiSendLen, String paucInData, int puiRecLen[], String paucOutData);
+
+ private native final int Native_Picc_Detect(byte Mode, DetectInfo info);
+};
diff --git a/app/src/main/java/com/newcapec/serial/SerialPort.java b/app/src/main/java/com/newcapec/serial/SerialPort.java
new file mode 100644
index 0000000..f8099fb
--- /dev/null
+++ b/app/src/main/java/com/newcapec/serial/SerialPort.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2009 Cedric Priscal
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.newcapec.serial;
+
+import java.io.IOException;
+
+public class SerialPort {
+
+ private static final String TAG = "SerialPort";
+ static {
+ System.loadLibrary("serial_port");
+ }
+
+ /**
+ * @name open
+ * @desc ??????1
+ * @param : ??
+ * @return 0-???, ????-???
+ * @throws IOException ??
+ */
+ public int open(int port, int baudrate, int flags)
+ {
+ return Native_Serial_Open(port, baudrate, flags);
+ }
+
+ /**
+ * @name sendMsg
+ * @desc ????????
+ * @param : ??
+ * @return 0-???, ????-???
+ * @throws IOException ??
+ */
+ public int sendMsg(byte[] msg)
+ {
+ return Native_Serial_SendMsg(msg);
+ }
+
+ /**
+ * @name recvMsg
+ * @desc ????????
+ * @param : ??
+ * @return 0-???, ????-???
+ * @throws IOException ??
+ */
+ public byte[] recvMsg()
+ {
+ return Native_Serial_RecvMsg();
+ }
+
+ /**
+ * @name close
+ * @desc ??????
+ * @param : ??
+ * @return 0-???, ????-???
+ * @throws IOException ??
+ */
+ public int close()
+ {
+ return Native_Serial_Close();
+ }
+
+
+ private native final int Native_Serial_Open(int port, int baudrate, int flags);
+ private native final int Native_Serial_SendMsg(byte[] msg);
+ private native final byte[] Native_Serial_RecvMsg();
+ private native final int Native_Serial_Close();
+
+}
diff --git a/app/src/main/java/com/supwisdom/activities/auxscreen/AuxScreenController.kt b/app/src/main/java/com/supwisdom/activities/auxscreen/AuxScreenController.kt
new file mode 100644
index 0000000..156367d
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/auxscreen/AuxScreenController.kt
@@ -0,0 +1,263 @@
+package com.supwisdom.auxscreen
+
+import android.graphics.Color
+import com.newcapec.jni.AuxScreen
+import com.supwisdom.utils.CommonUtil
+import java.util.concurrent.locks.ReentrantLock
+
+/**
+ * @author gqy
+ * @version 1.0.1
+ * @date 2018/7/11
+ * @desc 小屏控制器
+ */
+class AuxScreenController private constructor() {
+ private var auxScreen = AuxScreen()
+ private val xStart = 15
+ private val xSecStart = 240
+ private val sTitle = "refreshTitle"
+ private val sContent = "refreshContent"
+ private val sBottom = "refreshBottom"
+ private val lock = ReentrantLock()
+ private val refreshMap = hashMapOf<String, Any>()
+ private val auxRunnable = AuxRunnable()
+ private var isExit = false
+ private var taskThread: Thread? = null
+
+ companion object {
+ @Volatile
+ private var auxController: AuxScreenController? = null
+
+ fun getInstance(): AuxScreenController {
+ if (null == auxController) {
+ synchronized(AuxScreenController::class.java) {
+ if (null == auxController) {
+ auxController = AuxScreenController()
+ }
+ }
+ }
+ return auxController!!
+ }
+ }
+
+ /**
+ * 刷新标题栏
+ * @param title 标题
+ */
+ fun refreshTitle(title: String) {
+ lock.lock()
+ refreshMap[sTitle] = title
+ lock.unlock()
+ }
+
+ private fun localRefreshTitle(title: String) {
+ auxScreen.setBgcolor(Color.parseColor("#FFFFFF"))
+ auxScreen.clrLine(0, 50)
+ auxScreen.setBgcolor(Color.parseColor("#FFFFFF"))
+ auxScreen.setFontSize(20)
+ auxScreen.setFgcolor(Color.parseColor("#000000"))
+ auxScreen.textOut(xStart, 15, title)
+ }
+
+ /**
+ * 内容显示
+ * @param list 显示内容 size<=5
+ */
+ fun refreshContent(list: List<String>) {
+ lock.lock()
+ refreshMap[sContent] = list
+ lock.unlock()
+ }
+
+ private fun localRefreshContent(list: List<String>) {
+ auxScreen.setBgcolor(Color.parseColor("#F2F2F2"))
+ clearCenterContent()
+
+ val size = list.size
+ auxScreen.setFgcolor(Color.parseColor("#000000"))
+ when (size) {
+ 0 -> {
+
+ }
+ 1 -> {
+ auxScreen.setFontSize(40)
+ auxScreen.textOut(xStart, 140, getNotEmptyString(list[0]))
+ }
+ 2 -> {
+ auxScreen.setFontSize(35)
+ for (index in 0 until size) {
+ auxScreen.textOut(xStart, 120 + 60 * index, getNotEmptyString(list[index]))
+ }
+ }
+ 3 -> {
+ auxScreen.setFontSize(30)
+ for (index in 0 until size) {
+ auxScreen.textOut(xStart, 100 + 50 * index, getNotEmptyString(list[index]))
+ }
+ }
+ 4 -> {
+ auxScreen.setFontSize(25)
+ for (index in 0 until size) {
+ auxScreen.textOut(xStart, 80 + 45 * index, getNotEmptyString(list[index]))
+ }
+ }
+ 5 -> {
+ auxScreen.setFontSize(20)
+ for (index in 0 until size) {
+ auxScreen.textOut(xStart, 70 + 40 * index, getNotEmptyString(list[index]))
+ }
+ }
+ 6 -> {
+ auxScreen.setFontSize(15)
+ for (index in 0 until size) {
+ auxScreen.textOut(xStart, 60 + 35 * index, getNotEmptyString(list[index]))
+ }
+ }
+ 7, 8 -> {
+ auxScreen.setFontSize(25)
+ for (index in 0 until (size + 1) / 2) {
+ auxScreen.textOut(xStart, 80 + 45 * index, getNotEmptyString(list[2 * index]))
+ if (2 * index + 1 < size) {
+ auxScreen.textOut(xSecStart, 80 + 45 * index, getNotEmptyString(list[2 * index + 1]))
+ }
+ }
+ }
+ 9, 10 -> {
+ auxScreen.setFontSize(20)
+ for (index in 0 until (size + 1) / 2) {
+ auxScreen.textOut(xStart, 70 + 40 * index, getNotEmptyString(list[2 * index]))
+ if (2 * index + 1 < size) {
+ auxScreen.textOut(xSecStart, 70 + 40 * index, getNotEmptyString(list[2 * index + 1]))
+ }
+ }
+ }
+ else -> {
+ auxScreen.setFontSize(15)
+ for (index in 0 until (size + 1) / 2) {
+ auxScreen.textOut(xStart, 60 + 35 * index, getNotEmptyString(list[2 * index]))
+ if (2 * index + 1 < size) {
+ auxScreen.textOut(xSecStart, 60 + 35 * index, getNotEmptyString(list[2 * index + 1]))
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * 处理输入的空字符串
+ */
+ private fun getNotEmptyString(input: String?): String {
+ if (input == null || input.isEmpty()) {
+ return " "
+ }
+ return input
+ }
+
+ /**
+ * 刷新底部状态
+ * @param bottom 提示
+ */
+ fun refreshBottom(bottom: String) {
+ lock.lock()
+ refreshMap[sBottom] = bottom
+ lock.unlock()
+ }
+
+ private fun localRefreshBootom(bottom: String) {
+ auxScreen.setBgcolor(Color.parseColor("#FFFFFF"))
+ auxScreen.clrLine(269, 319)
+
+ auxScreen.setFontSize(20)
+ auxScreen.setFgcolor(Color.parseColor("#000000"))
+ auxScreen.textOut(15, 284, bottom)
+ }
+
+ /**
+ * 清空中间的内容
+ * @注意:此处必须一行一行的清除,底层bug
+ */
+ private fun clearCenterContent() {
+ auxScreen.clrLine(50, 100)
+ auxScreen.clrLine(100, 150)
+ auxScreen.clrLine(150, 200)
+ auxScreen.clrLine(200, 250)
+ auxScreen.clrLine(250, 269)
+ auxScreen.setFontSize(50)
+ }
+
+ /**
+ * 打开小屏
+ */
+ fun open() {
+ auxScreen.open()
+ if (taskThread == null) {
+ isExit = false
+ taskThread = Thread(auxRunnable)
+ taskThread!!.start()
+ }
+ }
+
+ /**
+ * 关闭小屏
+ */
+ fun close() {
+ auxScreen.close()
+ isExit = true
+ taskThread?.interrupt()
+ taskThread = null
+ }
+
+ /**
+ * 初始化小屏
+ */
+ private fun init() {
+ auxScreen.setBgcolor(Color.parseColor("#F2F2F2"))
+ auxScreen.cls()
+ auxScreen.setSpace(5, 5)
+ auxScreen.selectFont(AuxScreen.FONT_CODE_UTF8)
+ }
+
+ inner class AuxRunnable : Runnable {
+ override fun run() {
+ init()
+ while (!isExit) {
+ try {
+ try {
+ lock.lock()
+ val title = refreshMap[sTitle]
+ if (title != null) {
+ localRefreshTitle(title as String)
+ refreshMap.remove(sTitle)
+ }
+ } finally {
+ lock.unlock()
+ }
+ try {
+ lock.lock()
+ val content = refreshMap[sContent]
+ if (content != null) {
+ localRefreshContent(content as List<String>)
+ refreshMap.remove(sContent)
+ }
+ } finally {
+ lock.unlock()
+ }
+ try {
+ lock.lock()
+ val bottom = refreshMap[sBottom]
+ if (bottom != null) {
+ localRefreshBootom(bottom as String)
+ refreshMap.remove(sBottom)
+ }
+ } finally {
+ lock.unlock()
+ }
+ } catch (ex: Exception) {
+ ex.printStackTrace()
+ }
+ CommonUtil.doSleep(20)
+ }
+ }
+ }
+}
+
diff --git a/app/src/main/java/com/supwisdom/activities/auxscreen/AuxScreenViewSchedule.kt b/app/src/main/java/com/supwisdom/activities/auxscreen/AuxScreenViewSchedule.kt
new file mode 100644
index 0000000..896e3a6
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/auxscreen/AuxScreenViewSchedule.kt
@@ -0,0 +1,51 @@
+package com.supwisdom.activities.auxscreen
+
+import android.os.Handler
+import android.os.HandlerThread
+import android.os.Message
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class AuxScreenViewSchedule private constructor() {
+ private val mExector: Runnable? = null
+ private var mAuxWorkHandler: Handler
+ private var mHandlerThread: HandlerThread
+
+ companion object {
+ private var _instance: AuxScreenViewSchedule? = null
+ fun getInstancs(): AuxScreenViewSchedule {
+ if (_instance == null)
+ _instance =
+ AuxScreenViewSchedule()
+ return _instance!!
+ }
+ }
+
+ init {
+ mHandlerThread = HandlerThread("AuxScreenViewThread")
+
+ mHandlerThread.start()
+
+ mAuxWorkHandler = object : Handler(mHandlerThread.looper) {
+ override// 消息处理的操作
+ fun handleMessage(msg: Message) {
+ super.handleMessage(msg)
+ }
+ }
+ }
+
+ fun Post(r: Runnable, attr: Int) {
+ //定时任务
+ //mAuxWorkHandler.getLooper().getQueue()
+ mAuxWorkHandler.removeCallbacks(r)
+ mAuxWorkHandler.post(r)
+ }
+
+ fun PostDelayed(r: Runnable, millis: Int) {
+ //定时任务
+ //mAuxWorkHandler.getLooper().getQueue()
+ mAuxWorkHandler.postDelayed(r, millis.toLong())
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/consume/ConsumeActivity.kt b/app/src/main/java/com/supwisdom/activities/consume/ConsumeActivity.kt
new file mode 100644
index 0000000..f8da627
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/consume/ConsumeActivity.kt
@@ -0,0 +1,10 @@
+package com.supwisdom.activities.consume
+
+import com.supwisdom.activities.BaseActivity
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class ConsumeActivity : BaseActivity(), IConsumeView {
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/consume/IConsumeView.kt b/app/src/main/java/com/supwisdom/activities/consume/IConsumeView.kt
new file mode 100644
index 0000000..bca0fb1
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/consume/IConsumeView.kt
@@ -0,0 +1,8 @@
+package com.supwisdom.activities.consume
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+interface IConsumeView {
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/init/IInitView.kt b/app/src/main/java/com/supwisdom/activities/init/IInitView.kt
new file mode 100644
index 0000000..1f989f0
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/init/IInitView.kt
@@ -0,0 +1,15 @@
+package com.supwisdom.activities.init
+
+import android.app.Activity
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+interface IInitView {
+ fun getActivity(): Activity
+
+ fun showSWToastInfo(msg: String, showway: Int)
+
+ fun jumpToNextActivity()
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/init/InitActivity.kt b/app/src/main/java/com/supwisdom/activities/init/InitActivity.kt
new file mode 100644
index 0000000..c8785d0
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/init/InitActivity.kt
@@ -0,0 +1,244 @@
+package com.supwisdom.activities.init
+
+import android.app.Activity
+import android.net.nsd.NsdServiceInfo
+import android.os.Bundle
+import android.support.v7.widget.LinearLayoutManager
+import android.support.v7.widget.RecyclerView
+import android.widget.Button
+import android.widget.EditText
+import android.widget.RadioButton
+import android.widget.TextView
+import com.supwisdom.R
+import com.supwisdom.activities.BaseActivity
+import com.supwisdom.activities.SPApplication
+import com.supwisdom.activities.init.adapter.NsdServerConfigAdapter
+import com.supwisdom.activities.init.mode.NsdClient
+import com.supwisdom.activities.init.mode.NsdClientApi
+import com.supwisdom.activities.load.LoadActivity
+import com.supwisdom.auxscreen.AuxScreenController
+import com.supwisdom.entity.ConfigParaRecord
+import com.supwisdom.service.NtpClient
+import com.supwisdom.utils.CommonUtil
+import com.supwisdom.utils.DateUtil
+import com.supwisdom.utils.PublicDef
+import com.supwisdom.utils.ThreadPool
+import com.supwisdom.view.BigSwDialog
+import com.supwisdom.view.SWToast
+import java.util.*
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+@Suppress("DEPRECATION")
+class InitActivity : BaseActivity(), IInitView {
+ private lateinit var presenter: InitPresenter
+ private lateinit var vDevphyid: EditText
+ private lateinit var vServerIp: EditText
+ private lateinit var vUri: EditText
+ private lateinit var vPort: EditText
+ private lateinit var vNsdResult: TextView
+ private lateinit var vRadioPayMode: RadioButton
+ private lateinit var vRadioDepositMode: RadioButton
+ private lateinit var vRadioThirdPayMode: RadioButton
+ private lateinit var vRadioThirdLoginMode: RadioButton
+ private lateinit var vRadioGateMode: RadioButton
+ private var nsdClient: NsdClient? = null
+ private var nsdServiceIp: String? = null
+ private var nsdServicePort: Int = 0
+ private var dialogNsdConfig: BigSwDialog? = null
+ private var nsdConfigAdapter: NsdServerConfigAdapter? = null
+ private val pos = SPApplication.getInstance().getPos()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_init)
+ initView()
+ initData()
+ }
+
+ private fun initData() {
+ presenter = InitPresenter(this)
+ var record = pos.getConfigPara()
+ if (record == null) {
+ record = ConfigParaRecord()
+ record.mode = 0
+ record.devphyid = "12345678"
+ record.epayIP = "127.0.0.1"
+ record.epayPort = 8080
+ record.epayUri = "epayapi"
+ }
+ record.initOK = false
+ pos.replaceConfigPara(record)
+ val cfgRecord = pos.getConfigPara()!!
+
+// when {
+// cfgRecord.mode == PublicDef.TERMINAL_DEPOSIT_MODE -> vRadioDepositMode.isChecked = true
+// cfgRecord.mode == PublicDef.TERMINAL_THIRD_PAY_MODE -> vRadioThirdPayMode.isChecked = true
+// cfgRecord.mode == PublicDef.TERMINAL_GATE_MODE -> vRadioGateMode.isChecked = true
+// cfgRecord.mode == PublicDef.TERMINAL_THIRD_LOGIN_MODE -> vRadioThirdLoginMode.isChecked = true
+// else -> vRadioPayMode.isChecked = true
+// }
+ vDevphyid.setText(cfgRecord.devphyid)
+ vServerIp.setText(cfgRecord.epayIP)
+ vUri.setText(cfgRecord.epayUri)
+ vPort.setText(cfgRecord.epayPort.toString())
+
+ nsdClient = NsdClient(this, "epay-reg-server", object : NsdClient.IServerFound {
+ override fun onServerFound(serviceInfo: NsdServiceInfo) {
+ nsdServiceIp = serviceInfo.host?.hostAddress
+ nsdServicePort = serviceInfo.port
+ if (nsdServiceIp != null) {
+ asyncGetConfigName()
+ }
+ }
+
+ override fun onServerFail() {
+
+ }
+ })
+ }
+
+ private fun initView() {
+ this.findViewById<Button>(R.id.tv_settings).setOnClickListener {
+ // CommonUtil.sendBroadcast(applicationContext, false)
+ CommonUtil.startNetSetting(this@InitActivity)
+ }
+ this.findViewById<TextView>(R.id.btn_save).setOnClickListener {
+ // val mode = when {
+// vRadioDepositMode.isChecked -> PublicDef.TERMINAL_DEPOSIT_MODE
+// vRadioThirdPayMode.isChecked -> PublicDef.TERMINAL_THIRD_PAY_MODE
+// vRadioThirdLoginMode.isChecked -> PublicDef.TERMINAL_THIRD_LOGIN_MODE
+// vRadioGateMode.isChecked -> PublicDef.TERMINAL_GATE_MODE
+// else -> PublicDef.TERMINAL_PAY_MODE
+// }
+ presenter.saveConfigParam(
+ 0,
+ CommonUtil.getEditView(vDevphyid), CommonUtil.getEditView(vServerIp),
+ CommonUtil.getEditView(vUri), CommonUtil.getEditView(vPort)
+ )
+ }
+ this.findViewById<Button>(R.id.tv_nsd_query).setOnClickListener {
+ if (nsdServiceIp == null) {
+ showSWToastInfo("nsd未连接", PublicDef.TOAST_SHOW_DOUBT)
+ return@setOnClickListener
+ }
+ asyncGetConfigName()
+ }
+ vNsdResult = this.findViewById(R.id.tv_nsd_result) as TextView
+ vRadioPayMode = this.findViewById(R.id.rb_pay_mode) as RadioButton
+ vRadioDepositMode = this.findViewById(R.id.rb_deposit_mode) as RadioButton
+ vRadioThirdPayMode = this.findViewById(R.id.rb_third_pay_mode) as RadioButton
+ vRadioThirdLoginMode = this.findViewById(R.id.rb_third_login_mode) as RadioButton
+ vDevphyid = this.findViewById(R.id.tv_devphyid) as EditText
+ vServerIp = this.findViewById(R.id.tv_server_ip) as EditText
+ vUri = this.findViewById(R.id.tv_uri_root) as EditText
+ vPort = this.findViewById(R.id.tv_server_port) as EditText
+ }
+
+ override fun onResume() {
+ super.onResume()
+ nsdClient!!.start()
+ refresh()
+ }
+
+ override fun onStop() {
+ super.onStop()
+ nsdClient!!.stop()
+ }
+
+ private fun refresh() {
+ AuxScreenController.getInstance().refreshTitle("通讯参数设置")
+ AuxScreenController.getInstance().refreshBottom(DateUtil.getNowDate())
+ AuxScreenController.getInstance().refreshContent(Arrays.asList("设备第一次使用", "请联系管理员", "在大屏配置参数"))
+ }
+
+ private fun asyncGetConfigName() {
+ ThreadPool.getShortPool().execute(Runnable {
+ try {
+ val ret = NsdClientApi(nsdServiceIp!!, nsdServicePort).getNsdServerConfigList()
+ runOnUiThread {
+ vNsdResult.text = ret.retmsg
+ if (ret.retcode == PublicDef.SUCCESS) {
+ if (ret.list!!.isEmpty()) {
+ vNsdResult.text = "未找到配置项"
+ return@runOnUiThread
+ } else if (ret.list!!.size == 1) {
+ asyncGetConfigFromNsdServer(ret.list!![0])
+ return@runOnUiThread
+ }
+ vNsdResult.setTextColor(resources.getColor(R.color.light_blue2))
+ if (dialogNsdConfig == null) {
+ dialogNsdConfig = BigSwDialog(this, PublicDef.DIALOG_TYPE_NSD_CONFIG)
+ val vConfigList = dialogNsdConfig!!.findViewById(R.id.rv_config_list) as RecyclerView
+ vConfigList.layoutManager = LinearLayoutManager(this)
+ vConfigList.addItemDecoration(NsdServerConfigAdapter.ItemDecoration(10))
+ nsdConfigAdapter =
+ NsdServerConfigAdapter(this, object : NsdServerConfigAdapter.ConfigNameListener {
+ override fun callback(configName: String) {
+ asyncGetConfigFromNsdServer(configName)
+ dialogNsdConfig!!.dismiss()
+ }
+ })
+ vConfigList.adapter = nsdConfigAdapter
+ }
+ nsdConfigAdapter!!.setList(ret.list)
+ nsdConfigAdapter!!.notifyDataSetChanged()
+ dialogNsdConfig!!.show()
+ } else {
+ vNsdResult.setTextColor(resources.getColor(R.color.cl_red))
+ }
+ }
+ } catch (ex: Exception) {
+ runOnUiThread {
+ vNsdResult.text = "异常:${ex.message}"
+ vNsdResult.setTextColor(resources.getColor(R.color.cl_red))
+ }
+ }
+ })
+ }
+
+ private fun asyncGetConfigFromNsdServer(configName: String) {
+ ThreadPool.getShortPool().execute(Runnable {
+ try {
+ val ret = NsdClientApi(nsdServiceIp!!, nsdServicePort).getEcardConfigParam(configName)
+ NtpClient().startCalibrateTime(ret.systime)
+ runOnUiThread {
+ vNsdResult.text = ret.retmsg
+ if (ret.retcode == PublicDef.SUCCESS) {
+ vNsdResult.setTextColor(resources.getColor(R.color.light_blue2))
+ if (ret.mode == 0) {
+ vRadioPayMode.isChecked = true
+ } else {
+ vRadioDepositMode.isChecked = true
+ }
+ vDevphyid.setText(ret.devphyid)
+ vServerIp.setText(ret.epayIP)
+ vUri.setText(ret.epayUri)
+ vPort.setText(ret.epayPort.toString())
+ } else {
+ vNsdResult.setTextColor(resources.getColor(R.color.cl_red))
+ }
+ }
+ } catch (ex: Exception) {
+ runOnUiThread {
+ vNsdResult.text = "异常:${ex.message}"
+ vNsdResult.setTextColor(resources.getColor(R.color.cl_red))
+ }
+ }
+ })
+ }
+
+ override fun jumpToNextActivity() {
+ jumpActivity(LoadActivity::class.java)
+ }
+
+ override fun getActivity(): Activity {
+ return this
+ }
+
+ override fun showSWToastInfo(msg: String, showway: Int) {
+ SWToast.show(applicationContext, msg, showway)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/init/InitPresenter.kt b/app/src/main/java/com/supwisdom/activities/init/InitPresenter.kt
new file mode 100644
index 0000000..7f19261
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/init/InitPresenter.kt
@@ -0,0 +1,78 @@
+package com.supwisdom.activities.init
+
+import android.text.TextUtils
+import com.supwisdom.activities.SPApplication
+import com.supwisdom.activities.YktSession
+import com.supwisdom.entity.ConfigParaRecord
+import com.supwisdom.entity.ControlParaRecord
+import com.supwisdom.entity.DynamicParaRecord
+import com.supwisdom.utils.CommonUtil
+import com.supwisdom.utils.PublicDef
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class InitPresenter constructor(iInitView: IInitView) {
+ private val iInitView = iInitView
+ private val pos = SPApplication.getInstance().getPos()
+
+ fun saveConfigParam(mode: Int, devphyid: String, serverip: String, uri: String, port: String) {
+ val record = pos.getConfigPara() ?: ConfigParaRecord()
+ record.mode = mode
+ record.devphyid = devphyid
+ if (TextUtils.isEmpty(devphyid)) {
+ iInitView.showSWToastInfo("终端机编号不能为空!", PublicDef.TOAST_SHOW_DOUBT)
+ return
+ }
+ record.devphyid = devphyid.replace(" ", "")
+
+ if (TextUtils.isEmpty(serverip)) {
+ iInitView.showSWToastInfo("服务器IP不能为空!", PublicDef.TOAST_SHOW_DOUBT)
+ return
+ }
+ record.epayIP = serverip.replace(" ", "")
+ try {
+ val tmpPort = Integer.valueOf(port)
+ if (tmpPort > 65535) {
+ iInitView.showSWToastInfo("端口不能大于65535", PublicDef.TOAST_SHOW_DOUBT)
+ return
+ }
+ record.epayPort = tmpPort
+ } catch (e: Exception) {
+ iInitView.showSWToastInfo("端口不合法,请确认!", PublicDef.TOAST_SHOW_DOUBT)
+ return
+ }
+
+ if (TextUtils.isEmpty(uri)) {
+ iInitView.showSWToastInfo("URI不能为空!", PublicDef.TOAST_SHOW_DOUBT)
+ return
+ }
+ record.initOK = false
+ record.epayUri = uri.replace(" ", "")
+ record.shopPwd = PublicDef.PASSWD_SHOP_DEFAULT
+ pos.replaceConfigPara(record)
+
+ val dyRecord = DynamicParaRecord()
+ dyRecord.cardverno = "000000000000"
+// dyRecord.setAppId(PublicDef.APP_ID)
+// dyRecord.setAppSecret(PublicDef.APP_SECRET)
+ pos.replaceDynamicPara(dyRecord)
+
+ YktSession.getInstance().setWebAPISession(
+ record.epayIP!!,
+ record.epayPort,
+ record.epayUri!!,
+ record.devphyid!!,
+ CommonUtil.getCommunicateTime()
+ )
+ iInitView.jumpToNextActivity()
+ }
+
+ fun saveControlPara(name: String, value: String): Boolean {
+ val record = pos.getControlPara(name) ?: ControlParaRecord()
+ record.paraname = name
+ record.paraval = value
+ return pos.replaceControlPara(record)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/init/adapter/NsdServerConfigAdapter.kt b/app/src/main/java/com/supwisdom/activities/init/adapter/NsdServerConfigAdapter.kt
new file mode 100644
index 0000000..8f6e4f9
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/init/adapter/NsdServerConfigAdapter.kt
@@ -0,0 +1,70 @@
+package com.supwisdom.activities.init.adapter
+
+import android.content.Context
+import android.graphics.Rect
+import android.support.v7.widget.RecyclerView
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.LinearLayout
+import android.widget.TextView
+import com.supwisdom.R
+
+/**
+ * @author zzq
+ * @date 2018/7/12
+ * @desc nsd server 参数配置列表
+ */
+class NsdServerConfigAdapter constructor(context: Context, callback: ConfigNameListener) :
+ RecyclerView.Adapter<NsdServerConfigAdapter.Holder>() {
+ private val context = context
+ private val list = ArrayList<String>()
+ private val listener = callback
+ fun setList(data: List<String>?) {
+ list.clear()
+ if (data != null) {
+ list.addAll(data)
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
+ return Holder(LayoutInflater.from(context).inflate(R.layout.item_init_nsd_config_list, parent, false))
+ }
+
+ override fun getItemCount(): Int {
+ return list.size
+ }
+
+ override fun onBindViewHolder(holder: Holder, position: Int) {
+ holder.vConfigId.text = "配置$position:"
+ holder.vConfigName.text = list[position]
+ holder.vConfig.setOnClickListener {
+ listener.callback(list[position])
+ }
+ }
+
+ inner class Holder constructor(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ var vConfigName: TextView
+ var vConfigId: TextView
+ var vConfig: LinearLayout
+
+ init {
+ vConfigId = itemView.findViewById(R.id.tv_config_id) as TextView
+ vConfigName = itemView.findViewById(R.id.tv_config_name) as TextView
+ vConfig = itemView.findViewById(R.id.ll_config) as LinearLayout
+ }
+ }
+
+ class ItemDecoration constructor(space: Int) : RecyclerView.ItemDecoration() {
+ private val space = space
+ override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
+ outRect.left = space
+ outRect.right = space
+ outRect.bottom = space
+ }
+ }
+
+ interface ConfigNameListener {
+ fun callback(configName: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/init/bean/EcardConfigParamBean.kt b/app/src/main/java/com/supwisdom/activities/init/bean/EcardConfigParamBean.kt
new file mode 100644
index 0000000..538dbb3
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/init/bean/EcardConfigParamBean.kt
@@ -0,0 +1,17 @@
+package com.supwisdom.activities.init.bean
+
+import com.supwisdom.bean.BaseResp
+
+/**
+ * @author zzq
+ * @date 2018/7/11
+ * @desc 配置结果
+ */
+class EcardConfigParamBean constructor(retcode: Int, retmsg: String) : BaseResp(retcode, retmsg) {
+ var mode: Int = 0
+ var devphyid: String? = null
+ var epayIP: String? = null
+ var epayUri: String? = null
+ var epayPort: Int = 0
+ var systime: Long = 0
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/init/bean/EcardConfigParamRetBean.java b/app/src/main/java/com/supwisdom/activities/init/bean/EcardConfigParamRetBean.java
new file mode 100644
index 0000000..184c457
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/init/bean/EcardConfigParamRetBean.java
@@ -0,0 +1,54 @@
+package com.supwisdom.activities.init.bean;
+
+/**
+ * @author zzq
+ * @date 2018/7/12
+ * @desc nsd server返回结果
+ */
+public class EcardConfigParamRetBean {
+ private String _id;
+ private String name;
+ private String timestamp;
+ private String url;
+ private long system;
+
+ public String get_id() {
+ return _id;
+ }
+
+ public void set_id(String _id) {
+ this._id = _id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(String timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public long getSystem() {
+ return system;
+ }
+
+ public void setSystem(long system) {
+ this.system = system;
+ }
+}
diff --git a/app/src/main/java/com/supwisdom/activities/init/bean/NsdServerConfigRetBean.kt b/app/src/main/java/com/supwisdom/activities/init/bean/NsdServerConfigRetBean.kt
new file mode 100644
index 0000000..d6caa8f
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/init/bean/NsdServerConfigRetBean.kt
@@ -0,0 +1,12 @@
+package com.supwisdom.activities.init.bean
+
+import com.supwisdom.bean.BaseResp
+
+/**
+ * @author zzq
+ * @date 2018/7/12
+ * @desc nsd server 返回配置列表
+ */
+class NsdServerConfigRetBean constructor(retcode: Int, retmsg: String) : BaseResp(retcode, retmsg) {
+ var list: List<String>? = null
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/init/mode/NsdClient.kt b/app/src/main/java/com/supwisdom/activities/init/mode/NsdClient.kt
new file mode 100644
index 0000000..2f3bf18
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/init/mode/NsdClient.kt
@@ -0,0 +1,106 @@
+package com.supwisdom.activities.init.mode
+
+import android.content.Context
+import android.net.nsd.NsdManager
+import android.net.nsd.NsdServiceInfo
+import android.util.Log
+
+class NsdClient constructor(context: Context, serviceName: String, callback: IServerFound) {
+ private val TAG = NsdClient::class.java.simpleName
+ /**
+ * NSD_SERVICE_NAME和NSD_SERVER_TYPE需要与服务器端完全一致
+ */
+ private val NSD_SERVER_TYPE = "_http._tcp."
+ private val context = context
+ private val serviceName = serviceName
+ private val mIServerFound = callback
+
+ private var mDiscoveryListener: NsdManager.DiscoveryListener? = null
+ private var mResolverListener: NsdManager.ResolveListener? = null
+ private var mNsdManager: NsdManager? = null
+ private var singleFlag = false
+
+
+ fun start() {
+ mNsdManager = context.getSystemService(Context.NSD_SERVICE) as NsdManager
+ initializeDiscoveryListener()
+ mNsdManager!!.discoverServices(NSD_SERVER_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener)
+ initializeResolveListener()
+ }
+
+ /**
+ * 扫描未被解析前的 NsdServiceInfo
+ * 用于服务发现的回调调用接口
+ */
+ private fun initializeDiscoveryListener() {
+ mDiscoveryListener = object : NsdManager.DiscoveryListener {
+ override fun onStartDiscoveryFailed(serviceType: String, errorCode: Int) {
+ mNsdManager!!.stopServiceDiscovery(this)
+ Log.e(TAG, "onStartDiscoveryFailed():")
+ }
+
+ override fun onStopDiscoveryFailed(serviceType: String, errorCode: Int) {
+ mNsdManager!!.stopServiceDiscovery(this)
+ Log.e(TAG, "onStopDiscoveryFailed():")
+ }
+
+ override fun onDiscoveryStarted(serviceType: String) {
+ Log.e(TAG, "onDiscoveryStarted():")
+ }
+
+ override fun onDiscoveryStopped(serviceType: String) {
+ Log.e(TAG, "onDiscoveryStopped():")
+ }
+
+ /**
+ *
+ * @param serviceInfo
+ */
+ override fun onServiceFound(serviceInfo: NsdServiceInfo) {
+
+ //根据咱服务器的定义名称,指定解析该 NsdServiceInfo
+ if (serviceInfo.serviceName == serviceName) {
+ if (!singleFlag) {
+ singleFlag = true
+ mNsdManager!!.resolveService(serviceInfo, mResolverListener)
+ }
+ }
+ }
+
+ override fun onServiceLost(serviceInfo: NsdServiceInfo) {
+ Log.e(TAG, "onServiceLost(): serviceInfo=$serviceInfo")
+ }
+ }
+ }
+
+ /**
+ * 解析未 调用未被解析的 NsdServiceInfo
+ */
+ private fun initializeResolveListener() {
+ mResolverListener = object : NsdManager.ResolveListener {
+ override fun onResolveFailed(serviceInfo: NsdServiceInfo, errorCode: Int) {}
+
+ override fun onServiceResolved(serviceInfo: NsdServiceInfo) {
+ mIServerFound.onServerFound(serviceInfo)
+ }
+ }
+ }
+
+
+ fun stop() {
+ mNsdManager!!.stopServiceDiscovery(mDiscoveryListener)
+ singleFlag = false
+ }
+
+ interface IServerFound {
+ /**
+ * 回調 指定解析的结果
+ */
+ fun onServerFound(serviceInfo: NsdServiceInfo)
+
+ /**
+ * 無合適 回調失敗
+ */
+ fun onServerFail()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/init/mode/NsdClientApi.kt b/app/src/main/java/com/supwisdom/activities/init/mode/NsdClientApi.kt
new file mode 100644
index 0000000..79d8813
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/init/mode/NsdClientApi.kt
@@ -0,0 +1,81 @@
+package com.supwisdom.activities.init.mode
+
+import com.beust.klaxon.JsonArray
+import com.beust.klaxon.Parser
+import com.supwisdom.activities.init.bean.EcardConfigParamBean
+import com.supwisdom.activities.init.bean.EcardConfigParamRetBean
+import com.supwisdom.activities.init.bean.NsdServerConfigRetBean
+import com.supwisdom.okhttp.NetworkHandler
+import com.supwisdom.utilities.CommonUtil
+import com.supwisdom.utilities.GsonUtil
+import com.supwisdom.utilities.PublicDef
+import org.apache.http.HttpStatus
+
+/**
+ * @author zzq
+ * @date 2018/7/11
+ * @desc 从nsd-server获取数据
+ */
+class NsdClientApi constructor(ip: String, port: Int) {
+ private var url: String = "http://$ip:$port"
+
+ fun getEcardConfigParam(configName: String): EcardConfigParamBean {
+ val resp = NetworkHandler.getInstance().get("$url/ns/$configName", null)
+ ?: return EcardConfigParamBean(PublicDef.ERROR, "请求超时")
+ if (resp.retcode != HttpStatus.SC_OK) {
+ return EcardConfigParamBean(resp.retcode, "错误码=${resp.retcode},${resp.retmsg}")
+ }
+ try {
+ val retBean = GsonUtil.GsonToBean(resp.retjson, EcardConfigParamRetBean::class.java)
+ ?: return EcardConfigParamBean(PublicDef.ERROR, "解析为空")
+ val ret = EcardConfigParamBean(PublicDef.SUCCESS, "获取成功")
+ ret.systime = retBean.system
+ retBean.url!!.split("&", " ").forEach {
+ val keyValue = it.split("=")
+ when {
+ keyValue[0].compareTo("mode", ignoreCase = true) == 0 -> {
+ if (!CommonUtil.isNumeric(keyValue[1])) {
+ return EcardConfigParamBean(PublicDef.ERROR, "mode不是数字")
+ }
+ ret.mode = keyValue[1].toInt()
+ }
+ keyValue[0].compareTo("id", ignoreCase = true) == 0 -> {
+ if (!CommonUtil.isNumeric(keyValue[1])) {
+ return EcardConfigParamBean(PublicDef.ERROR, "id不是数字")
+ }
+ ret.devphyid = keyValue[1]
+ }
+ keyValue[0].compareTo("ip", ignoreCase = true) == 0 -> {
+ ret.epayIP = keyValue[1]
+ }
+ keyValue[0].compareTo("uri", ignoreCase = true) == 0 -> {
+ ret.epayUri = keyValue[1]
+ }
+ keyValue[0].compareTo("port", ignoreCase = true) == 0 -> {
+ if (!CommonUtil.isNumeric(keyValue[1])) {
+ return EcardConfigParamBean(PublicDef.ERROR, "port不是数字")
+ }
+ ret.epayPort = keyValue[1].toInt()
+ }
+ }
+ }
+ return ret
+ } catch (ex: Exception) {
+ ex.printStackTrace()
+ return EcardConfigParamBean(PublicDef.ERROR, "异常:${ex.message}")
+ }
+ }
+
+ fun getNsdServerConfigList(): NsdServerConfigRetBean {
+ val resp = NetworkHandler.getInstance().get("$url/list", null)
+ ?: return NsdServerConfigRetBean(PublicDef.ERROR, "请求超时")
+ if (resp.retcode != HttpStatus.SC_OK) {
+ return NsdServerConfigRetBean(resp.retcode, "错误码=${resp.retcode},${resp.retmsg}")
+ }
+ return NsdServerConfigRetBean(PublicDef.SUCCESS, "成功").apply {
+ this.list = (Parser().parse(StringBuilder(resp.retjson)) as JsonArray<String>).map {
+ it
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/load/ILoadView.kt b/app/src/main/java/com/supwisdom/activities/load/ILoadView.kt
new file mode 100644
index 0000000..e94d5c0
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/load/ILoadView.kt
@@ -0,0 +1,17 @@
+package com.supwisdom.activities.load
+
+import android.app.Activity
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+interface ILoadView {
+ fun getActivity(): Activity
+
+ fun showProgress(hint: String, clearlast: Boolean)
+
+ fun showFinish()
+
+ fun jumpToUnregister(errmsg: String)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/load/LoadActivity.kt b/app/src/main/java/com/supwisdom/activities/load/LoadActivity.kt
new file mode 100644
index 0000000..dccbe29
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/load/LoadActivity.kt
@@ -0,0 +1,99 @@
+package com.supwisdom.activities.load
+
+import android.app.Activity
+import android.content.Intent
+import android.os.Bundle
+import android.view.View
+import android.widget.TextView
+import android.widget.Toast
+import com.supwisdom.R
+import com.supwisdom.activities.BaseActivity
+import com.supwisdom.activities.SPApplication
+import com.supwisdom.activities.unregister.UnregisterActivity
+import com.supwisdom.auxscreen.AuxScreenController
+import com.supwisdom.utils.DateUtil
+import java.lang.StringBuilder
+import java.util.ArrayList
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class LoadActivity : BaseActivity(), ILoadView {
+ private lateinit var presenter: LoadPresenter
+ private lateinit var vLoadPro: TextView
+ private val procontent = StringBuilder()
+ private val auxList = ArrayList<String>()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_load)
+
+ initView()
+ initData()
+ }
+
+ override fun onResume() {
+ super.onResume()
+ presenter.start()
+ refresh()
+ }
+
+ private fun refresh() {
+ procontent.setLength(0)
+ auxList.clear()
+ AuxScreenController.getInstance().refreshTitle("设备参数加载")
+ AuxScreenController.getInstance().refreshBottom(DateUtil.getNowDate())
+ AuxScreenController.getInstance().refreshContent(auxList)
+ }
+
+ private fun initData() {
+ presenter = LoadPresenter(this)
+ }
+
+ private fun initView() {
+ this.findViewById<View>(R.id.btn_back).setOnClickListener {
+ if (presenter.isLoading()) {
+ Toast.makeText(applicationContext, "正在加载信息", Toast.LENGTH_SHORT).show()
+ } else {
+ this@LoadActivity.finish()
+ }
+ }
+ vLoadPro = findViewById<View>(R.id.tv_load_pro) as TextView
+ }
+
+ override fun getActivity(): Activity {
+ return this
+ }
+
+ override fun showProgress(hint: String, clearlast: Boolean) {
+ procontent.append("\n").append(hint)
+ vLoadPro.text = procontent.toString()
+ if (clearlast) {
+ auxList.removeAt(auxList.size - 1)
+ }
+ auxList.add(hint)
+ AuxScreenController.getInstance().refreshContent(showFormatAux())
+ }
+
+ override fun showFinish() {
+
+ }
+
+ override fun jumpToUnregister(errmsg: String) {
+ val intent = Intent()
+ intent.putExtra("errmsg", errmsg)
+ intent.setClass(this, UnregisterActivity::class.java!!)
+ startActivity(intent)
+ }
+
+ private fun showFormatAux(): List<String> {
+ val list = ArrayList<String>()
+ val size = auxList.size
+ list.addAll(auxList)
+ for (i in size..4) {
+ list.add(" ")
+ }
+ return list
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/load/LoadPresenter.kt b/app/src/main/java/com/supwisdom/activities/load/LoadPresenter.kt
new file mode 100644
index 0000000..701e029
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/load/LoadPresenter.kt
@@ -0,0 +1,60 @@
+package com.supwisdom.activities.load
+
+import android.os.Handler
+import android.os.Looper
+import android.os.Message
+import com.supwisdom.activities.SPApplication
+import com.supwisdom.utils.CommonUtil
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class LoadPresenter constructor(iLoadView: ILoadView) {
+ private val iLoadView = iLoadView
+ private val pos = SPApplication.getInstance().getPos()
+ private lateinit var handler: Handler
+
+ init {
+ createHandler()
+ }
+
+ private val LOAD_SUCCESS = 1
+ private val JUMP_TO_UNREGISTER = 2
+ private val LOAD_PROGRESS = 3
+ private val LOAD_DONE = 3
+
+ private var hasInit: Boolean = false
+ private var loading: Boolean = false
+
+ fun isLoading(): Boolean {
+ return loading
+ }
+
+ fun start() {
+
+ }
+
+ private fun createHandler() {
+ handler = object : Handler(Looper.getMainLooper()) {
+ override fun handleMessage(msg: Message) {
+ when (msg.what) {
+ LOAD_DONE -> iLoadView.showProgress(msg.obj as String, true)
+ LOAD_PROGRESS -> iLoadView.showProgress(msg.obj as String, false)
+ JUMP_TO_UNREGISTER -> iLoadView.jumpToUnregister(msg.obj as String)
+ LOAD_SUCCESS -> {
+ CommonUtil.doSleep(3000)
+ iLoadView.showFinish()
+ }
+ }
+ }
+ }
+ }
+
+ private fun sendMessage(code: Int, info: String) {
+ val msg = Message()
+ msg.what = code
+ msg.obj = info
+ handler.sendMessage(msg)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/unregister/UnregisterActivity.kt b/app/src/main/java/com/supwisdom/activities/unregister/UnregisterActivity.kt
new file mode 100644
index 0000000..9ce56b4
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/unregister/UnregisterActivity.kt
@@ -0,0 +1,60 @@
+package com.supwisdom.activities.unregister
+
+import android.content.Intent
+import android.os.Bundle
+import android.view.KeyEvent
+import android.widget.TextView
+import com.supwisdom.R
+import com.supwisdom.activities.BaseActivity
+import com.supwisdom.activities.init.InitActivity
+import com.supwisdom.auxscreen.AuxScreenController
+import com.supwisdom.utils.DateUtil
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class UnregisterActivity:BaseActivity() {
+ private lateinit var vErrmsg: TextView
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.setContentView(R.layout.activity_unregister)
+
+ initView()
+ }
+
+ private fun initView() {
+ val backBtn = this.findViewById(R.id.tv_back) as TextView
+ backBtn.setOnClickListener {
+ jumpActivity(InitActivity::class.java)
+ }
+ vErrmsg = this.findViewById(R.id.tv_errmsg) as TextView
+ }
+
+ override fun dispatchKeyEvent(event: KeyEvent?): Boolean {
+ return super.dispatchKeyEvent(event)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ }
+
+ override fun onResume() {
+ super.onResume()
+ val errmsg = intent.getStringExtra("errmsg")
+ refresh(errmsg)
+ vErrmsg.text = errmsg
+ }
+
+ private fun refresh(errmsg: String) {
+ AuxScreenController.getInstance().refreshTitle("设备注册状态")
+ AuxScreenController.getInstance().refreshBottom(DateUtil.getNowDate())
+ AuxScreenController.getInstance().refreshContent(listOf("设备未注册", errmsg))
+ }
+
+ override fun onNewIntent(intent: Intent) {
+ super.onNewIntent(intent)
+ this.intent.putExtra("errmsg", intent.getStringExtra("errmsg"))
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/upgrade/UpgradeAcvitity.kt b/app/src/main/java/com/supwisdom/activities/upgrade/UpgradeAcvitity.kt
index 025873d..0e57a3b 100644
--- a/app/src/main/java/com/supwisdom/activities/upgrade/UpgradeAcvitity.kt
+++ b/app/src/main/java/com/supwisdom/activities/upgrade/UpgradeAcvitity.kt
@@ -1,22 +1,179 @@
package com.supwisdom.activities.upgrade
+import android.content.Intent
+import android.net.Uri
+import android.os.Build
import android.os.Bundle
+import android.os.CountDownTimer
+import android.support.v4.content.FileProvider
+import android.view.KeyEvent
+import android.widget.Button
+import android.widget.TextView
+import com.supwisdom.R
import com.supwisdom.activities.BaseActivity
+import com.supwisdom.auxscreen.AuxScreenController
+import com.supwisdom.activities.upgrade.mode.EpayUpgradeApi
+import com.supwisdom.utils.CommonUtil
+import com.supwisdom.utils.DateUtil
+import com.supwisdom.utils.ThreadPool
+import java.io.File
+import java.util.*
/**
** create by zzq on 2019/7/24
** @desc
**/
+@Suppress("DEPRECATION")
class UpgradeAcvitity : BaseActivity() {
+ private lateinit var vResult: TextView
+ private lateinit var vUpgradeMsg: TextView
+ private lateinit var vServerUrl: TextView
+ private lateinit var vPosOldVersion: TextView
+ private lateinit var vPosVersion: TextView
+ private var isUpgrading = false
+ @Volatile
+ private var keyActive = true
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_upgrade)
+ initView()
+ initData()
}
- override fun onDestroy() {
- super.onDestroy()
+ private fun initData() {
+ vPosOldVersion.text = CommonUtil.getVersionName(this)
+ }
+
+ private fun initView() {
+ vResult = this.findViewById(R.id.tv_result) as TextView
+ vUpgradeMsg = this.findViewById(R.id.tv_upgrade_msg) as TextView
+
+ vServerUrl = this.findViewById(R.id.tv_server_url) as TextView
+ vPosOldVersion = this.findViewById(R.id.tv_old_version) as TextView
+ vPosVersion = this.findViewById(R.id.tv_pos_version) as TextView
+ this.findViewById<Button>(R.id.tv_upgrade).setOnClickListener {
+ asyncUpgrade()
+ }
+ }
+
+ override fun dispatchKeyEvent(event: KeyEvent): Boolean {
+ if (event.action == KeyEvent.ACTION_DOWN) {
+ if (isUpgrading || !keyActive) {
+ return super.dispatchKeyEvent(event)
+ }
+ resetCounter(200)
+
+ when (event.keyCode) {
+ KeyEvent.KEYCODE_DEL ->
+ //cancel
+ finish()
+ KeyEvent.KEYCODE_ENTER -> {
+ //ok
+ isUpgrading = true
+ AuxScreenController.getInstance().refreshContent(Arrays.asList<String>("正在升级", "请稍等..."))
+ asyncUpgrade()
+ }
+ }
+ }
+ return super.dispatchKeyEvent(event)
}
override fun onResume() {
super.onResume()
+ keyActive = true
+ refresh()
+ }
+
+ private fun refresh() {
+ isUpgrading = false
+ AuxScreenController.getInstance().refreshTitle("应用在线升级")
+ AuxScreenController.getInstance().refreshBottom(DateUtil.getNowDate())
+ AuxScreenController.getInstance().refreshContent(
+ Arrays.asList(
+ "当前版本>>", CommonUtil.getVersionName(applicationContext),
+ "确认 --应用升级", "取消 --退出"
+ )
+ )
+ }
+
+ private val upgradeApiCallback = object : EpayUpgradeApi.CallbackInterface {
+ override fun progresss(pro: Int) {
+ runOnUiThread {
+ vUpgradeMsg.text = "$pro%"
+ vUpgradeMsg.setTextColor(resources.getColor(R.color.black))
+ AuxScreenController.getInstance().refreshContent(Arrays.asList<String>("正在下载", "$pro%"))
+ }
+ }
+
+ override fun success(filepath: String) {
+ runOnUiThread {
+ isUpgrading = false
+ vUpgradeMsg.text = "下载成功"
+ vUpgradeMsg.setTextColor(resources.getColor(R.color.black))
+ AuxScreenController.getInstance().refreshContent(Arrays.asList<String>("下载应用成功", "请在大屏确认升级"))
+ val apkFile = File(filepath)
+ installAPK(apkFile)
+ }
+ }
+
+ override fun failed(errmsg: String) {
+ runOnUiThread {
+ isUpgrading = false
+ vUpgradeMsg.text = errmsg
+ vUpgradeMsg.setTextColor(resources.getColor(R.color.cl_red))
+ AuxScreenController.getInstance().refreshContent(Arrays.asList<String>("升级失败", "原因:", errmsg))
+ }
+ }
+ }
+
+ /**
+ * 开始下载apk
+ */
+ fun asyncUpgrade() {
+ ThreadPool.getDownloadPool().execute(Runnable {
+ EpayUpgradeApi(upgradeApiCallback).upgrade(CommonUtil.getVersionName(this))
+ })
+ }
+
+ /**
+ * 安装apk
+ */
+ private fun installAPK(apkFile: File) {
+ val intent = Intent(Intent.ACTION_VIEW)
+ intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
+ val contentUri = FileProvider.getUriForFile(
+ this, "com.supwisdom.charge.fileprovider", apkFile
+ )
+ intent.setDataAndType(contentUri, "application/vnd.android.package-archive")
+ } else {
+ intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive")
+ }
+ startActivity(intent)
+ }
+
+ private var counter: ContinuePressTimer? = null
+
+ private fun resetCounter(timems: Long) {
+ if (counter == null) {
+ counter = ContinuePressTimer(timems, 100)
+ }
+ counter!!.cancel()
+ keyActive = false
+ counter!!.start()
+ }
+
+ private inner class ContinuePressTimer internal constructor(millisInFuture: Long, countDownInterval: Long) :
+ CountDownTimer(millisInFuture, countDownInterval) {
+
+ override fun onTick(millisUntilFinished: Long) {
+
+ }
+
+ override fun onFinish() {
+ keyActive = true
+ }
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/upgrade/mode/EpayUpgradeApi.kt b/app/src/main/java/com/supwisdom/activities/upgrade/mode/EpayUpgradeApi.kt
new file mode 100644
index 0000000..1545002
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/upgrade/mode/EpayUpgradeApi.kt
@@ -0,0 +1,177 @@
+package com.supwisdom.activities.upgrade.mode
+
+import android.text.TextUtils
+import com.supwisdom.activities.YktSession
+import com.supwisdom.bean.UpgradeInfoRetBean
+import com.supwisdom.okhttp.WebParams
+import com.supwisdom.utils.*
+import org.apache.http.HttpStatus
+import java.io.File
+import java.io.FileInputStream
+import java.io.FileOutputStream
+import java.net.HttpURLConnection
+import java.net.URL
+import java.util.*
+
+/**
+ * @author zzq
+ * @date 2019/4/9
+ * @desc 在线升级
+ */
+class EpayUpgradeApi constructor(callbackInterface: CallbackInterface) {
+ private val TIMEOUT = 5 * 1000// 超时
+ private val callbackInterface = callbackInterface
+ private val POSID = "chargepos"
+
+ fun upgrade(versionName: String) {
+ val resp = getAppVersion()
+ if (resp.retcode != PublicDef.SUCCESS) {
+ callbackInterface.failed(resp.retmsg!!)
+ return
+ }
+ val updateFile = FileUtil.getUpdateFile("$POSID.zip")
+ if (updateFile == null) {
+ callbackInterface.failed("创建本地文件失败")
+ return
+ }
+ if (!downloadUpdateFile(resp.packageurl!!, updateFile, resp.packageversion!!)) {
+ return
+ }
+ parseDownloadFile(updateFile.absolutePath, resp.packageversion!!)
+ }
+
+ private fun downloadUpdateFile(downUrl: String, file: File, versionName: String): Boolean {
+// val downStep = 1// 提示step
+ var downStep = 0// 提示step
+ val totalSize: Int// 文件总大小
+ var downloadCount = 0// 已经下载好的大小
+ var updateCount = 0// 已经上传的文件大小
+ try {
+ val url = URL(downUrl)
+ val urlConnection = url.openConnection() as HttpURLConnection
+ urlConnection.connectTimeout = TIMEOUT
+ urlConnection.readTimeout = TIMEOUT
+ urlConnection.doOutput = true
+ urlConnection.doInput = true
+ urlConnection.useCaches = false
+ // setting serialized
+ urlConnection.setRequestProperty("Content-type", "application/x-java-serialized-object")
+ //default is GET
+ urlConnection.requestMethod = "POST"
+ urlConnection.setRequestProperty("Charsert", "UTF-8")
+ urlConnection.setRequestProperty("connection", "Keep-Alive")
+ urlConnection.addRequestProperty("version", versionName)
+
+ urlConnection.addRequestProperty("username", "supwisdom")
+ urlConnection.addRequestProperty("password", "supwisdom")
+ urlConnection.addRequestProperty("filename", "$POSID.apk")
+
+ //connect to server (tcp)
+ urlConnection.connect()
+ // 获取下载文件的size
+ totalSize = urlConnection.contentLength
+ if (urlConnection.responseCode != HttpStatus.SC_OK) {
+ urlConnection.disconnect()
+ callbackInterface.failed("下载文件失败:错误码=${urlConnection.responseCode}")
+ return false
+ }
+ val inputStream = urlConnection.inputStream
+ val outputStream = FileOutputStream(file, false)// 文件存在则覆盖掉
+ val buffer = ByteArray(1024)
+ while (true) {
+ val readSize = inputStream.read(buffer)
+ if (readSize < 0) {
+ break
+ }
+ outputStream.write(buffer, 0, readSize)
+ downloadCount += readSize// 实时获取下载到的大小
+
+ val progress = downloadCount * 1.0 / totalSize
+ val pro = Math.round(progress * 100).toInt()
+ if (pro - downStep >= 1) {
+ downStep++
+ CommonUtil.doSleep(100)
+ callbackInterface.progresss(pro)
+ }
+ }
+ urlConnection.disconnect()
+ inputStream.close()
+ outputStream.close()
+ return true
+ } catch (e: Exception) {
+ e.printStackTrace()
+ callbackInterface.failed("下载文件异常:${e.message}")
+ return false
+ }
+ }
+
+ private fun parseDownloadFile(zipFilePath: String, versionName: String): Boolean {
+ try {
+ val index = zipFilePath.lastIndexOf("/")
+ val unZipFilePath = zipFilePath.substring(0, index)
+ ZipUtil.unzip(zipFilePath, unZipFilePath, false)
+ val apkFile = File("$unZipFilePath/$POSID.apk")
+ if (!apkFile.exists()) {
+ callbackInterface.failed("未找到文件$POSID.apk")
+ return false
+ }
+
+ val fileHash256 = CryptUtil.HASH256(FileInputStream(apkFile), "nzoqPYMIu91VViA/mEIG5FtJXi8=")
+ if (fileHash256 == null) {
+ callbackInterface.failed("计算文件校验数据错误")
+ return false
+ }
+ val signFile = FileInputStream("$unZipFilePath/hash256.sign")
+ val buffer = ByteArray(1024)
+ val length = signFile.read(buffer, 0, buffer.size)
+ if (length < 0) {
+ callbackInterface.failed("读取校验文件失败")
+ return false
+ }
+ signFile.close()
+ val signHash256 = String(Arrays.copyOfRange(buffer, 0, length))
+ if (!fileHash256.equals(signHash256, ignoreCase = true)) {
+ callbackInterface.failed("文件校验错误")
+ return false
+ }
+ callbackInterface.success("$unZipFilePath/$POSID.apk")
+ return true
+ } catch (e: Exception) {
+ e.printStackTrace()
+ callbackInterface.failed("文件校验异常:${e.message}")
+ return false
+ }
+ }
+
+ private fun getAppVersion(): UpgradeInfoRetBean {
+ val params = WebParams()
+ params.setParameter("version_package_id", "com.supwisdom.$POSID")
+ .setParameter("sourcetype", "pos")
+
+ val signdata = params.getParameterString("version_package_id")
+ val resp = YktSession.getInstance().sendYktRequestPost("/common/apk/version", signdata, params)
+ ?: return UpgradeInfoRetBean(PublicDef.ERROR, "获取版本号网络超时")
+ if (resp.retcode != HttpStatus.SC_OK) {
+ return UpgradeInfoRetBean(resp.retcode, resp.retmsg!!)
+ }
+ return try {
+ val bean = GsonUtil.GsonToBean(resp.retjson!!, UpgradeInfoRetBean::class.java)
+ when {
+ TextUtils.isEmpty(bean.packageversion) -> UpgradeInfoRetBean(PublicDef.ERROR, "获取版本号为空")
+ TextUtils.isEmpty(bean.packageurl) -> UpgradeInfoRetBean(PublicDef.ERROR, "获取升级链接为空")
+ else -> bean
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ UpgradeInfoRetBean(PublicDef.ERROR, "获取版本号JSON错误:${e.message}")
+ }
+ }
+
+ interface CallbackInterface {
+ fun progresss(pro: Int)
+
+ fun success(filepath: String)
+
+ fun failed(errmsg: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/bean/BaseResp.kt b/app/src/main/java/com/supwisdom/bean/BaseResp.kt
index bb60f03..ac5fb29 100644
--- a/app/src/main/java/com/supwisdom/bean/BaseResp.kt
+++ b/app/src/main/java/com/supwisdom/bean/BaseResp.kt
@@ -4,5 +4,14 @@
** create by zzq on 2019/7/24
** @desc
**/
-open class BaseResp constructor(retcode: Int, retmsg: String) {
+open class BaseResp {
+ constructor(retcode: Int, retmsg: String?) {
+ this.retcode = retcode
+ this.retmsg = retmsg
+ }
+
+ constructor()
+
+ var retcode: Int = 0
+ var retmsg: String? = null
}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/bean/UpgradeInfoRetBean.kt b/app/src/main/java/com/supwisdom/bean/UpgradeInfoRetBean.kt
new file mode 100644
index 0000000..d32ccff
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/bean/UpgradeInfoRetBean.kt
@@ -0,0 +1,10 @@
+package com.supwisdom.bean
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class UpgradeInfoRetBean constructor(retcode: Int, retmsg: String) : BaseResp(retcode, retmsg) {
+ var packageversion: String? = null
+ var packageurl: String? = null
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/db/ControlParaDao.kt b/app/src/main/java/com/supwisdom/db/ControlParaDao.kt
new file mode 100644
index 0000000..8998aa8
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/db/ControlParaDao.kt
@@ -0,0 +1,101 @@
+package com.supwisdom.db
+
+import android.content.ContentValues
+import android.content.Context
+import android.database.Cursor
+import com.supwisdom.entity.ControlParaRecord
+import java.util.concurrent.locks.Lock
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class ControlParaDao constructor(context: Context) {
+ private val dbHelper = DBParaHelper.getInstance(context)
+ private val TABLE = DBParaHelper.TABLE_NAME_CONTROLPARA
+
+ fun getLock(): Lock {
+ return dbHelper.getLock()
+ }
+
+ fun replace(record: ControlParaRecord): Boolean {
+ val db = dbHelper.readableDatabase
+ val values = getContentValues(record)
+ try {
+ db.beginTransaction()
+ if (db.replace(TABLE, null, values) > 0) {
+ db.setTransactionSuccessful()
+ return true
+ }
+ } finally {
+ db.endTransaction()
+ }
+ return false
+ }
+
+ fun update(record: ControlParaRecord): Boolean {
+ val db = dbHelper.writableDatabase
+ val values = getContentValues(record)
+ try {
+ db.beginTransaction()
+ if (db.update(
+ TABLE,
+ values,
+ BeanPropEnum.ControlPara.paraname.toString() + "=?",
+ arrayOf(record.paraname)
+ ) > 0
+ ) {
+ db.setTransactionSuccessful()
+ return true
+ }
+ } finally {
+ db.endTransaction()
+ }
+ return false
+ }
+
+ fun get(paraname: String): ControlParaRecord? {
+ val db = dbHelper.readableDatabase
+ var cursor: Cursor? = null
+ try {
+ cursor = db.query(
+ TABLE, null, BeanPropEnum.ControlPara.paraname.toString() + "=?",
+ arrayOf(paraname), null, null, null
+ )
+ if (cursor != null && cursor.moveToNext()) {
+ return getRecord(cursor)
+ }
+ } finally {
+ cursor?.close()
+ }
+ return null
+ }
+
+ fun clear(): Boolean {
+ val db = dbHelper.writableDatabase
+ try {
+ db.beginTransaction()
+ if (db.delete(TABLE, null, null) < 0) {
+ return false
+ }
+ db.setTransactionSuccessful()
+ return true
+ } finally {
+ db.endTransaction()
+ }
+ }
+
+ private fun getRecord(cursor: Cursor): ControlParaRecord {
+ val record = ControlParaRecord()
+ record.paraname = cursor.getString(cursor.getColumnIndex(BeanPropEnum.ControlPara.paraname.toString()))
+ record.paraval = cursor.getString(cursor.getColumnIndex(BeanPropEnum.ControlPara.paraval.toString()))
+ return record
+ }
+
+ private fun getContentValues(record: ControlParaRecord): ContentValues {
+ val values = ContentValues()
+ values.put(BeanPropEnum.ControlPara.paraname.toString(), record.paraname)
+ values.put(BeanPropEnum.ControlPara.paraval.toString(), record.paraval)
+ return values
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/db/Pos.kt b/app/src/main/java/com/supwisdom/db/Pos.kt
index eff19ce..79caa4b 100644
--- a/app/src/main/java/com/supwisdom/db/Pos.kt
+++ b/app/src/main/java/com/supwisdom/db/Pos.kt
@@ -16,6 +16,7 @@
private var dyRecord: DynamicParaRecord? = null
private val sysParaDao = SysParaDao(context)
private var sysRecord: SysParaRecord? = null
+ private val controlParaDao = ControlParaDao(context)
private val transdtlOnlineDao = TransdtlOnlineDao(sdContext)
private val transdtlOfflineDao = TransdtlOfflineDao(sdContext)
@@ -50,6 +51,24 @@
return cfgRecord
}
+ fun replaceControlPara(record: ControlParaRecord): Boolean {
+ try {
+ controlParaDao.getLock().lock()
+ return controlParaDao.replace(record)
+ } finally {
+ controlParaDao.getLock().unlock()
+ }
+ }
+
+ fun getControlPara(paraname: String): ControlParaRecord? {
+ try {
+ controlParaDao.getLock().lock()
+ return controlParaDao.get(paraname)
+ } finally {
+ controlParaDao.getLock().unlock()
+ }
+ }
+
fun replaceDynamicPara(record: DynamicParaRecord): Boolean {
try {
dynamicParaDao.getLock().lock()
@@ -144,6 +163,7 @@
transdtlOfflineDao.getLock().unlock()
}
}
+
fun saveTransdtlOffline(record: TransdtlOfflineRecord): Boolean {
try {
transdtlOfflineDao.getLock().lock()
diff --git a/app/src/main/java/com/supwisdom/entity/ControlParaRecord.kt b/app/src/main/java/com/supwisdom/entity/ControlParaRecord.kt
new file mode 100644
index 0000000..9028aa7
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/entity/ControlParaRecord.kt
@@ -0,0 +1,10 @@
+package com.supwisdom.entity
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class ControlParaRecord {
+ var paraname: String? = null
+ var paraval: String? = null
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/okhttp/TransResp.kt b/app/src/main/java/com/supwisdom/okhttp/TransResp.kt
index 1ff26d9..3215172 100644
--- a/app/src/main/java/com/supwisdom/okhttp/TransResp.kt
+++ b/app/src/main/java/com/supwisdom/okhttp/TransResp.kt
@@ -4,13 +4,15 @@
** create by zzq on 2019/7/24
** @desc
**/
-class TransResp constructor(retcode: Int, retmsg: String) {
+class TransResp constructor(retcode: Int, retmsg: String?) {
/**
* HTTP返回码 retcode 200 success
*/
+ var retcode: Int = retcode
/**
* retmsg 返回消息,如果是200 则为空,非200则为返回错误信息
*/
+ var retmsg: String? = retmsg
/**
* 返回json信息
*/
diff --git a/app/src/main/java/com/supwisdom/utils/CommonUtil.kt b/app/src/main/java/com/supwisdom/utils/CommonUtil.kt
index aaeac12..91af8f7 100644
--- a/app/src/main/java/com/supwisdom/utils/CommonUtil.kt
+++ b/app/src/main/java/com/supwisdom/utils/CommonUtil.kt
@@ -12,6 +12,8 @@
import android.os.Build
import android.os.PowerManager
import android.provider.Settings
+import android.widget.EditText
+import com.supwisdom.activities.SPApplication
import java.io.File
import java.io.FileOutputStream
import java.io.PrintWriter
@@ -32,6 +34,22 @@
}
}
+ fun getEditView(et: EditText): String {
+ return et.text.toString().trim { it <= ' ' }.replace(" ", "")
+ }
+
+ fun getCommunicateTime(): Int {
+ var commTime = 2
+ val sysRecord = SPApplication.getInstance().getPos().getSysPara()
+ if (sysRecord != null) {
+ commTime = sysRecord.commTime
+ if (commTime == 0) {
+ commTime = 2
+ }
+ }
+ return commTime
+ }
+
fun YuanToFen(yuan: Double): Int {
return Math.round(yuan * 100).toInt()
}
diff --git a/app/src/main/java/com/supwisdom/utils/CryptUtil.kt b/app/src/main/java/com/supwisdom/utils/CryptUtil.kt
new file mode 100644
index 0000000..d1677e6
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/utils/CryptUtil.kt
@@ -0,0 +1,126 @@
+package com.supwisdom.utils
+
+import java.io.InputStream
+import java.io.UnsupportedEncodingException
+import java.security.InvalidKeyException
+import java.security.MessageDigest
+import java.security.NoSuchAlgorithmException
+import javax.crypto.Mac
+import javax.crypto.spec.SecretKeySpec
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+object CryptUtil {
+ fun HASH256(text: String): String? {
+ return algorithm2(text, "SHA-256", true)
+ }
+
+ fun HASH256(fis: InputStream): String? {
+ return algorithm(fis, "SHA-256")
+ }
+
+ fun HASH256(fis: InputStream, extData: String): String? {
+ return algorithm(fis, "SHA-256", extData)
+ }
+
+ fun HASH512(text: String): String? {
+ return algorithm2(text, "SHA-512", true)
+ }
+
+ fun MD5(text: String): String? {
+ return algorithm2(text, "MD5", false)
+ }
+
+ fun HMACSHA1(data: String, key: String): String? {
+ try {
+ val algorithm = "HmacSHA1"
+ val mac = Mac.getInstance(algorithm)
+ val spec = SecretKeySpec(key.toByteArray(), algorithm)
+ mac.init(spec)
+ val byteHMAC = mac.doFinal(data.toByteArray())
+ return byteHMAC.encodeHex()
+ } catch (e: InvalidKeyException) {
+ e.printStackTrace()
+ } catch (ignore: NoSuchAlgorithmException) {
+ ignore.printStackTrace()
+ }
+ return null
+ }
+
+ private fun algorithm2(text: String?, algorithm: String, isUpperCase: Boolean): String? {
+ if (text != null && text.isNotEmpty()) {
+ try {
+ //创建具有指定算法名称的信息摘要
+ val md = MessageDigest.getInstance(algorithm)
+ //使用指定的字节数组对摘要进行最后更新,然后完成摘要计算
+ val results = md.digest(text.toByteArray(charset("UTF-8")))
+ //将得到的字节数组变成字符串返回
+ val resultString = results.encodeHex()
+ return if (isUpperCase) {
+ resultString.toUpperCase()
+ } else {
+ resultString.toLowerCase()
+ }
+ } catch (ex: NoSuchAlgorithmException) {
+ ex.printStackTrace()
+ } catch (ex: UnsupportedEncodingException) {
+ ex.printStackTrace()
+ }
+ }
+ return null
+ }
+
+ private fun algorithm(fis: InputStream, algorithm: String): String? {
+ try {
+ //拿到一个MD5转换器,如果想使用SHA-1或SHA-256,则传入SHA-1,SHA-256
+ val md = MessageDigest.getInstance(algorithm)
+
+ //分多次将一个文件读入,对于大型文件而言,比较推荐这种方式,占用内存比较少。
+ val buffer = ByteArray(1024)
+ var length: Int
+ while (true) {
+ length = fis.read(buffer, 0, 1024)
+ if (length < 0) {
+ break
+ }
+ md.update(buffer, 0, length)
+ }
+ fis.close()
+ //转换并返回包含16个元素字节数组,返回数值范围为-128到127
+ return md.digest().encodeHex()
+ } catch (e: Exception) {
+ e.printStackTrace()
+ return null
+ }
+
+ }
+
+ private fun algorithm(fis: InputStream, algorithm: String, extData: String): String? {
+ try {
+ //拿到一个MD5转换器,如果想使用SHA-1或SHA-256,则传入SHA-1,SHA-256
+ val md = MessageDigest.getInstance(algorithm)
+
+ //分多次将一个文件读入,对于大型文件而言,比较推荐这种方式,占用内存比较少。
+ val buffer = ByteArray(1024)
+ var length: Int
+ while (true) {
+ length = fis.read(buffer, 0, 1024)
+ if (length < 0) {
+ break
+ }
+ md.update(buffer, 0, length)
+ }
+ fis.close()
+ md.update(extData.toByteArray(charset("UTF-8")))
+
+ //转换并返回包含16个元素字节数组,返回数值范围为-128到127
+ return md.digest().encodeHex()
+ } catch (e: Exception) {
+ e.printStackTrace()
+ return null
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/utils/GsonUtil.kt b/app/src/main/java/com/supwisdom/utils/GsonUtil.kt
new file mode 100644
index 0000000..2c6d722
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/utils/GsonUtil.kt
@@ -0,0 +1,30 @@
+package com.supwisdom.utils
+
+import com.alibaba.fastjson.JSON
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+object GsonUtil {
+ /**
+ * 转成json
+ *
+ * @param object
+ * @return
+ */
+ fun GsonString(obj: Any): String {
+ return JSON.toJSONString(obj)
+ }
+
+ /**
+ * 转成bean
+ *
+ * @param gsonString
+ * @param cls
+ * @return
+ */
+ fun <T> GsonToBean(gsonString: String, cls: Class<T>): T {
+ return JSON.parseObject(gsonString, cls)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/utils/PublicDef.kt b/app/src/main/java/com/supwisdom/utils/PublicDef.kt
index b860920..14fc606 100644
--- a/app/src/main/java/com/supwisdom/utils/PublicDef.kt
+++ b/app/src/main/java/com/supwisdom/utils/PublicDef.kt
@@ -40,4 +40,21 @@
const val TRANSFLAG_PWD_CONSUME = 0x04 // 密码消费
const val BG_SERVICE_NAME = "com.supwisdom.service.BackgroundTaskService"
+
+ /**
+ * Toast show
+ */
+ const val TOAST_SHOW_CRY = 1
+ const val TOAST_SHOW_SMILE = 2
+ const val TOAST_SHOW_DOUBT = 3
+
+ const val DIALOG_TYPE_BIG_PICTURE = 1
+ const val DIALOG_TYPE_PURCHASE = 2
+ const val DIALOG_TYPE_PASSWORD = 3
+ const val DIALOG_TYPE_SELECT_ORDER = 4
+ const val DIALOG_TYPE_DPS_CONFIRM = 5
+ const val DIALOG_TYPE_SCAN_RVS_CONFIRM = 6
+ const val DIALOG_TYPE_ORDINARY_CONSUME = 7
+ const val DIALOG_TYPE_DEPOSIT = 8
+ const val DIALOG_TYPE_NSD_CONFIG = 9
}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/utils/ZipUtil.kt b/app/src/main/java/com/supwisdom/utils/ZipUtil.kt
new file mode 100644
index 0000000..37f1d09
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/utils/ZipUtil.kt
@@ -0,0 +1,194 @@
+package com.supwisdom.utils
+
+import org.apache.commons.lang3.StringUtils
+import java.io.*
+import java.util.*
+import java.util.zip.*
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+object ZipUtil {
+ /**
+ * 递归压缩文件夹
+ *
+ * @param srcRootDir 压缩文件夹根目录的子路径
+ * @param file 当前递归压缩的文件或目录对象
+ * @param zos 压缩文件存储对象
+ * @throws Exception
+ */
+ @Throws(Exception::class)
+ private fun zip(srcRootDir: String, file: File?, zos: ZipOutputStream) {
+ if (file == null) {
+ throw Exception("file is null")
+ }
+
+ //如果是文件,则直接压缩该文件
+ if (file.isFile) {
+ var count: Int
+ val bufferLen = 1024
+ val data = ByteArray(bufferLen)
+
+ //获取文件相对于压缩文件夹根目录的子路径
+ var subPath = file.absolutePath
+ val index = subPath.indexOf(srcRootDir)
+ if (index != -1) {
+ subPath = subPath.substring(srcRootDir.length + File.separator.length)
+ }
+ val entry = ZipEntry(subPath)
+ zos.putNextEntry(entry)
+ val bis = BufferedInputStream(FileInputStream(file))
+ while (true) {
+ count = bis.read(data, 0, bufferLen)
+ if (count < 0) {
+ break
+ }
+ zos.write(data, 0, count)
+ }
+ bis.close()
+ zos.closeEntry()
+ } else {
+ //压缩目录中的文件或子目录
+ val childFileList = file.listFiles()
+ for (aChildFileList in childFileList!!) {
+ aChildFileList.absolutePath.indexOf(file.absolutePath)
+ zip(srcRootDir, aChildFileList, zos)
+ }
+ }//如果是目录,则压缩整个目录
+ }
+
+ /**
+ * 对文件或文件目录进行压缩
+ *
+ * @param srcPath 要压缩的源文件路径。如果压缩一个文件,则为该文件的全路径;如果压缩一个目录,则为该目录的顶层目录路径
+ * @param zipPath 压缩文件保存的路径。注意:zipPath不能是srcPath路径下的子文件夹
+ * @param zipFileName 压缩文件名
+ * @throws Exception
+ */
+ @Throws(Exception::class)
+ fun zip(srcPath: String, zipPath: String, zipFileName: String) {
+ if (StringUtils.isEmpty(srcPath) || StringUtils.isEmpty(zipPath) || StringUtils.isEmpty(zipFileName)) {
+ throw Exception("传入参数为空")
+ }
+ try {
+ val srcFile = File(srcPath)
+ //判断压缩文件保存的路径是否为源文件路径的子文件夹,如果是,则抛出异常(防止无限递归压缩的发生)
+ if (srcFile.isDirectory && zipPath.contains(srcPath)) {
+ throw Exception("zipPath must not be the child directory of srcPath.")
+ }
+
+ //判断压缩文件保存的路径是否存在,如果不存在,则创建目录
+ val zipDir = File(zipPath)
+ if (!zipDir.exists() || !zipDir.isDirectory) {
+ zipDir.mkdirs()
+ }
+
+ //创建压缩文件保存的文件对象
+ val zipFilePath = zipPath + File.separator + zipFileName
+ val zipFile = File(zipFilePath)
+ if (zipFile.exists()) {
+ //检测文件是否允许删除,如果不允许删除,将会抛出SecurityException
+ val securityManager = SecurityManager()
+ securityManager.checkDelete(zipFilePath)
+ //删除已存在的目标文件
+ zipFile.delete()
+ }
+
+ val cos = CheckedOutputStream(FileOutputStream(zipFile), CRC32())
+ val zos = ZipOutputStream(cos)
+
+ //如果只是压缩一个文件,则需要截取该文件的父目录
+ var srcRootDir = srcPath
+ if (srcFile.isFile) {
+ val index = srcPath.lastIndexOf(File.separator)
+ if (index != -1) {
+ srcRootDir = srcPath.substring(0, index)
+ }
+ }
+ //调用递归压缩方法进行目录或文件压缩
+ zip(srcRootDir, srcFile, zos)
+ zos.flush()
+ zos.close()
+ } catch (e: Exception) {
+ throw e
+ }
+
+ }
+
+ /**
+ * 解压缩zip包
+ *
+ * @param zipFilePath zip文件的全路径
+ * @param unzipFilePath 解压后的文件保存的路径
+ * @param includeZipFileName 解压后的文件保存的路径是否包含压缩文件的文件名。true-包含;false-不包含
+ */
+ @Throws(Exception::class)
+ fun unzip(zipFilePath: String, unzipFilePath: String, includeZipFileName: Boolean) {
+ var unzipFilePath = unzipFilePath
+ if (StringUtils.isEmpty(zipFilePath) || StringUtils.isEmpty(unzipFilePath)) {
+ throw Exception("传入参数为空")
+ }
+ val zipFile = File(zipFilePath)
+ //如果解压后的文件保存路径包含压缩文件的文件名,则追加该文件名到解压路径
+ if (includeZipFileName) {
+ var fileName = zipFile.name
+ if (StringUtils.isNotEmpty(fileName)) {
+ fileName = fileName.substring(0, fileName.lastIndexOf("."))
+ }
+ unzipFilePath = unzipFilePath + File.separator + fileName
+ }
+ //创建解压缩文件保存的路径
+ val unzipFileDir = File(unzipFilePath)
+ if (!unzipFileDir.exists() || !unzipFileDir.isDirectory) {
+ unzipFileDir.mkdirs()
+ }
+
+ //开始解压
+ val bufferSize = 1024
+ val buffer = ByteArray(bufferSize)
+ val zip = ZipFile(zipFile)
+ val entries = zip.entries() as Enumeration<ZipEntry>
+ //循环对压缩包里的每一个文件进行解压
+ while (entries.hasMoreElements()) {
+ val entry = entries.nextElement()
+ //构建压缩包中一个文件解压后保存的文件全路径
+ val entryFilePath = unzipFilePath + File.separator + entry.name
+ //构建解压后保存的文件夹路径
+ val index = entryFilePath.lastIndexOf(File.separator)
+ var entryDirPath = ""
+ if (index != -1) {
+ entryDirPath = entryFilePath.substring(0, index)
+ }
+ val entryDir = File(entryDirPath)
+ //如果文件夹路径不存在,则创建文件夹
+ if (!entryDir.exists() || !entryDir.isDirectory) {
+ entryDir.mkdirs()
+ }
+
+ //创建解压文件
+ val entryFile = File(entryFilePath)
+ if (entryFile.exists()) {
+ //检测文件是否允许删除,如果不允许删除,将会抛出SecurityException
+ val securityManager = SecurityManager()
+ securityManager.checkDelete(entryFilePath)
+ //删除已存在的目标文件
+ entryFile.delete()
+ }
+
+ //写入文件
+ val bos = BufferedOutputStream(FileOutputStream(entryFile))
+ val bis = BufferedInputStream(zip.getInputStream(entry))
+ var count: Int
+ while (true) {
+ count = bis.read(buffer, 0, bufferSize)
+ if (count < 0) {
+ break
+ }
+ bos.write(buffer, 0, count)
+ }
+ bos.flush()
+ bos.close()
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/view/BigProgressDialog.kt b/app/src/main/java/com/supwisdom/view/BigProgressDialog.kt
new file mode 100644
index 0000000..9fd9825
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/view/BigProgressDialog.kt
@@ -0,0 +1,47 @@
+package com.supwisdom.view
+
+import android.app.Activity
+import android.app.ProgressDialog
+import android.content.Context
+import android.view.Gravity
+import android.widget.TextView
+import com.supwisdom.R
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+@Suppress("DEPRECATION")
+class BigProgressDialog constructor(context: Context, strMessage: String, cancelable: Boolean) :
+ ProgressDialog(context) {
+ private var tvMsg: TextView
+
+ init {
+ this.show()
+ this.setContentView(R.layout.dialog_progress)
+ this.window!!.attributes.gravity = Gravity.CENTER
+ tvMsg = this.findViewById<TextView>(R.id.loadingmsg)
+ this.setCancelable(cancelable)
+ setCanceledOnTouchOutside(false)
+ tvMsg.text = strMessage
+ }
+
+ fun setMsg(msg: String) {
+ tvMsg.text = msg
+ }
+
+ override fun show() {
+ if (!(context as Activity).isFinishing) {
+ //防止activity处于销毁状态
+ //android.view.WindowManager$BadTokenException: Unable to add window
+ // -- token android.os.BinderProxy@41b43ec0 is not valid; is your activity running
+ super.show()
+ }
+ }
+
+ override fun dismiss() {
+ if (!(context as Activity).isFinishing) {
+ super.dismiss()
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/view/BigSwDialog.kt b/app/src/main/java/com/supwisdom/view/BigSwDialog.kt
new file mode 100644
index 0000000..45fa8f3
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/view/BigSwDialog.kt
@@ -0,0 +1,30 @@
+package com.supwisdom.view
+
+import android.content.Context
+import android.view.KeyEvent
+import com.supwisdom.R
+import com.supwisdom.utils.PublicDef
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class BigSwDialog constructor(context: Context, dialogType: Int) : DialogBase(context) {
+ init {
+ when (dialogType) {
+ PublicDef.DIALOG_TYPE_PASSWORD -> this.setContentView(R.layout.dialog_password)
+ PublicDef.DIALOG_TYPE_NSD_CONFIG -> this.setContentView(R.layout.dialog_init_nsd_config)
+ }
+ this.setCancelable(false)
+ this.setCanceledOnTouchOutside(false)
+ }
+
+ override fun dispatchKeyEvent(event: KeyEvent): Boolean {
+ if (event.action == KeyEvent.ACTION_DOWN) {
+ when (event.keyCode) {
+ KeyEvent.KEYCODE_DEL -> dismiss()
+ }
+ }
+ return super.dispatchKeyEvent(event)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/view/RecyclerViewUtil.kt b/app/src/main/java/com/supwisdom/view/RecyclerViewUtil.kt
index 58d4fa2..7af0cd0 100644
--- a/app/src/main/java/com/supwisdom/view/RecyclerViewUtil.kt
+++ b/app/src/main/java/com/supwisdom/view/RecyclerViewUtil.kt
@@ -9,7 +9,7 @@
* @date 2018/6/21
* @desc TODO
*/
-class RecyclerViewUtil {
+object RecyclerViewUtil {
class ItemDecoration constructor(top: Int, bottom: Int, left: Int, right: Int) : RecyclerView.ItemDecoration() {
private val top = top
private val bottom = bottom
diff --git a/app/src/main/java/com/supwisdom/view/SWToast.kt b/app/src/main/java/com/supwisdom/view/SWToast.kt
new file mode 100644
index 0000000..deb3fa2
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/view/SWToast.kt
@@ -0,0 +1,53 @@
+package com.supwisdom.view
+
+import android.content.Context
+import android.view.Gravity
+import android.view.LayoutInflater
+import android.view.View
+import android.widget.ImageView
+import android.widget.TextView
+import android.widget.Toast
+import com.supwisdom.R
+import com.supwisdom.utils.PublicDef
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+object SWToast {
+ fun show(context: Context, msg: String, showway: Int) {
+ val Inflater = LayoutInflater.from(context)
+ val layout = Inflater.inflate(R.layout.sw_toast, null)
+
+ val cry = layout.findViewById(R.id.pic_cry) as ImageView
+ val smile = layout.findViewById(R.id.pic_smile) as ImageView
+ val doubt = layout.findViewById(R.id.pic_doubt) as ImageView
+ if (showway == PublicDef.TOAST_SHOW_CRY) {
+ cry.visibility = View.VISIBLE
+ smile.visibility = View.GONE
+ doubt.visibility = View.GONE
+ } else if (showway == PublicDef.TOAST_SHOW_SMILE) {
+ cry.visibility = View.GONE
+ smile.visibility = View.VISIBLE
+ doubt.visibility = View.GONE
+ } else if (showway == PublicDef.TOAST_SHOW_DOUBT) {
+ cry.visibility = View.GONE
+ smile.visibility = View.GONE
+ doubt.visibility = View.VISIBLE
+ } else {
+ cry.visibility = View.GONE
+ smile.visibility = View.VISIBLE
+ doubt.visibility = View.GONE
+ }
+
+ // set a message
+ val toastText = layout.findViewById(R.id.toasttext) as TextView
+ toastText.text = msg
+ // Toast...
+ val toast = Toast(context)
+ toast.setGravity(Gravity.CENTER, 0, 0)
+ toast.duration = Toast.LENGTH_SHORT
+ toast.view = layout
+ toast.show()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_init.xml b/app/src/main/res/layout/activity_init.xml
new file mode 100644
index 0000000..24c9d45
--- /dev/null
+++ b/app/src/main/res/layout/activity_init.xml
@@ -0,0 +1,160 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:background="@color/light_blue2"
+ tools:context="com.supwisdom.activities.init.InitActivity">
+ <!--终端编号输入界面-->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_margin="20dp"
+ android:background="@drawable/corner_bg_white"
+ android:gravity="center_horizontal"
+ android:orientation="vertical">
+ <!--标题-->
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="10dp"
+ android:gravity="center"
+ android:text="请填写以下信息"
+ android:textColor="@color/light_blue2"
+ android:textSize="@dimen/enable_title_text_size"/>
+
+ <ScrollView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scrollbars="none">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:padding="10dp">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:weightSum="2">
+
+ <Button
+ android:id="@+id/tv_nsd_query"
+ style="@style/init_param_title_btn_name_style"
+ android:text="动态参数获取"/>
+
+ <Button
+ android:id="@+id/tv_settings"
+ style="@style/init_param_title_btn_name_style"
+ android:text="进入设置界面"/>
+ </LinearLayout>
+
+ <TextView
+ android:id="@+id/tv_nsd_result"
+ style="@style/init_param_name_style"/>
+
+ <TextView
+ style="@style/init_param_name_style"
+ android:text="终端MODE"/>
+
+ <RadioGroup
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <RadioButton
+ android:id="@+id/rb_pay_mode"
+ style="@style/init_param_mode_style"
+ android:checked="true"
+ android:text="消费模式"/>
+
+ <RadioButton
+ android:id="@+id/rb_deposit_mode"
+ style="@style/init_param_mode_style"
+ android:visibility="gone"
+ android:text="充值模式"/>
+
+ <RadioButton
+ android:id="@+id/rb_third_pay_mode"
+ style="@style/init_param_mode_style"
+ android:visibility="gone"
+ android:text="对接消费模式"/>
+
+ <RadioButton
+ android:id="@+id/rb_third_login_mode"
+ style="@style/init_param_mode_style"
+ android:visibility="gone"
+ android:text="对接签到模式"/>
+
+ <RadioButton
+ android:id="@+id/rb_gate_mode"
+ style="@style/init_param_mode_style"
+ android:visibility="gone"
+ android:text="闸机(入)模式(点击切换)"/>
+ </RadioGroup>
+
+ <TextView
+ style="@style/init_param_name_style"
+ android:text="终端物理ID"/>
+
+ <EditText
+ android:id="@+id/tv_devphyid"
+ style="@style/init_param_name_style"
+ android:inputType="numberDecimal"
+ android:maxLength="8"
+ android:text="20000001"/>
+
+ <TextView
+ style="@style/init_param_name_style"
+ android:text="服务器IP"/>
+
+ <EditText
+ android:id="@+id/tv_server_ip"
+ style="@style/init_param_name_style"
+ android:text="172.28.201.101"/>
+
+ <TextView
+ style="@style/init_param_name_style"
+ android:text="服务器URI"/>
+
+ <EditText
+ android:id="@+id/tv_uri_root"
+ style="@style/init_param_name_style"
+ android:maxLines="1"
+ android:text="epayapi"/>
+
+
+ <TextView
+ style="@style/init_param_name_style"
+ android:text="服务器PORT"/>
+
+ <EditText
+ android:id="@+id/tv_server_port"
+ style="@style/init_param_name_style"
+ android:inputType="numberDecimal"
+ android:maxLength="5"
+ android:maxLines="1"
+ android:text="9100"/>
+
+ <TextView
+ android:id="@+id/btn_save"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_marginTop="20dp"
+ android:background="@drawable/select_bg_keyboard"
+ android:paddingLeft="20dp"
+ android:paddingTop="10dp"
+ android:paddingRight="20dp"
+ android:paddingBottom="10dp"
+ android:text="保 存"
+ android:textColor="@color/light_blue2"
+ android:textSize="35sp"/>
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="500dp"/>
+ </LinearLayout>
+ </ScrollView>
+ </LinearLayout>
+</LinearLayout>
diff --git a/app/src/main/res/layout/activity_load.xml b/app/src/main/res/layout/activity_load.xml
new file mode 100644
index 0000000..b6d9c86
--- /dev/null
+++ b/app/src/main/res/layout/activity_load.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:background="@color/light_blue2">
+
+ <LinearLayout
+ android:id="@+id/ll_enable_step"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_margin="20dp"
+ android:background="@drawable/corner_bg_white"
+ android:gravity="center_horizontal"
+ android:orientation="vertical">
+ <!--标题-->
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="10dp"
+ android:gravity="center"
+ android:text="正在加载设备参数"
+ android:textColor="@color/light_blue2"
+ android:textSize="@dimen/enable_title_text_size"/>
+ <!--中间内容-->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="400dp"
+ android:layout_gravity="center_horizontal"
+ android:layout_marginTop="20dp"
+ android:orientation="vertical"
+ android:padding="10dp">
+
+ <TextView
+ android:id="@+id/tv_load_pro"
+ style="@style/load_info_text_style"
+ android:text=" "/>
+ </LinearLayout>
+ <!--底下俩按钮-->
+ <TextView
+ android:id="@+id/btn_back"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="10dp"
+ android:background="@drawable/select_bg_keyboard"
+ android:paddingLeft="20dp"
+ android:paddingTop="10dp"
+ android:paddingRight="20dp"
+ android:paddingBottom="10dp"
+ android:text="返 回"
+ android:textColor="@color/light_blue2"
+ android:textSize="30sp"/>
+ </LinearLayout>
+</LinearLayout>
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
deleted file mode 100644
index 980638c..0000000
--- a/app/src/main/res/layout/activity_main.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<android.support.constraint.ConstraintLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context=".MainActivity">
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Hello World!"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent"
- app:layout_constraintTop_toTopOf="parent"/>
-
-</android.support.constraint.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_unregister.xml b/app/src/main/res/layout/activity_unregister.xml
new file mode 100644
index 0000000..5bcd6cb
--- /dev/null
+++ b/app/src/main/res/layout/activity_unregister.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:background="@color/light_blue2">
+
+ <LinearLayout
+ android:id="@+id/ll_enable_step"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_margin="20dp"
+ android:background="@drawable/corner_bg_white"
+ android:gravity="center_horizontal"
+ android:orientation="vertical">
+ <!--标题-->
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="10dp"
+ android:gravity="center"
+ android:text="设备未注册"
+ android:textColor="@color/light_blue2"
+ android:textSize="@dimen/enable_title_text_size" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="10dp"
+ android:padding="10dp"
+ android:text="说明: 设备参数配置已保存,后续只需签到认证成功即可使用"
+ android:textColor="@color/light_blue2"
+ android:textSize="30sp" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="10dp"
+ android:padding="10dp"
+ android:text="设备注册失败信息:"
+ android:textColor="@color/light_blue2"
+ android:textSize="30sp" />
+
+ <TextView
+ android:id="@+id/tv_errmsg"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="10dp"
+ android:textColor="@color/cl_red"
+ android:textSize="30sp" />
+
+ <TextView
+ android:id="@+id/tv_back"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="10dp"
+ android:background="@drawable/select_bg_keyboard"
+ android:paddingBottom="10dp"
+ android:paddingLeft="20dp"
+ android:paddingRight="20dp"
+ android:paddingTop="10dp"
+ android:text="返 回"
+ android:textColor="@color/light_blue2"
+ android:textSize="30sp" />
+ </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_upgrade.xml b/app/src/main/res/layout/activity_upgrade.xml
new file mode 100644
index 0000000..f4e1fa0
--- /dev/null
+++ b/app/src/main/res/layout/activity_upgrade.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@color/light_blue2"
+ android:orientation="vertical">
+
+ <ScrollView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_margin="20dp"
+ android:background="@drawable/corner_bg_white"
+ android:fillViewport="true"
+ android:scrollbars="none">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="10dp"
+ android:gravity="center"
+ android:text="软件在线升级"
+ android:textColor="@color/light_blue2"
+ android:textSize="30sp"/>
+ <TableLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <TableRow>
+
+ <TextView
+ style="@style/upgrade_text_value_style"
+ android:text="结\u3000\u3000果:"/>
+
+ <TextView
+ android:id="@+id/tv_result"
+ style="@style/upgrade_text_value_style"/>
+ </TableRow>
+
+ <TableRow android:layout_marginTop="15dp">
+
+ <TextView
+ style="@style/upgrade_text_value_style"
+ android:text="升级地址:"/>
+
+ <TextView
+ android:id="@+id/tv_server_url"
+ style="@style/upgrade_text_value_style"/>
+ </TableRow>
+
+ <TableRow android:layout_marginTop="15dp">
+
+ <TextView
+ style="@style/upgrade_text_value_style"
+ android:text="当前版本:"/>
+
+ <TextView
+ android:id="@+id/tv_old_version"
+ style="@style/upgrade_text_value_style"/>
+ </TableRow>
+
+ <TableRow android:layout_marginTop="15dp">
+
+ <TextView
+ style="@style/upgrade_text_value_style"
+ android:text="升级版本:"/>
+
+ <TextView
+ android:id="@+id/tv_pos_version"
+ style="@style/upgrade_text_value_style"/>
+ </TableRow>
+
+ <TableRow android:layout_marginTop="15dp">
+
+ <TextView
+ style="@style/upgrade_text_value_style"
+ android:text="升级进度:"/>
+
+ <TextView
+ android:id="@+id/tv_upgrade_msg"
+ style="@style/upgrade_text_value_style"/>
+ </TableRow>
+ </TableLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="30dp"
+ android:gravity="center_vertical"
+ android:orientation="horizontal">
+
+ <Button
+ android:id="@+id/tv_upgrade"
+ style="@style/upgrade_text_value_style"
+ android:layout_marginStart="50dp"
+ android:layout_marginEnd="50dp"
+ android:text="升级"/>
+
+ </LinearLayout>
+ </LinearLayout>
+ </ScrollView>
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_init_nsd_config.xml b/app/src/main/res/layout/dialog_init_nsd_config.xml
new file mode 100644
index 0000000..301e484
--- /dev/null
+++ b/app/src/main/res/layout/dialog_init_nsd_config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="400dp"
+ android:layout_height="500dp"
+ android:layout_gravity="center"
+ android:background="@drawable/corner_bg_white"
+ android:orientation="vertical">
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="10dp"
+ android:gravity="center"
+ android:text="参数配置列表"
+ android:textColor="@color/light_blue2"
+ android:textSize="35sp"
+ android:textStyle="bold" />
+
+ <android.support.v7.widget.RecyclerView
+ android:id="@+id/rv_config_list"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginTop="10dp"
+ android:orientation="vertical" />
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_password.xml b/app/src/main/res/layout/dialog_password.xml
new file mode 100644
index 0000000..7b62bbd
--- /dev/null
+++ b/app/src/main/res/layout/dialog_password.xml
@@ -0,0 +1,281 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+ android:id="@+id/ll_float_password"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@drawable/order_btn_purchase"
+ android:orientation="vertical">
+ <!--上半部分-->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:orientation="vertical">
+ <!--提示文字-->
+ <TextView
+ android:id="@+id/tv_float_password_title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/float_password_left_word_margin_top"
+ android:text="请输入卡密码"
+ android:textColor="@color/password_hint"
+ android:textSize="@dimen/float_password_hint_size"
+ android:textStyle="bold"/>
+ <!--密码输入框-->
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/float_password_left_obj_gap"
+ android:orientation="horizontal">
+ <!--密码1-->
+ <RelativeLayout
+ android:layout_width="@dimen/float_password_pwd_size"
+ android:layout_height="@dimen/float_password_pwd_size">
+
+ <ImageView
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:background="@drawable/password_pwd_frame"/>
+
+ <ImageView
+ android:id="@+id/float_password_img1"
+ android:layout_width="20dp"
+ android:layout_height="20dp"
+ android:layout_margin="26dp"
+ android:layout_marginTop="26dp"
+ android:scaleType="fitXY"
+ android:src="@drawable/purchase_cardread"/>
+ </RelativeLayout>
+ <!--密码2-->
+ <RelativeLayout
+ android:layout_width="@dimen/float_password_pwd_size"
+ android:layout_height="@dimen/float_password_pwd_size"
+ android:layout_marginLeft="@dimen/float_password_left_obj_gap">
+
+ <ImageView
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:background="@drawable/password_pwd_frame"/>
+
+ <ImageView
+ android:id="@+id/float_password_img2"
+ android:layout_width="20dp"
+ android:layout_height="20dp"
+ android:layout_margin="26dp"
+ android:layout_marginTop="26dp"
+ android:scaleType="fitXY"
+ android:src="@drawable/purchase_cardread"/>
+ </RelativeLayout>
+ <!--密码3-->
+ <RelativeLayout
+ android:layout_width="@dimen/float_password_pwd_size"
+ android:layout_height="@dimen/float_password_pwd_size"
+ android:layout_marginLeft="@dimen/float_password_left_obj_gap">
+
+ <ImageView
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:background="@drawable/password_pwd_frame"/>
+
+ <ImageView
+ android:id="@+id/float_password_img3"
+ android:layout_width="20dp"
+ android:layout_height="20dp"
+ android:layout_margin="26dp"
+ android:layout_marginTop="26dp"
+ android:scaleType="fitXY"
+ android:src="@drawable/purchase_cardread"/>
+ </RelativeLayout>
+ <!--密码4-->
+ <RelativeLayout
+ android:layout_width="@dimen/float_password_pwd_size"
+ android:layout_height="@dimen/float_password_pwd_size"
+ android:layout_marginLeft="@dimen/float_password_left_obj_gap">
+
+ <ImageView
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:background="@drawable/password_pwd_frame"/>
+
+ <ImageView
+ android:id="@+id/float_password_img4"
+ android:layout_width="20dp"
+ android:layout_height="20dp"
+ android:layout_margin="26dp"
+ android:layout_marginTop="26dp"
+ android:scaleType="fitXY"
+ android:src="@drawable/purchase_cardread"/>
+ </RelativeLayout>
+ <!--密码5-->
+ <RelativeLayout
+ android:layout_width="@dimen/float_password_pwd_size"
+ android:layout_height="@dimen/float_password_pwd_size"
+ android:layout_marginLeft="@dimen/float_password_left_obj_gap">
+
+ <ImageView
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:background="@drawable/password_pwd_frame"/>
+
+ <ImageView
+ android:id="@+id/float_password_img5"
+ android:layout_width="20dp"
+ android:layout_height="20dp"
+ android:layout_margin="26dp"
+ android:layout_marginTop="26dp"
+ android:scaleType="fitXY"
+ android:src="@drawable/purchase_cardread"/>
+ </RelativeLayout>
+ <!--密码6-->
+ <RelativeLayout
+ android:layout_width="@dimen/float_password_pwd_size"
+ android:layout_height="@dimen/float_password_pwd_size"
+ android:layout_marginLeft="@dimen/float_password_left_obj_gap">
+
+ <ImageView
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:background="@drawable/password_pwd_frame"/>
+
+ <ImageView
+ android:id="@+id/float_password_img6"
+ android:layout_width="20dp"
+ android:layout_height="20dp"
+ android:layout_margin="26dp"
+ android:layout_marginTop="26dp"
+ android:scaleType="fitXY"
+ android:src="@drawable/purchase_cardread"/>
+ </RelativeLayout>
+ </LinearLayout>
+ </LinearLayout>
+
+ <!--下半部分-->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="10dp"
+ android:layout_marginTop="@dimen/float_password_right_margin_top"
+ android:gravity="center_horizontal"
+ android:orientation="vertical">
+ <!--第一行按键-->
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/float_password_btn_size"
+ android:orientation="horizontal">
+
+ <ImageView
+ android:id="@+id/float_password_btn1"
+ android:layout_width="@dimen/float_password_btn_size"
+ android:layout_height="@dimen/float_password_btn_size"
+ android:src="@drawable/pass_one_normal"/>
+
+ <ImageView
+ android:id="@+id/float_password_btn2"
+ android:layout_width="@dimen/float_password_btn_size"
+ android:layout_height="@dimen/float_password_btn_size"
+ android:layout_marginLeft="@dimen/float_password_right_btn_margin"
+ android:src="@drawable/pass_two_normal"/>
+
+ <ImageView
+ android:id="@+id/float_password_btn3"
+ android:layout_width="@dimen/float_password_btn_size"
+ android:layout_height="@dimen/float_password_btn_size"
+ android:layout_marginLeft="@dimen/float_password_right_btn_margin"
+ android:src="@drawable/pass_three_normal"/>
+ </LinearLayout>
+ <!--第二行按钮-->
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/float_password_btn_size"
+ android:layout_marginTop="@dimen/float_password_right_btn_margin"
+ android:orientation="horizontal">
+
+ <ImageView
+ android:id="@+id/float_password_btn4"
+ android:layout_width="@dimen/float_password_btn_size"
+ android:layout_height="@dimen/float_password_btn_size"
+ android:src="@drawable/pass_four_normal"/>
+
+ <ImageView
+ android:id="@+id/float_password_btn5"
+ android:layout_width="@dimen/float_password_btn_size"
+ android:layout_height="@dimen/float_password_btn_size"
+ android:layout_marginLeft="@dimen/float_password_right_btn_margin"
+ android:src="@drawable/pass_five_normal"/>
+
+ <ImageView
+ android:id="@+id/float_password_btn6"
+ android:layout_width="@dimen/float_password_btn_size"
+ android:layout_height="@dimen/float_password_btn_size"
+ android:layout_marginLeft="@dimen/float_password_right_btn_margin"
+ android:src="@drawable/pass_six_normal"/>
+ </LinearLayout>
+ <!--第三行按钮-->
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/float_password_btn_size"
+ android:layout_marginTop="@dimen/float_password_right_btn_margin"
+ android:orientation="horizontal">
+
+ <ImageView
+ android:id="@+id/float_password_btn7"
+ android:layout_width="@dimen/float_password_btn_size"
+ android:layout_height="@dimen/float_password_btn_size"
+ android:src="@drawable/pass_seven_normal"/>
+
+ <ImageView
+ android:id="@+id/float_password_btn8"
+ android:layout_width="@dimen/float_password_btn_size"
+ android:layout_height="@dimen/float_password_btn_size"
+ android:layout_marginLeft="@dimen/float_password_right_btn_margin"
+ android:src="@drawable/pass_eight_normal"/>
+
+ <ImageView
+ android:id="@+id/float_password_btn9"
+ android:layout_width="@dimen/float_password_btn_size"
+ android:layout_height="@dimen/float_password_btn_size"
+ android:layout_marginLeft="@dimen/float_password_right_btn_margin"
+ android:src="@drawable/pass_nine_normal"/>
+ </LinearLayout>
+ <!--第四行按钮-->
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/float_password_btn_size"
+ android:layout_marginBottom="10dp"
+ android:layout_marginTop="@dimen/float_password_right_btn_margin"
+ android:orientation="horizontal">
+
+ <TextView
+ android:id="@+id/float_password_cancel"
+ android:layout_width="@dimen/float_password_btn_size"
+ android:layout_height="@dimen/float_password_btn_size"
+ android:background="@drawable/btn_red_normal"
+ android:gravity="center"
+ android:text="取消"
+ android:textColor="@color/white"
+ android:textSize="30sp"/>
+
+ <ImageView
+ android:id="@+id/float_password_btn0"
+ android:layout_width="@dimen/float_password_btn_size"
+ android:layout_height="@dimen/float_password_btn_size"
+ android:layout_marginLeft="@dimen/float_password_right_btn_margin"
+ android:src="@drawable/pass_zero_normal"/>
+
+ <ImageView
+ android:id="@+id/float_password_btn_delete"
+ android:layout_width="@dimen/float_password_btn_size"
+ android:layout_height="@dimen/float_password_btn_size"
+ android:layout_marginLeft="@dimen/float_password_right_btn_margin"
+ android:src="@drawable/pass_delete_normal"/>
+ </LinearLayout>
+ </LinearLayout>
+ </LinearLayout>
+</RelativeLayout>
+
+
diff --git a/app/src/main/res/layout/dialog_progress.xml b/app/src/main/res/layout/dialog_progress.xml
new file mode 100644
index 0000000..f2c8fb8
--- /dev/null
+++ b/app/src/main/res/layout/dialog_progress.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@drawable/pay_ret_dialog_bg"
+ android:orientation="vertical"
+ android:gravity="center"
+ android:paddingTop="30dp"
+ android:paddingBottom="30dp"
+ android:paddingLeft="30dp"
+ android:paddingRight="30dp">
+
+ <ProgressBar
+ android:id="@+id/loadingImageView"
+ style="@style/myProgressBarStyleLarge"
+ android:layout_width="200dp"
+ android:layout_height="200dp"
+ android:layout_gravity="center"
+ android:padding="20dp" />
+
+ <TextView
+ android:id="@+id/loadingmsg"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:textColor="@android:color/white"
+ android:text="正在处理,请不要拿走卡片..."
+ android:textSize="30dp"
+ android:layout_marginBottom="30dp"
+ android:layout_marginTop="10dp" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_init_nsd_config_list.xml b/app/src/main/res/layout/item_init_nsd_config_list.xml
new file mode 100644
index 0000000..735e6f9
--- /dev/null
+++ b/app/src/main/res/layout/item_init_nsd_config_list.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/ll_config"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@drawable/corner_bg_gray"
+ android:orientation="horizontal">
+
+ <TextView
+ android:id="@+id/tv_config_id"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:maxLines="1"
+ android:padding="10dp"
+ android:textColor="@color/light_blue2"
+ android:textSize="30sp"
+ android:textStyle="bold" />
+
+ <TextView
+ android:id="@+id/tv_config_name"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="10dp"
+ android:maxLines="1"
+ android:padding="10dp"
+ android:textColor="@color/light_blue2"
+ android:textSize="30sp"
+ android:textStyle="bold" />
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/sw_toast.xml b/app/src/main/res/layout/sw_toast.xml
new file mode 100644
index 0000000..bdc5081
--- /dev/null
+++ b/app/src/main/res/layout/sw_toast.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/corner_bg"
+ android:gravity="center"
+ android:orientation="horizontal"
+ android:padding="5dp">
+
+ <ImageView
+ android:id="@+id/pic_cry"
+ android:layout_width="60dp"
+ android:layout_height="60dp"
+ android:layout_gravity="center"
+ android:scaleType="fitXY"
+ android:src="@drawable/toast_cry"
+ android:visibility="gone"/>
+
+ <ImageView
+ android:id="@+id/pic_smile"
+ android:layout_width="60dp"
+ android:layout_height="60dp"
+ android:layout_gravity="center"
+ android:scaleType="fitXY"
+ android:src="@drawable/toast_smile"/>
+
+ <ImageView
+ android:id="@+id/pic_doubt"
+ android:layout_width="60dp"
+ android:layout_height="60dp"
+ android:layout_gravity="center"
+ android:scaleType="fitXY"
+ android:src="@drawable/toast_doubt"
+ android:visibility="gone"/>
+
+ <TextView
+ android:id="@+id/toasttext"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="链路检测失败"
+ android:textColor="@color/black"
+ android:textSize="45dp"
+ android:textStyle="bold"/>
+</LinearLayout>
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index dae37ff..07cae7a 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -1,5 +1,4 @@
<resources>
-
<color name="black_overlay">#66000000</color>
<color name="btn_light_blue">#5bc0de</color>
<color name="light_gray">#ffa2a2a2</color>