Commit a2b15449 by patpat

action改版(未完成)

parent 949ca291
package com.bgycc.smartcanteen.action;
import com.bgycc.smartcanteen.event.PayStateEvent;
import com.bgycc.smartcanteen.server.websocket.MainWebSocket;
import org.greenrobot.eventbus.EventBus;
import org.json.JSONObject;
import java.util.Timer;
import java.util.TimerTask;
public abstract class Action {
public enum State {
RESPONSE_TIMEOUT,
RESPONSE_FAIL,
RESQUEST_TIMEOUT,
RESQUEST_FAIL,
FAIL,
UNINIT,
INITED,
STARTED,
RESQUEST,
RESQUEST_SUCCESS,
RESPONSE_SUCCESS,
SUCCESS
}
private String mAction;
private State mState;
protected Action(String action) {
mState = State.UNINIT;
mAction = action;
if (mAction != null && !mAction.isEmpty()) {
mState = State.INITED;
}
}
public String getAction() {
return mAction;
}
public State getState() {
return mState;
}
boolean isAction(String action) {
if (mAction == null || mAction.isEmpty()) return false;
return mAction.equals(action);
}
public void response(JSONObject response) {
}
protected void timeout(final Runnable runnable, long ms) {
new Timer().schedule(new TimerTask() {
@Override
public void run() {
if (runnable != null) runnable.run();
}
}, ms);
}
protected void success(String message, ActionResult result) {
if (result != null) result.onSuccess(message);
}
protected void fail(String message, ActionResult result) {
if (result != null) result.onFail(message);
}
}
package com.bgycc.smartcanteen.action;
public interface ActionResult {
void onSuccess();
void onSuccess(String message);
void onFail(String message);
}
package com.bgycc.smartcanteen.action;
import org.json.JSONObject;
public abstract class BaseAction {
private String mAction;
public BaseAction(String action) {
mAction = action;
}
boolean isAction(String action) {
if (mAction == null || mAction.isEmpty()) return false;
return mAction.equals(action);
}
void exec(String data, ActionResult result) {
try {
JSONObject json = new JSONObject(data);
exec(json, result);
} catch (Exception e) {
onFail("数据格式错误", result);
}
}
void exec(JSONObject data, ActionResult result) {
}
void onSuccess(ActionResult result) {
if (result != null) result.onSuccess();
}
void onFail(String message, ActionResult result) {
if (result != null) result.onFail(message);
}
}
package com.bgycc.smartcanteen.action;
import org.json.JSONObject;
public class ConfigAction extends BaseAction {
public ConfigAction(String action) {
super(action);
}
@Override
void exec(JSONObject data, ActionResult result) {
}
}
......@@ -2,7 +2,7 @@ package com.bgycc.smartcanteen.action;
import org.json.JSONObject;
public class PayAction extends BaseAction {
public class PayAction extends Action {
public PayAction(String action) {
super(action);
......@@ -12,19 +12,19 @@ public class PayAction extends BaseAction {
public void exec(JSONObject data, ActionResult result) {
if (isAction(ActionEnum.PAY_RESULT.name())) {
if (data == null) {
onFail("数据格式错误", result);
fail("数据格式错误", result);
return;
}
String payCode = data.optString("payCode", "");
if (payCode.isEmpty()) {
onFail("payCode不能为空", result);
fail("payCode不能为空", result);
return;
}
onSuccess(result);
success("", result);
} else {
onFail("action无效", result);
fail("action无效", result);
}
}
}
package com.bgycc.smartcanteen.action;
import com.bgycc.smartcanteen.event.PayStateEvent;
import com.bgycc.smartcanteen.server.websocket.MainWebSocket;
import org.greenrobot.eventbus.EventBus;
import org.json.JSONObject;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class PayOnlineAction extends Action {
public PayOnlineAction(String action) {
super(action);
}
public void exec(String payCode, String payCodeType, ActionResult result) {
if (getState() != State.INITED) return;
final MainWebSocket.Response response = new MainWebSocket.Response() {
@Override
protected void onSuccess(JSONObject data, String message) {
EventBus.getDefault().post(new PayStateEvent(PayStateEvent.StateEnum.SUCCESS, message));
}
@Override
protected void onFail(String code, String message) {
EventBus.getDefault().post(new PayStateEvent(PayStateEvent.StateEnum.FAIL, message));
resetStep();
timeout(new Runnable() {
@Override
public void run() {
restart();
}
}, 3000);
}
};
timeout(new Runnable() {
@Override
public void run() {
response.fail(null, "交易失败");
response.cancel();
}
}, 10000);
MainWebSocket.payOnline(event.string, event.payCodeType, response);
try {
JSONObject json = new JSONObject();
json.put("equipmentNo", sDeviceSN);
json.put("payCode", payCode);
json.put("terminalType", payCodeType);
json.put("time", new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault()).format(new Date()));
MainWebSocket.action(getAction(), json, response);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void response(JSONObject response) {
}
}
......@@ -4,11 +4,11 @@ import android.os.Bundle
import android.widget.TextView
import com.bgycc.smartcanteen.QRCodeEvent
import com.bgycc.smartcanteen.R
import com.bgycc.smartcanteen.helper.QRCodeHelper
import com.bgycc.smartcanteen.server.websocket.ConnectStateEvent
import com.bgycc.smartcanteen.event.PayStateEvent
import com.bgycc.smartcanteen.server.websocket.event.ConnectStateEvent
import com.bgycc.smartcanteen.server.websocket.MainWebSocket
import com.bgycc.smartcanteen.server.websocket.RecvMessageEvent
import com.bgycc.smartcanteen.server.websocket.SendMessageEvent
import com.bgycc.smartcanteen.server.websocket.event.RecvMessageEvent
import com.bgycc.smartcanteen.server.websocket.event.SendMessageEvent
import com.bgycc.smartcanteen.task.QRCodeTask
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
......@@ -22,10 +22,11 @@ class MainActivity : BaseActivity() {
var TAG: String = MainActivity::class.java.simpleName
}
lateinit var mQRCodeText: TextView
lateinit var mServerText: TextView
lateinit var mSendText: TextView
lateinit var mRecvText: TextView
lateinit var mMessageTextView: TextView
lateinit var mQRCodeTextView: TextView
lateinit var mServerTextView: TextView
lateinit var mSendTextView: TextView
lateinit var mRecvTextView: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
......@@ -48,10 +49,11 @@ class MainActivity : BaseActivity() {
}
fun initView() {
mQRCodeText = findViewById(R.id.qrcode)
mServerText = findViewById(R.id.server)
mSendText = findViewById(R.id.send_msg)
mRecvText = findViewById(R.id.recv_msg)
mMessageTextView = findViewById(R.id.message)
mQRCodeTextView = findViewById(R.id.qrcode)
mServerTextView = findViewById(R.id.server)
mSendTextView = findViewById(R.id.send_msg)
mRecvTextView = findViewById(R.id.recv_msg)
}
fun printQRCode(event: QRCodeEvent) {
......@@ -59,7 +61,7 @@ class MainActivity : BaseActivity() {
if (event.payCodeType != null) {
msg += String.format(" (%s)", event.payCodeType)
}
mQRCodeText.text = msg
mQRCodeTextView.text = msg
}
@Subscribe(threadMode = ThreadMode.MAIN)
......@@ -68,23 +70,40 @@ class MainActivity : BaseActivity() {
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(event: PayStateEvent) {
if (event.state == PayStateEvent.StateEnum.IDLE) {
mMessageTextView.setTextColor(0xFF333333.toInt())
mMessageTextView.text = "请出示付款码"
} else if (event.state == PayStateEvent.StateEnum.WAIT) {
mMessageTextView.setTextColor(0xFF333333.toInt())
mMessageTextView.text = "交易处理中"
} else if (event.state == PayStateEvent.StateEnum.SUCCESS) {
mMessageTextView.setTextColor(0xFF009900.toInt())
mMessageTextView.text = event.message
} else if (event.state == PayStateEvent.StateEnum.FAIL) {
mMessageTextView.setTextColor(0xFFFF0000.toInt())
mMessageTextView.text = event.message
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(event: ConnectStateEvent) {
if (event.state == ConnectStateEvent.OFFLINE) mServerText.text = "Server: 未连接"
else if (event.state == ConnectStateEvent.CONNECTING) mServerText.text = "Server: 正在连接..."
else if (event.state == ConnectStateEvent.CONNECTED) mServerText.text = "Server: 已连接"
else if (event.state == ConnectStateEvent.RECONNECTING) mServerText.text = "Server: 正在重连..."
if (event.state == ConnectStateEvent.OFFLINE) mServerTextView.text = "Server: 未连接"
else if (event.state == ConnectStateEvent.CONNECTING) mServerTextView.text = "Server: 正在连接..."
else if (event.state == ConnectStateEvent.CONNECTED) mServerTextView.text = "Server: 已连接"
else if (event.state == ConnectStateEvent.RECONNECTING) mServerTextView.text = "Server: 正在重连..."
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(event: SendMessageEvent) {
val time = SimpleDateFormat("HH:mm:ss.SSS", Locale.getDefault()).format(Date())
mSendText.text = String.format("Send: %s - %s", time, event.message);
mSendTextView.text = String.format("Send: %s - %s", time, event.message)
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(event: RecvMessageEvent) {
val time = SimpleDateFormat("HH:mm:ss.SSS", Locale.getDefault()).format(Date())
mRecvText.text = String.format("Receive: %s - %s", time, event.message);
mRecvTextView.text = String.format("Receive: %s - %s", time, event.message)
}
}
package com.bgycc.smartcanteen.event;
public class PayStateEvent {
public enum StateEnum {
IDLE,
WAIT,
SUCCESS,
FAIL
}
public StateEnum state;
public String message;
public PayStateEvent(StateEnum state) {
this.state = state;
}
public PayStateEvent(StateEnum state, String message) {
this(state);
this.message = message;
}
}
......@@ -4,7 +4,11 @@ import android.util.Log;
import android.util.SparseArray;
import com.bgycc.smartcanteen.action.ActionEnum;
import com.bgycc.smartcanteen.action.ActionResult;
import com.bgycc.smartcanteen.action.Action;
import com.bgycc.smartcanteen.action.PayAction;
import com.bgycc.smartcanteen.server.websocket.event.ConnectStateEvent;
import com.bgycc.smartcanteen.server.websocket.event.RecvMessageEvent;
import com.bgycc.smartcanteen.server.websocket.event.SendMessageEvent;
import com.example.zhoukai.modemtooltest.ModemToolTest;
import com.example.zhoukai.modemtooltest.NvConstants;
import org.greenrobot.eventbus.EventBus;
......@@ -50,7 +54,7 @@ public class MainWebSocket extends WebSocketClient {
if (sDeviceSN == null || sDeviceSN.isEmpty()) return;
EventBus.getDefault().post(new ConnectStateEvent(ConnectStateEvent.CONNECTING));
sInstance = new MainWebSocket(new URI("ws://10.187.5.223:9001/websocket/" + sDeviceSN));
sInstance = new MainWebSocket(new URI("ws://10.181.0.56:5000/websocket/" + sDeviceSN));
sInstance.connect();
} catch (URISyntaxException e) {
e.printStackTrace();
......@@ -90,6 +94,39 @@ public class MainWebSocket extends WebSocketClient {
}
}
public static void action(String action, JSONObject params, Response callback) {
if (!isInited()) return;
sInstance.send(action, params, callback);
}
public static boolean subscribe(Action action) {
if (action == null) return false;
String a = action.getAction();
if (a == null || a.isEmpty()) return false;
ArrayList<Action> list = sInstance.mSubscribeList.get(a);
if (list == null) {
list = new ArrayList<Action>();
sInstance.mSubscribeList.put(a, list);
}
list.add(action);
return true;
}
public static boolean unsubscribe(Action action) {
if (action == null) return false;
String a = action.getAction();
if (a == null || a.isEmpty()) return false;
ArrayList<Action> list = sInstance.mSubscribeList.get(a);
if (list == null) return false;
return list.remove(action);
}
private static void response(int sessionId, String code, String message) {
try {
JSONObject json = new JSONObject();
......@@ -109,6 +146,7 @@ public class MainWebSocket extends WebSocketClient {
private int mSessionId = 0;
private final SparseArray<Resquest> mResquestList = new SparseArray<>();
private final HashMap<String, ArrayList<Action>> mSubscribeList = new HashMap<>();
private MainWebSocket(URI serverUri) {
super(serverUri, new Draft_6455(), null, 10000);
......@@ -159,8 +197,8 @@ public class MainWebSocket extends WebSocketClient {
if (action.startsWith(ActionEnum.PAY_.name())) {
new PayAction(action).exec(json.optJSONObject(FieldEnum.data.name()), new ActionResult() {
@Override
public void onSuccess() {
response(sessionId, CODE_OK, "");
public void onSuccess(String message) {
response(sessionId, CODE_OK, message);
}
@Override
public void onFail(String message) {
......@@ -199,16 +237,34 @@ public class MainWebSocket extends WebSocketClient {
void parseResponse(String code, JSONObject res) {
if (res == null) return;
String message = res.optString(FieldEnum.message.name());
if (CODE_OK.equals(code)) {
response.onSuccess(res.optJSONObject(FieldEnum.data.name()));
response.onSuccess(res.optJSONObject(FieldEnum.data.name()), message);
} else {
response.onFail(code, res.optString(FieldEnum.message.name()));
response.onFail(code, message);
}
}
}
public interface Response {
void onSuccess(JSONObject data);
void onFail(String code, String message);
public static abstract class Response {
boolean cancel = false;
public void cancel() {
this.cancel = true;
}
public void success(JSONObject data, String message) {
if (this.cancel) return;
onSuccess(data, message);
}
public void fail(String code, String message){
if (this.cancel) return;
onFail(code, message);
}
protected void onSuccess(JSONObject data, String message) {}
protected void onFail(String code, String message) {}
}
}
package com.bgycc.smartcanteen.server.websocket;
package com.bgycc.smartcanteen.server.websocket.event;
public class ConnectStateEvent {
......
package com.bgycc.smartcanteen.server.websocket;
package com.bgycc.smartcanteen.server.websocket.event;
public class RecvMessageEvent {
......
package com.bgycc.smartcanteen.server.websocket;
package com.bgycc.smartcanteen.server.websocket.event;
public class SendMessageEvent {
......
......@@ -12,6 +12,14 @@ public class AsyncTask implements Runnable {
protected long mTimeout = 0;
protected Runnable mTimeoutRunnable = null;
protected AsyncTask() {
init();
}
protected void init() {
}
@Override
public void run() {
long time = System.currentTimeMillis();
......@@ -46,6 +54,11 @@ public class AsyncTask implements Runnable {
clearTimeout();
}
protected void restart() {
resetStep();
mStep = 0;
}
protected void nextStep() {
resetStep();
mStep++;
......
package com.bgycc.smartcanteen.task;
import android.util.Log;
import com.bgycc.smartcanteen.QRCodeEvent;
import com.bgycc.smartcanteen.action.Action;
import com.bgycc.smartcanteen.action.ActionEnum;
import com.bgycc.smartcanteen.action.ActionResult;
import com.bgycc.smartcanteen.event.PayStateEvent;
import com.bgycc.smartcanteen.server.websocket.MainWebSocket;
import com.szxb.jni.libszxb;
import org.greenrobot.eventbus.EventBus;
......@@ -26,6 +31,7 @@ public class QRCodeTask {
}
private Timer mScanTimer;
private AsyncTask mAsyncTask;
private QRCodeTask() {}
......@@ -50,43 +56,106 @@ public class QRCodeTask {
}
private class LoopTimerTask extends TimerTask {
QRCodeEvent lastEvent;
AsyncTask asyncTask = new AsyncTask() {
int lastLen = -1;
byte[] lastBuf;
AsyncTask asyncTask = mAsyncTask = new AsyncTask() {
@Override
protected void init() {
MainWebSocket.subscribe(new Action(ActionEnum.PAY_RESULT.name()) {
@Override
protected void exec(JSONObject data, ActionResult result) {
if (data == null) {
fail("数据格式错误", result);
return;
}
String payCode = data.optString("payCode", "");
if (payCode.isEmpty()) {
fail("payCode不能为空", result);
return;
}
success("", result);
}
});
}
@Override
protected void run(int step, int progress) {
Log.i("LoopTimerTask", String.format("step: %d progress: %d", step, progress));
switch (step) {
case 0: // 获取二维码
case 0:
EventBus.getDefault().post(new PayStateEvent(PayStateEvent.StateEnum.IDLE));
nextStep();
break;
case 1:
if (progress != 0) break;
byte[] buf = new byte[1024];
int len = libszxb.getBarcode(buf);
if (len <= 0) break;
delay(500);
boolean changed = checkBarCodeChanged(buf, len);
if (!changed || len <= 0) break;
delay(1000);
String str = new String(buf, 0, len);
QRCodeEvent event = new QRCodeEvent(str.getBytes(), str, checkPayCodeType(str));
QRCodeEvent le = lastEvent;
lastEvent = event;
if (event.equal(le)) break;
EventBus.getDefault().post(event);
if (event.payCodeType == null) {
parseCommand(event);
} else {
MainWebSocket.payOnline(event.string, event.payCodeType, new MainWebSocket.Response() {
final MainWebSocket.Response response = new MainWebSocket.Response() {
@Override
public void onSuccess(JSONObject data) {
protected void onSuccess(JSONObject data, String message) {
EventBus.getDefault().post(new PayStateEvent(PayStateEvent.StateEnum.SUCCESS, message));
}
@Override
public void onFail(String code, String message) {
protected void onFail(String code, String message) {
EventBus.getDefault().post(new PayStateEvent(PayStateEvent.StateEnum.FAIL, message));
resetStep();
timeout(new Runnable() {
@Override
public void run() {
restart();
}
});
nextStep();
}, 3000);
}
};
timeout(new Runnable() {
@Override
public void run() {
response.fail(null, "交易失败");
response.cancel();
}
}, 10000);
MainWebSocket.payOnline(event.string, event.payCodeType, response);
EventBus.getDefault().post(new PayStateEvent(PayStateEvent.StateEnum.WAIT));
nextProgress();
}
break;
}
}
boolean checkBarCodeChanged(byte[] buf, int len) {
boolean changed = false;
if (len != lastLen) {
changed = true;
} else if (lastBuf == null) {
changed = true;
} else {
for (int i = 0; i < len; i++) {
if (buf[i] != lastBuf[i]) {
changed = true;
break;
}
}
}
lastLen = len;
lastBuf = buf;
return changed;
}
};
@Override
public void run() {
......
......@@ -15,8 +15,9 @@
</LinearLayout>
<TextView
android:text="请出示付款二维码"
android:textSize="40sp"
android:id="@+id/message"
android:text="请出示付款码"
android:textSize="60sp"
android:textColor="#333"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment