左晓为主开发手持机充值管理机
zuoxiao
2024-03-26 ebc06a3ae3a42bd6ac1359a59c55d5e6f1a0e2f0
优化通讯
写卡界面添加二次确认
优化用户写卡逻辑,提高写卡速度。
15个文件已修改
9个文件已添加
765 ■■■■ 已修改文件
app/src/main/java/com/dayu/recharge/MyApplication.java 100 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/recharge/activity/BaseActivity.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/recharge/activity/NFCWreatActivity.java 88 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/recharge/activity/NewCardActivity.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/recharge/activity/ReadCardAcitivy.java 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/recharge/activity/RechargeActivity.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/recharge/net/CallbackIDFactoryImpl.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/recharge/net/CallbackSender.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/recharge/net/SocketNet.java 133 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/recharge/tools/NFCWriteHelper.java 134 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/recharge/tools/NfcReadHelper.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/recharge/tools/WriteCardUtils.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/recharge/view/ConfirmDialog.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/recharge/view/ProgressDialog.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/confirm_dialog.xml 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
easysocket/.idea/.gitignore 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
easysocket/.idea/gradle.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
easysocket/.idea/misc.xml 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
easysocket/.idea/vcs.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
easysocket/local.properties 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
easysocket/src/main/java/com/easysocket/EasySocket.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
easysocket/src/main/java/com/easysocket/connection/connect/SuperConnection.java 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
easysocket/src/main/java/com/easysocket/connection/dispatcher/CallbackResponseDispatcher.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
local.properties 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/recharge/MyApplication.java
@@ -8,6 +8,7 @@
import com.dayu.recharge.dao.BaseDaoSingleton;
import com.dayu.recharge.dbBean.IpBean;
import com.dayu.recharge.net.CallbackIDFactoryImpl;
import com.dayu.recharge.net.ScoketMessageProtocol;
import com.dayu.recharge.net.SocketCallBack;
import com.dayu.recharge.net.SocketData;
@@ -34,14 +35,12 @@
public class MyApplication extends Application {
    public static String TAG = "MyApplication";
    public static MyApplication myApplication;
    private String address;
    SocketNet.CreateBack createBack;
    //是否正在请求初始化接口
    public boolean isDoInitMachine = false;
    //是否连接服务器成功
    public boolean isConncet = false;
    private final Timer timer = new Timer();
    //每次启动程序只去注册一遍,不再重新注册。
    public static boolean isCreate = false;
@@ -89,48 +88,10 @@
//                ipBean.setIp("dayuyanjiuyuan.top");
//                ipBean.setPort(8888);
            }
            if (ipBean != null) {
                try {
                    //处理当连接上IP后修改ip不生效问题
                    if (EasySocket.getInstance().getDefconnection() != null) {
                        SocketAddress address = EasySocket.getInstance().getDefconnection().getOptions().getSocketAddress();
                        if (address != null) {
                            if (!address.getIp().equals(ipBean.getIp()) || address.getPort() != ipBean.getPort()) {
                                EasySocket.getInstance().destroyConnection();
                            }
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (!SocketUtil.isInteger(ipBean.getIp())) {
                    //域名方式
                    SocketUtil.parseHostGetIPAddress(ipBean.getIp(), new Handler() {
                        @Override
                        public void handleMessage(Message msg) {
                            super.handleMessage(msg);
                            switch (msg.what) {
                                case 1:
                                    createSocket(msg.obj + "", ipBean.getPort(), "0", 88);
                                    break;
                                case 2:
                                    InetAddress[] data = (InetAddress[]) msg.obj;
                                    createSocket(data[0].getHostAddress(), ipBean.getPort(), data[1].getHostAddress(), ipBean.getPort());
                                    break;
                                case -1:
                                    ToastUtil.show("DNS解析失败");
                                    break;
                            }
                        }
                    });
                } else {
                    //ip方式
                    if (EasySocket.getInstance().getContext() == null || isCreate) {
                        createSocket(ipBean.getIp(), ipBean.getPort(), "0", 88);
                    } else {
            if (SocketNet.getInstance().isNetworkAvailable(this)){
                if (ipBean != null) {
                    try {
                        //处理当连接上IP后修改ip不生效问题
                        if (EasySocket.getInstance().getDefconnection() != null) {
                            SocketAddress address = EasySocket.getInstance().getDefconnection().getOptions().getSocketAddress();
                            if (address != null) {
@@ -139,10 +100,53 @@
                                }
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    if (!SocketUtil.isInteger(ipBean.getIp())) {
                        //域名方式
                        SocketUtil.parseHostGetIPAddress(ipBean.getIp(), new Handler() {
                            @Override
                            public void handleMessage(Message msg) {
                                super.handleMessage(msg);
                                switch (msg.what) {
                                    case 1:
                                        createSocket(msg.obj + "", ipBean.getPort(), "0", 88);
                                        break;
                                    case 2:
                                        InetAddress[] data = (InetAddress[]) msg.obj;
                                        createSocket(data[0].getHostAddress(), ipBean.getPort(), data[1].getHostAddress(), ipBean.getPort());
                                        break;
                                    case -1:
                                        ToastUtil.show("DNS解析失败");
                                        break;
                                }
                            }
                        });
                    } else {
                        //ip方式
                        if (EasySocket.getInstance().getContext() == null || isCreate) {
                            createSocket(ipBean.getIp(), ipBean.getPort(), "0", 88);
                        } else {
                            if (EasySocket.getInstance().getDefconnection() != null) {
                                SocketAddress address = EasySocket.getInstance().getDefconnection().getOptions().getSocketAddress();
                                if (address != null) {
                                    if (!address.getIp().equals(ipBean.getIp()) || address.getPort() != ipBean.getPort()) {
                                        EasySocket.getInstance().destroyConnection();
                                    }
                                }
                            }
                        }
                    }
                }
            }else {
                ToastUtil.show("请检查网络连接");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
@@ -166,7 +170,7 @@
                initMachineRequestBean.setAddress(addressCode);
                initMachineRequestBean.setXuLie(SocketUtil.getXuLie(this));
                initMachineRequestBean.setAFN("91");
                SocketNet.getInstance().sendTestMessage(initMachineRequestBean.pack(), new SocketCallBack() {
                SocketNet.getInstance().sendTestMessage(initMachineRequestBean.pack(), "91",new SocketCallBack() {
                    @Override
                    public void onSocketResponse(SocketData readData) {
@@ -183,7 +187,7 @@
                            confirmMachineRequestBean.setAFN("92");
                            confirmMachineRequestBean.setInitCode(initCode);
                            Log.i("Socket", "确认注册报文");
                            SocketNet.getInstance().sendTestMessage(confirmMachineRequestBean.pack(), new SocketCallBack() {
                            SocketNet.getInstance().sendTestMessage(confirmMachineRequestBean.pack(), "92",new SocketCallBack() {
                                @Override
                                public void onSocketResponse(SocketData readData) {
@@ -240,10 +244,10 @@
                .setSocketAddress(new SocketAddress(ip, port))
                // 定义消息协议,方便解决 socket黏包、分包的问题
                .setReaderProtocol(new ScoketMessageProtocol())
                .setCallbackIDFactory(new CallbackIDFactoryImpl())
                .setMaxWriteBytes(150)
                .setMaxReadBytes(150)
                .setRequestTimeout(5 * 1000)
                .setRequestTimeout(20 * 1000)
                .setBackupAddress(new SocketAddress(backUpIp, backUpPort))
                .build();
app/src/main/java/com/dayu/recharge/activity/BaseActivity.java
@@ -1,7 +1,5 @@
package com.dayu.recharge.activity;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
@@ -11,12 +9,10 @@
import androidx.appcompat.app.AppCompatActivity;
import com.dayu.recharge.MyApplication;
import com.dayu.recharge.R;
import com.dayu.recharge.dao.AppDatabase;
import com.dayu.recharge.dao.BaseDaoSingleton;
import com.dayu.recharge.view.TitleBar;
import com.easysocket.EasySocket;
/**
 * Created by zuoxiao on 2018/12/20.
@@ -58,13 +54,7 @@
            if (view != null && view instanceof TitleBar) {
                titleBar = (TitleBar) view;
                titleBar.setOnItemclickListner(TitleBar.ClickType_LEFT_IMAGE, new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        finish();
                    }
                });
                titleBar.setOnItemclickListner(TitleBar.ClickType_LEFT_IMAGE, v -> finish());
            }
        } catch (Exception e) {
            e.printStackTrace();
app/src/main/java/com/dayu/recharge/activity/NFCWreatActivity.java
@@ -5,6 +5,7 @@
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Toast;
@@ -42,7 +43,9 @@
import com.dayu.recharge.utils.MyCommon;
import com.dayu.recharge.utils.SocketUtil;
import com.dayu.recharge.utils.TipUtil;
import com.dayu.recharge.view.ConfirmDialog;
import com.dayu.recharge.view.ProgressDialog;
import com.dayu.recharge.view.TitleBar;
import com.tencent.bugly.crashreport.CrashReport;
import java.util.Arrays;
@@ -71,6 +74,11 @@
    boolean configDeviceRegiestFlag = false;
    boolean configPowerFlag = false;
    /**
     * 是否不再验证用户直接写卡
     */
    boolean isAgainWrite = false;
    UserCardBean userCardBean;
@@ -105,6 +113,7 @@
    //充值通信是否完成
    boolean rechargeIsOk = false;
    ActivityWriteTextBinding binding;
    ConfirmDialog confirmDialog;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
@@ -113,12 +122,61 @@
            binding = ActivityWriteTextBinding.inflate(LayoutInflater.from(this));
            setContentView(binding.getRoot());
            nfcWreatActivity = this;
            setData();
            getData();
            baseApp = (MyApplication) getApplication();
        } catch (Exception e) {
            e.printStackTrace();
            CrashReport.postCatchedException(e);
        }
    }
    private void setData() {
        titleBar.setOnItemclickListner(TitleBar.ClickType_LEFT_IMAGE, v -> {
            //处理因用户误操作返回导致不能写卡的问题,添加二次确认
            back();
        });
    }
    private void back() {
        if (isUser) {
            confirmDialog = new ConfirmDialog(NFCWreatActivity.this, v -> {
                confirmDialog.dismiss();
                myFinish();
            });
            confirmDialog.show();
        } else if (!TextUtils.isEmpty(morny)) {
            confirmDialog = new ConfirmDialog(NFCWreatActivity.this, v -> {
                confirmDialog.dismiss();
                myFinish();
            });
            confirmDialog.show();
        } else {
            finish();
        }
    }
    private void myFinish() {
        if (NewCardActivity.newCardActivity != null) {
            NewCardActivity.newCardActivity.finish();
        }
        if (RechargeActivity.rechargeActivity != null) {
            RechargeActivity.rechargeActivity.finish();
        }
        NFCWreatActivity.nfcWreatActivity.finish();
    }
    //点击两次退出程序 有时间间隔 间隔内点击则退出程序 否则 则提示
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            back();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
@@ -201,6 +259,8 @@
            binding.textView.setTextColor(getResources().getColor(R.color.red));
        } else if (cardType.equals("-1")) {
            TipUtil.show(NFCWreatActivity.this, "请勿移动卡片,读卡失败请重试!!");
        } else if (cardType.equals("-2")) {
            TipUtil.show(NFCWreatActivity.this, "读卡失败,请检查卡是否是用户卡");
        } else {
            Log.i("NFCWreatActivity", "olduserCard!=null  saveData");
            saveData();
@@ -219,7 +279,6 @@
                    || configureDeviceRegistrationCrad != null
                    || configurationPowerCard != null) {
                if (userCard != null && TextUtils.isEmpty(morny)) {
                    userFlag = WriteCardUtils.setUser(intent, userCard, this);
                }
                if (cleanCard != null) {
@@ -360,7 +419,7 @@
            rechargeRequestBean.setBalance(morny);
            rechargeRequestBean.setOrderId(SocketUtil.getOrderId(NFCWreatActivity.this));
            SocketNet.getInstance().sendTestMessage(rechargeRequestBean.pack(), new SocketCallBack() {
            SocketNet.getInstance().sendTestMessage(rechargeRequestBean.pack(),"95", new SocketCallBack() {
                @Override
                public void onSocketResponse(SocketData readData) {
@@ -437,7 +496,7 @@
        UserCard userCardold = NfcReadHelper.getInstence(intent, this).getUserCardData();
        if (userCardold != null) {
            //判断是否充值的是一个卡
            if (userCard.getInitPeasantCode().equals(userCardold.getInitPeasantCode())) {
            if (userCard.getInitPeasantCode().equals(userCardold.getInitPeasantCode()) || isAgainWrite) {
                userCard.setState("00");
                userFlag = WriteCardUtils.setUser(intent, userCard, this);
                //   打印相关
@@ -445,12 +504,14 @@
                    setPrinterData(rechargeBean);
                    startDetailActivity(userName, "启用");
                } else {
                    TipUtil.show(NFCWreatActivity.this, "写卡失败,请重新再试");
                    isAgainWrite = true;
                    TipUtil.show(NFCWreatActivity.this, "写卡失败,请重新贴卡");
                }
            } else {
                TipUtil.show(NFCWreatActivity.this, "读取的卡和充值的卡不一致");
            }
        }
        stopAnim();
    }
    private void setmanageCard(Intent intent, final ManageCard manageCard) {
@@ -539,13 +600,7 @@
            detail.putExtra("morny", morny);
        }
        startActivity(detail);
        if (NewCardActivity.newCardActivity != null) {
            NewCardActivity.newCardActivity.finish();
        }
        if (RechargeActivity.rechargeActivity != null) {
            RechargeActivity.rechargeActivity.finish();
        }
        NFCWreatActivity.nfcWreatActivity.finish();
        myFinish();
    }
    /**
@@ -564,7 +619,7 @@
            requestBean.setInitCode(initCode);
            requestBean.setInitPeasantCode(initPeasantCode);
            requestBean.setXuLie(SocketUtil.getXuLie(this));
            SocketNet.getInstance().sendTestMessage(requestBean.pack(), new SocketCallBack() {
            SocketNet.getInstance().sendTestMessage(requestBean.pack(), "94",new SocketCallBack() {
                @Override
                public void onSocketResponse(SocketData readData) {
                    if (CRC8.isCRC8(readData.getOriginDataBytes())) {
@@ -602,12 +657,7 @@
                                //补卡逻辑
                                userFlag = WriteCardUtils.setUser(intent, userCard, NFCWreatActivity.this);
                                if (userFlag) {
                                    TipUtil.show(NFCWreatActivity.this, "补卡成功", new TipUtil.TipListener() {
                                        @Override
                                        public void onCancle() {
                                            NFCWreatActivity.this.finish();
                                        }
                                    });
                                    TipUtil.show(NFCWreatActivity.this, "补卡成功", () -> NFCWreatActivity.this.finish());
                                }
                                return;
                            } else if ("01".equals(state)) {
@@ -642,7 +692,6 @@
                @Override
                public void onSocketError(int code, String msg) {
                    stopAnim();
                    TipUtil.show(NFCWreatActivity.this, msg);
                }
            });
@@ -657,6 +706,7 @@
    protected void onDestroy() {
        super.onDestroy();
        ProgressDialog.dismiss();
        nfcWreatActivity = null;
    }
}
app/src/main/java/com/dayu/recharge/activity/NewCardActivity.java
@@ -53,7 +53,6 @@
    public static final int SCAN_IDCARD_REQUEST = 1;
    UserCardBean userCardBean;
    Dialog dialog;
    ActivityNewCardBinding newCardBinding;
    AdminDataBean adminData;
@@ -271,7 +270,7 @@
        initCardRequestBean.setPhone(phoneBuffer.toString());
        String userId = userCardBean.getUserID();
        initCardRequestBean.setIdCard(SocketUtil.str2HexStr(userId));
        SocketNet.getInstance().sendTestMessage(initCardRequestBean.pack(), new SocketCallBack() {
        SocketNet.getInstance().sendTestMessage(initCardRequestBean.pack(), "93",new SocketCallBack() {
            @Override
            public void onSocketResponse(SocketData readData) {
app/src/main/java/com/dayu/recharge/activity/ReadCardAcitivy.java
@@ -39,20 +39,6 @@
 */
public class ReadCardAcitivy extends BaseNfcActivity {
    private static final int USER_CRAD = 1;
    private static final int MANAGE_CRAD = 2;
    private static final int CLEAN_CARD = 3;
    private static final int REGISTERED_CARD = 4;
    private static final int CLEAN_ALL_USER = 5;
    private static final int DOMAIN_CARD = 6;
    private static final int TEST_CARD = 7;
    private static final int CONFIGURATION_CARD = 8;
    private static final int CONFIGURATION_POWER_CARD = 9;
    private static final int PASS_WORD_CRAD = 10;
    volatile UserCard userCard;
    ActivityRedCardBinding redCardBinding;
@@ -229,7 +215,7 @@
        requestBean.setInitCode(initCode);
        requestBean.setInitPeasantCode(initPeasantCode);
        requestBean.setXuLie(SocketUtil.getXuLie(this));
        SocketNet.getInstance().sendTestMessage(requestBean.pack(), new SocketCallBack() {
        SocketNet.getInstance().sendTestMessage(requestBean.pack(), "94",new SocketCallBack() {
            @Override
            public void onSocketResponse(SocketData readData) {
                if (CRC8.isCRC8(readData.getOriginDataBytes())) {
@@ -285,6 +271,7 @@
            @Override
            public void onSocketError(int code, String msg) {
                stopAnim();
                TipUtil.show(ReadCardAcitivy.this, msg);
            }
        });
app/src/main/java/com/dayu/recharge/activity/RechargeActivity.java
@@ -167,7 +167,7 @@
            requestBean.setInitCode(initCode);
            requestBean.setInitPeasantCode(initPeasantCode);
            requestBean.setXuLie(SocketUtil.getXuLie(this));
            SocketNet.getInstance().sendTestMessage(requestBean.pack(), new SocketCallBack() {
            SocketNet.getInstance().sendTestMessage(requestBean.pack(),"94", new SocketCallBack() {
                @Override
                public void onSocketResponse(SocketData readData) {
                    ProgressDialog.dismiss();
app/src/main/java/com/dayu/recharge/net/CallbackIDFactoryImpl.java
New file
@@ -0,0 +1,29 @@
package com.dayu.recharge.net;
import com.dayu.recharge.tools.HexUtil;
import com.easysocket.config.CallbackIDFactory;
import com.easysocket.entity.OriginReadData;
/**
 * author: zuo
 * Date: 2024-03-26
 * Time: 10:02
 * 备注:
 */
public class CallbackIDFactoryImpl extends CallbackIDFactory {
    /**
     * @param
     * @return
     */
    @Override
    public String getCallbackID(OriginReadData data) {
        try {
            String AFN = HexUtil.byteToHex(data.getBodyBytes()[1]);
            return AFN;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
app/src/main/java/com/dayu/recharge/net/CallbackSender.java
New file
@@ -0,0 +1,38 @@
package com.dayu.recharge.net;
import com.easysocket.entity.basemsg.SuperCallbackSender;
/**
 * author: zuo
 * Date: 2024-03-25
 * Time: 17:33
 * 备注:带有回调标识的发送消息
 */
public class CallbackSender extends SuperCallbackSender {
    //通信类型码
    String AFN;
    public String getAFN() {
        return AFN;
    }
    public void setAFN(String AFN) {
        this.AFN = AFN;
    }
    byte[] data;
    public byte[] getData() {
        return data;
    }
    public void setData(byte[] data) {
        this.data = data;
    }
    @Override
    public byte[] pack() {
        return data;
    }
}
app/src/main/java/com/dayu/recharge/net/SocketNet.java
@@ -1,22 +1,22 @@
package com.dayu.recharge.net;
import android.content.Context;
import android.os.Handler;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.text.TextUtils;
import android.util.Log;
import com.dayu.recharge.MyApplication;
import com.dayu.recharge.activity.HomeActivity;
import com.dayu.recharge.dao.BaseDaoSingleton;
import com.dayu.recharge.dbBean.AdminDataBean;
import com.dayu.recharge.dbBean.DeviceNumber;
import com.dayu.recharge.dbBean.IpBean;
import com.easysocket.EasySocket;
import com.easysocket.connection.action.SocketStatus;
import com.easysocket.callback.SimpleCallBack;
import com.easysocket.entity.OriginReadData;
import com.easysocket.entity.SocketAddress;
import com.easysocket.exception.RequestTimeOutException;
import com.easysocket.interfaces.conn.ISocketActionListener;
import com.easysocket.interfaces.conn.SocketActionListener;
import com.dayu.recharge.MyApplication;
import com.easysocket.utils.HexUtil;
import com.tencent.bugly.crashreport.CrashReport;
@@ -34,6 +34,8 @@
    boolean isTest = false;
    Context mContext;
    CallbackSender mSender;
    public static SocketNet getInstance() {
        if (socketNet == null) {
            socketNet = new SocketNet();
@@ -48,24 +50,60 @@
    /**
     * 发送一个的消息,
     */
    public void sendTestMessage(byte[] dataMessage, SocketCallBack callBack) {
    public void sendTestMessage(byte[] dataMessage, String AFN, SocketCallBack callBack) {
        myCallBack = callBack;
        isTest = false;
        // 发送
//        EasySocket.getInstance().upMessage(dataMessage);
        if (EasySocket.getInstance().getDefconnection() != null) {
//            EasySocket.getInstance().disconnect(false);
//            EasySocket.getInstance().connect();
//            if (EasySocket.getInstance().getDefconnection().getConnectionStatus()== SocketStatus.SOCKET_CONNECTED){
            EasySocket.getInstance().upMessage(dataMessage);
//            }else {
//
//            }
        mSender = new CallbackSender();
        mSender.setAFN(AFN);
        mSender.setData(dataMessage);
        if (isNetworkAvailable(MyApplication.myApplication)) {
            // 发送
            if (EasySocket.getInstance().getDefconnection() != null) {
//            EasySocket.getInstance().upMessage(dataMessage);
                EasySocket.getInstance().upCallbackMessage(mSender).onCallBack(new SimpleCallBack(AFN) {
                    @Override
                    public void onResponse(OriginReadData data) {
//            this.dataMessage = dataMessage;
                        try {
                            mSender = null;
                            myCallBack=null;
                            Log.i("SocketActionListener", "SimpleCallBack收到数据-->" + HexUtil.bytesToHex(data.getBodyBytes()));
                            SocketData socketData = new SocketData();
                            socketData.setBodyData(data.getBodyBytes());
                            socketData.setHeaderData(data.getHeaderData());
//            dataMessage = null;
                            if (callBack != null) {
                                callBack.onSocketResponse(socketData);
                            }
                        } catch (Exception e) {
                         e.printStackTrace();
                        }
                    }
                    @Override
                    public void onError(Exception e) {
                        super.onError(e);
                        mSender = null;
                        myCallBack=null;
                        try {
                            if (e instanceof RequestTimeOutException) {
                                callBack.onSocketError(-3, "请求超时,正在重试");
                                //超时后重新连接
                                EasySocket.getInstance().disconnect(true);
                            }
                        } catch (Exception ex) {
                            throw new RuntimeException(ex);
                        }
                    }
                });
            } else {
                callBack.onSocketError(-2, "与服务器连接断开,请检查网络,或者稍后再试");
                MyApplication.myApplication.initEasySocket(false, null);
            }
        } else {
            MyApplication.myApplication.initEasySocket(false, null);
            callBack.onSocketError(-2, "请检查网络连接");
        }
    }
@@ -103,11 +141,14 @@
         */
        @Override
        public void onSocketConnSuccess(SocketAddress socketAddress) {
            Log.i("SocketActionListener1111", "连接成功");
            MyApplication.myApplication.isConncet = true;
            try {
                AdminDataBean adminData = BaseDaoSingleton.getInstance(MyApplication.myApplication).adminDao().findFirst();
                Log.i("SocketActionListener1111", "isDoInitMachine==" + MyApplication.myApplication.isDoInitMachine + "");
                //每次连接成功注册一次设备
                if (!MyApplication.myApplication.isDoInitMachine) {
                    Log.i("SocketActionListener1111", "isDoInitMachine");
                    if (MyApplication.myApplication.ipBean != null && adminData != null) {
@@ -117,8 +158,16 @@
                        }
                    }
                }
                try {
                    if (mSender != null) {
                        sendTestMessage(mSender.getData(), mSender.getAFN(), myCallBack);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } catch (Exception e) {
                CrashReport.postCatchedException(e);
            }
@@ -135,10 +184,10 @@
            MyApplication.myApplication.isConncet = false;
            rushState();
            Log.i("SocketActionListener", "socket连接失败");
            if (myCallBack != null) {
                myCallBack.onSocketError(-1, "连接数据中心失败,请检查网络");
            }
            myCallBack = null;
//            if (myCallBack != null) {
//                myCallBack.onSocketError(-1, "连接数据中心失败,请检查网络");
//            }
//            myCallBack = null;
        }
        /**
@@ -151,10 +200,14 @@
            Log.i("SocketActionListener", "---> socket断开连接,是否需要重连:" + isNeedReconnect);
            MyApplication.myApplication.isConncet = false;
            rushState();
            if (myCallBack != null) {
                myCallBack.onSocketError(-2, "与服务器连接断开,请重试");
            try {
                if (myCallBack != null) {
                    myCallBack.onSocketError(-2, "与服务器连接断开,请检查网络");
                }
                myCallBack = null;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            myCallBack = null;
        }
@@ -167,14 +220,14 @@
        public void onSocketResponse(SocketAddress socketAddress, OriginReadData originReadData) {
            super.onSocketResponse(socketAddress, originReadData);
            Log.i("SocketActionListener", "SocketActionListener收到数据-->" + HexUtil.bytesToHex(originReadData.getBodyBytes()));
            SocketData socketData = new SocketData();
            socketData.setBodyData(originReadData.getBodyBytes());
            socketData.setHeaderData(originReadData.getHeaderData());
//            dataMessage = null;
            if (myCallBack != null) {
                myCallBack.onSocketResponse(socketData);
            }
            myCallBack = null;
//            SocketData socketData = new SocketData();
//            socketData.setBodyData(originReadData.getBodyBytes());
//            socketData.setHeaderData(originReadData.getHeaderData());
////            dataMessage = null;
//            if (myCallBack != null) {
//                myCallBack.onSocketResponse(socketData);
//            }
//            myCallBack = null;
        }
    };
@@ -188,4 +241,16 @@
        }
    }
    // 检查网络连接是否可用
    public boolean isNetworkAvailable(Context context) {
        if (context != null) {
            ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            if (connectivityManager != null) {
                NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
                return activeNetworkInfo != null && activeNetworkInfo.isConnected();
            }
        }
        return false;
    }
}
app/src/main/java/com/dayu/recharge/tools/NFCWriteHelper.java
@@ -7,6 +7,8 @@
import android.nfc.tech.MifareClassic;
import android.util.Log;
import com.dayu.recharge.card.UserCard;
import java.io.IOException;
/**
@@ -55,6 +57,67 @@
        return helper;
    }
    /**
     * 写卡
     *
     * @param userCard 用户卡内容
     * @param
     */
    public boolean writeUserData(UserCard userCard) {
        if (userCard != null) {
            int a = 1;
            try {
                MifareClassic mfc = MifareClassic.get(tag);
                if (null != mfc) {
                    try {
                        //连接NFC
                        mfc.connect();
                        //验证扇区密码
                        boolean isOpen = mfc.authenticateSectorWithKeyA(a, defauleKey);
                        if (!isOpen) {
                            isOpen = mfc.authenticateSectorWithKeyA(a, companyKey);
                        } else {
                            //写卡时修改所有密码
                            changePasword(a, mfc);
                        }
                        if (isOpen) {
                            for (int b = 0; b < 3; b++) {
                                byte[] data;
                                if (b == 0) {
                                    data = userCard.getZeroBytes();
                                } else if (b == 1) {
                                    data = userCard.getOneBytes();
                                } else {
                                    data = userCard.getTwoBytes();
                                }
                                int bIndex = mfc.sectorToBlock(a);
                                //写卡
                                mfc.writeBlock(bIndex + b, data);
                            }
                            return true;
                        }
                        return false;
                    } catch (Exception e) {
                        e.printStackTrace();
                        return false;
                    } finally {
                        try {
                            mfc.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        return false;
    }
    /**
     * 写卡
     *
@@ -65,8 +128,6 @@
     */
    public boolean writeData(byte[] str, int a, int b) {
        Log.i("NFCWreatActivity", "writeData: a=" + a + " b=" + b);
        //写卡时修改所有密码
        changePasword(a);
        if (str.length <= 16) {
            try {
                MifareClassic mfc = MifareClassic.get(tag);
@@ -90,6 +151,9 @@
                        boolean isOpen = mfc.authenticateSectorWithKeyA(a, defauleKey);
                        if (!isOpen) {
                            isOpen = mfc.authenticateSectorWithKeyA(a, companyKey);
                        } else {
                            //写卡时修改所有密码
                            changePasword(a, mfc);
                        }
                        if (isOpen) {
                            int bIndex = mfc.sectorToBlock(a);
@@ -124,54 +188,52 @@
     * @param a 书写的扇区
     *          //     * @param callback 返回监听
     */
    public boolean changePasword(int a) {
        MifareClassic mfc = MifareClassic.get(tag);
    public boolean changePasword(int a, MifareClassic mfc) {
//        MifareClassic mfc = MifareClassic.get(tag);
        byte[] data = new byte[16];
        if (null != mfc) {
            try {
                mfc.connect();
                int count = mfc.getSectorCount();
                boolean isOpen = mfc.authenticateSectorWithKeyA(a, defauleKey);
                //验证是否是默认密码,当默认密码时修改密码
                if (isOpen) {
                    //将密码转换为keyA
                    byte[] dataA = HexUtil.hexToByteArray(companyKeyA);
                    for (int i = 0; i < dataA.length; i++) {
                        data[i] = dataA[i];
                    }
                    //输入控制位
                    data[6] = (byte) 0xFF;
                    data[7] = (byte) 0x07;
                    data[8] = (byte) 0x80;
                    data[9] = (byte) 0x69;
                    byte[] dataB = HexUtil.hexToByteArray(companyKeyB);
                    //将密码转换为KeyB
                    for (int i = 0; i < dataB.length; i++) {
                        data[i + 10] = dataB[i];
                    }
                    int bIndex = mfc.sectorToBlock(a);
                    int bCount = mfc.getBlockCountInSector(a);
                    //写到扇区的最后一个块
                    mfc.writeBlock(bIndex + bCount - 1, data);
//                mfc.connect();
//                int count = mfc.getSectorCount();
//                boolean isOpen = mfc.authenticateSectorWithKeyA(a, defauleKey);
//                //验证是否是默认密码,当默认密码时修改密码
//                if (isOpen) {
                //将密码转换为keyA
                byte[] dataA = HexUtil.hexToByteArray(companyKeyA);
                for (int i = 0; i < dataA.length; i++) {
                    data[i] = dataA[i];
                }
                //输入控制位
                data[6] = (byte) 0xFF;
                data[7] = (byte) 0x07;
                data[8] = (byte) 0x80;
                data[9] = (byte) 0x69;
                byte[] dataB = HexUtil.hexToByteArray(companyKeyB);
                //将密码转换为KeyB
                for (int i = 0; i < dataB.length; i++) {
                    data[i + 10] = dataB[i];
                }
                int bIndex = mfc.sectorToBlock(a);
                int bCount = mfc.getBlockCountInSector(a);
                //写到扇区的最后一个块
                mfc.writeBlock(bIndex + bCount - 1, data);
//                    byte[] dataa = mfc.readBlock(bIndex + bCount - 1);
//                    // 修改密码 A
//                    mfc.writeBlock(mfc.sectorToBlock(a) + 3, dataA);
//                    // 修改密码 B
//                    mfc.writeBlock(mfc.sectorToBlock(a) + 7, dataB);
                }
//                }
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
//                callback.isSusses(false);
            } finally {
                try {
                    mfc.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
//                try {
//                    mfc.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
            }
        }
        return false;
app/src/main/java/com/dayu/recharge/tools/NfcReadHelper.java
@@ -133,7 +133,7 @@
                } else {
                    Log.i("NFCWreatActivity", "isOpen===" + isOpen);
                    return "-1";
                    return "-2";
                }
            } catch (IOException e) {
                return "-1";
app/src/main/java/com/dayu/recharge/tools/WriteCardUtils.java
@@ -17,15 +17,8 @@
    //向卡写入用户信息
    public static boolean setUser(Intent intent, UserCard userCard, Activity activity) {
        userFlag = NFCWriteHelper.getInstence(intent,activity).writeData(userCard.getZeroBytes(), 1, 0);
        if (!userFlag) {
            return false;
        }
        userFlag = NFCWriteHelper.getInstence(intent,activity).writeData(userCard.getOneBytes(), 1, 1);
        if (!userFlag) {
            return false;
        }
        userFlag = NFCWriteHelper.getInstence(intent,activity).writeData(userCard.getTwoBytes(), 1, 2);
        userFlag = NFCWriteHelper.getInstence(intent,activity).writeUserData(userCard);
        return userFlag;
    }
}
app/src/main/java/com/dayu/recharge/view/ConfirmDialog.java
New file
@@ -0,0 +1,54 @@
package com.dayu.recharge.view;
import android.app.Activity;
import android.app.Dialog;
import android.view.Gravity;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import com.dayu.recharge.R;
/**
 * author: zuo
 * Date: 2024-03-25
 * Time: 13:22
 * 备注:
 */
public class ConfirmDialog extends Dialog {
    Activity mContext;
    View.OnClickListener mListner;
    public ConfirmDialog(@NonNull Activity context) {
        super(context, R.style.ws_pay_showSelfDialog);
        mContext = context;
        initView();
    }
    public ConfirmDialog(@NonNull Activity context, View.OnClickListener listner) {
        super(context, R.style.ws_pay_showSelfDialog);
        mContext = context;
        mListner = listner;
        initView();
    }
    private void initView() {
        getWindow().setGravity(Gravity.CENTER);
        setContentView(R.layout.confirm_dialog);
        setCanceledOnTouchOutside(false);
        TextView cannel = (TextView) this.findViewById(R.id.confirm_cancel);
        TextView ok = (TextView) this.findViewById(R.id.confirm_ok);
        cannel.setOnClickListener(v -> ConfirmDialog.this.dismiss());
        if (mListner == null) {
            ok.setOnClickListener((View v) -> {
                ConfirmDialog.this.dismiss();
                mContext.finish();
            });
        } else {
            ok.setOnClickListener(mListner);
        }
    }
}
app/src/main/java/com/dayu/recharge/view/ProgressDialog.java
@@ -2,9 +2,7 @@
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import com.dayu.recharge.activity.NewCardActivity;
import com.tencent.bugly.crashreport.CrashReport;
/**
@@ -22,7 +20,6 @@
            dialog = android.app.ProgressDialog.show(activity, "", "正在通信请稍后", true, true);
        } catch (Exception e) {
            e.printStackTrace();
            CrashReport.postCatchedException(e);
        }
    }
app/src/main/res/layout/confirm_dialog.xml
New file
@@ -0,0 +1,65 @@
<?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="#00ffffff"
    android:gravity="center"
    android:orientation="vertical">
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/ws_pay_bg_dialog_top_stroke"
        android:gravity="center"
        android:orientation="vertical"
        android:padding="20dp">
        <TextView
            android:id="@+id/confirm_data"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="22sp"
            android:textColor="#000000"
            android:text="确认退出吗?"
            />
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <TextView
                android:id="@+id/confirm_cancel"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="20dp"
                android:background="@drawable/ws_login_red_btn_one"
                android:paddingLeft="15dp"
                android:paddingTop="5dp"
                android:paddingRight="15dp"
                android:paddingBottom="5dp"
                android:text="取消"
                android:textSize="@dimen/text_size" />
            <TextView
                android:id="@+id/confirm_ok"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="100dp"
                android:layout_marginTop="20dp"
                android:background="@drawable/ws_login_red_btn_one"
                android:paddingLeft="15dp"
                android:paddingTop="5dp"
                android:paddingRight="15dp"
                android:paddingBottom="5dp"
                android:text="确认"
                android:textSize="@dimen/text_size" />
        </LinearLayout>
    </LinearLayout>
</LinearLayout>
easysocket/.idea/.gitignore
New file
@@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml
easysocket/.idea/gradle.xml
New file
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="GradleSettings">
    <option name="linkedExternalProjectsSettings">
      <GradleProjectSettings>
        <option name="testRunner" value="GRADLE" />
        <option name="distributionType" value="DEFAULT_WRAPPED" />
        <option name="externalProjectPath" value="$PROJECT_DIR$" />
        <option name="gradleJvm" value="jbr-17" />
      </GradleProjectSettings>
    </option>
  </component>
</project>
easysocket/.idea/misc.xml
New file
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ExternalStorageConfigurationManager" enabled="true" />
  <component name="ProjectRootManager" version="2" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
    <output url="file://$PROJECT_DIR$/build/classes" />
  </component>
  <component name="ProjectType">
    <option name="id" value="Android" />
  </component>
</project>
easysocket/.idea/vcs.xml
New file
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="VcsDirectoryMappings">
    <mapping directory="$PROJECT_DIR$/.." vcs="Git" />
  </component>
</project>
easysocket/local.properties
New file
@@ -0,0 +1,8 @@
## This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Mon Mar 25 17:17:41 CST 2024
sdk.dir=D\:\\android\\sdk
easysocket/src/main/java/com/easysocket/EasySocket.java
@@ -12,8 +12,6 @@
import com.easysocket.interfaces.conn.ISocketActionListener;
import com.easysocket.utils.LogUtil;
import java.nio.charset.Charset;
/**
 * Author:Alex
 * Date:2019/6/4
@@ -129,8 +127,9 @@
     */
    public EasySocket disconnect(boolean isNeedReconnect) {
        LogUtil.d("EasySocket--》disconnect");
        if (defConnection != null)
        getDefconnection().disconnect(isNeedReconnect);
        if (defConnection != null) {
            getDefconnection().disconnect(isNeedReconnect);
        }
        return this;
    }
easysocket/src/main/java/com/easysocket/connection/connect/SuperConnection.java
@@ -122,12 +122,9 @@
    public synchronized void connect() {
        if (connectionStatus.get() == SocketStatus.SOCKET_DISCONNECTING) {
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    LogUtil.d("---> socket>>connect>>正在断开连接,延时一秒執行重连");
                    connect();
                }
            new Handler().postDelayed(() -> {
                LogUtil.d("---> socket>>connect>>正在断开连接,延时一秒執行重连");
                connect();
            }, 1000); // 延时1秒
            return;
        }
@@ -328,6 +325,10 @@
        return this;
    }
    /**
     * 消息回调主要处理超时消息
     * @param callBack
     */
    @Override
    public void onCallBack(SuperCallBack callBack) {
        callbackResponseDispatcher.addSocketCallback(callBack);
easysocket/src/main/java/com/easysocket/connection/dispatcher/CallbackResponseDispatcher.java
@@ -29,7 +29,7 @@
     * 保存发送的每个回调消息的监听实例,key为回调标识callbackId,这样回调消息有反馈的时候,就可以找到并调用
     * 对应的监听对象
     */
    private Map<String, SuperCallBack> callbacks = new HashMap<>();
    private volatile Map<String, SuperCallBack> callbacks = new HashMap<>();
    /**
     * 保存需要进行超时检测的请求,这是一个延时队列,元素超时的时候会被取出来
     */
@@ -76,13 +76,19 @@
                timeoutExecutor.execute(new Runnable() {
                    @Override
                    public void run() {
                        LogUtil.d("任务超时轮询");
                        try {
                            // 只有超时的元素才会被取出,没有的话会被等待
                            timeoutItem item = timeoutQueue.take();
                            if (item != null) {
                                LogUtil.d("超时任务ID:" + item.callbackId);
                                SuperCallBack callBack = callbacks.remove(item.callbackId);
                                if (callBack != null)
                                if (callBack != null) {
                                    LogUtil.d("超时任务ID:" + item.callbackId + "callBack != null");
                                    callBack.onError(new RequestTimeOutException("request timeout"));
                                }else {
                                    LogUtil.d("超时任务ID:" + item.callbackId + "  callBack == null");
                                }
                            }
                        } catch (InterruptedException e) {
                            e.printStackTrace();
local.properties
@@ -4,6 +4,6 @@
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Tue Feb 27 10:36:34 CST 2024
sdk.dir=D\:\\AndroidStudio\\sdk
#Fri Mar 15 09:00:13 CST 2024
ndk.dir=D\:\\android\\sdk\\ndk\\android-ndk-r21
sdk.dir=D\:\\android\\sdk