feat(nfc): 新增用户卡写入功能并优化开卡流程
- 新增用户卡写入功能,支持异步写卡- 优化开卡流程,增加订单号和用户信息传递
- 修复部分数据类型不匹配问题
- 优化异常处理和日志记录
| | |
| | | |
| | | private static NativeNfcWriteHelper helper; |
| | | |
| | | |
| | | public void setIntent(Intent intent) { |
| | | this.tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); |
| | | } |
| | |
| | | return helper; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 写卡 |
| | | * |
| | |
| | | MifareClassic mfc = MifareClassic.get(tag); |
| | | if (null != mfc) { |
| | | try { |
| | | //连接NFC |
| | | // 连接NFC |
| | | mfc.connect(); |
| | | //验证扇区密码 |
| | | // 验证扇区密码 |
| | | boolean isOpen = false; |
| | | for (int i = 0; i < listKeyA.size(); i++) { |
| | | if (mfc.authenticateSectorWithKeyA(a, listKeyA.get(i))) { |
| | | isOpen = true; |
| | | if (listKeyA.get(i).equals(defauleKey)) { |
| | | //当前为默认白卡密码时写卡时修改密码 |
| | | // 当前为默认白卡密码时写卡时修改密码 |
| | | changePasword(a, mfc); |
| | | } |
| | | break; |
| | |
| | | data = userCard.getTwoBytes(); |
| | | } |
| | | int bIndex = mfc.sectorToBlock(a); |
| | | //写卡 |
| | | // 写卡 |
| | | mfc.writeBlock(bIndex + b, data); |
| | | } |
| | | return true; |
| | |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * 写卡(带回调) |
| | | * |
| | | * @param userCard 用户卡内容 |
| | | * @param sector 扇区 |
| | | * @param callBack 回调接口 |
| | | */ |
| | | public boolean writeUserData(BaseUserCardCard userCard, int sector, NFCCallBack callBack) { |
| | | if (userCard != null) { |
| | | int a = sector; |
| | | try { |
| | | MifareClassic mfc = MifareClassic.get(tag); |
| | | if (null != mfc) { |
| | | try { |
| | | // 连接NFC |
| | | mfc.connect(); |
| | | // 验证扇区密码 |
| | | boolean isOpen = false; |
| | | for (int i = 0; i < listKeyA.size(); i++) { |
| | | if (mfc.authenticateSectorWithKeyA(a, listKeyA.get(i))) { |
| | | isOpen = true; |
| | | if (listKeyA.get(i).equals(defauleKey)) { |
| | | // 当前为默认白卡密码时写卡时修改密码 |
| | | changePasword(a, mfc); |
| | | } |
| | | break; |
| | | } |
| | | } |
| | | 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); |
| | | } |
| | | if (callBack != null) { |
| | | callBack.isSusses(true, "用户数据写入成功"); |
| | | } |
| | | return true; |
| | | } |
| | | if (callBack != null) { |
| | | callBack.isSusses(false, "扇区" + a + "密码验证失败"); |
| | | } |
| | | return false; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | if (callBack != null) { |
| | | callBack.isSusses(false, "扇区" + a + "写卡异常: " + e.getMessage()); |
| | | } |
| | | return false; |
| | | } finally { |
| | | try { |
| | | mfc.close(); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | if (callBack != null) { |
| | | callBack.isSusses(false, "写卡异常: " + e.getMessage()); |
| | | } |
| | | return false; |
| | | } |
| | | } else { |
| | | if (callBack != null) { |
| | | callBack.isSusses(false, "用户卡数据为空"); |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * 写卡 |
| | |
| | | MifareClassic mfc = MifareClassic.get(tag); |
| | | if (null != mfc) { |
| | | try { |
| | | //连接NFC |
| | | // 连接NFC |
| | | if (isConnect) { |
| | | mfc.connect(); |
| | | } |
| | | //获取扇区数量 |
| | | // 获取扇区数量 |
| | | int count = mfc.getSectorCount(); |
| | | //如果传进来的扇区大了或者小了直接退出方法 |
| | | // 如果传进来的扇区大了或者小了直接退出方法 |
| | | if (a > count - 1 || a < 0) { |
| | | if (callBack != null) { |
| | | callBack.isSusses(false, "扇区错误--" + a); |
| | | } |
| | | return false; |
| | | } |
| | | //获取写的扇区的块的数量 |
| | | // 获取写的扇区的块的数量 |
| | | int bCount = mfc.getBlockCountInSector(a); |
| | | //如果输入的块大了或者小了也是直接退出 |
| | | // 如果输入的块大了或者小了也是直接退出 |
| | | if (b > bCount - 1 || b < 0) { |
| | | if (callBack != null) { |
| | | callBack.isSusses(false, "块区错误--" + b); |
| | | } |
| | | return false; |
| | | } |
| | | //验证扇区密码 |
| | | // 验证扇区密码 |
| | | boolean isOpen = false; |
| | | if (listKeyA.size() != 0) { |
| | | for (int i = 0; i < listKeyA.size(); i++) { |
| | | if (mfc.authenticateSectorWithKeyA(0, listKeyA.get(i))) { |
| | | isOpen = true; |
| | | if (listKeyA.get(i).equals(defauleKey)) { |
| | | //当前为默认白卡密码时写卡时修改密码 |
| | | // 当前为默认白卡密码时写卡时修改密码 |
| | | changePasword(a, mfc); |
| | | } |
| | | break; |
| | |
| | | } |
| | | if (isOpen) { |
| | | int bIndex = mfc.sectorToBlock(a); |
| | | //写卡 |
| | | // 写卡 |
| | | mfc.writeBlock(bIndex + b, str); |
| | | // 校验写入数据是否正确 |
| | | boolean isVerified = true; |
| | |
| | | return false; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 修改密码 |
| | | * |
| | | * @param 书写的扇区 |
| | | * @param 书写的扇区 |
| | | * @param passWord 密码 |
| | | * @return |
| | | */ |
| | | public boolean changePasword( List<byte[]> passWord, boolean isConnect, boolean isClose, NFCCallBack callBack) { |
| | | if (passWord == null || passWord.size()!=16) { |
| | | public boolean changePasword(List<byte[]> passWord, boolean isConnect, boolean isClose, NFCCallBack callBack) { |
| | | if (passWord == null || passWord.size() != 16) { |
| | | if (callBack != null) { |
| | | callBack.isSusses(false, "密码数组为空或长度不为16"); |
| | | } |
| | |
| | | mfc.connect(); |
| | | } |
| | | for (int i = 0; i < passWord.size(); i++) { |
| | | byte [] passWordItem = passWord.get(i); |
| | | byte[] passWordItem = passWord.get(i); |
| | | // 验证扇区密码 |
| | | boolean isAuthenticated = false; |
| | | |
| | |
| | | /** |
| | | * 修改密码 |
| | | * |
| | | * @param a 扇区 |
| | | * @param a 扇区 |
| | | * @param mfc MifareClassic实例 |
| | | * @return |
| | | */ |
| | |
| | | byte[] data = new byte[16]; |
| | | if (null != mfc) { |
| | | try { |
| | | //将密码转换为keyA |
| | | // 将密码转换为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 |
| | | // 将密码转换为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); |
| | | |
| | | return true; |
| | |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 初始化卡 |
| | | * |
| | |
| | | MifareClassic mfc = MifareClassic.get(tag); |
| | | if (null != mfc) { |
| | | try { |
| | | //连接NFC |
| | | // 连接NFC |
| | | mfc.connect(); |
| | | //获取扇区数量 |
| | | // 获取扇区数量 |
| | | int count = mfc.getSectorCount(); |
| | | byte[] data = new byte[16]; |
| | | String initData = "FFFFFFFFFFFFFF078069FFFFFFFFFFFF"; |
| | | byte[] initDataBytes = HexUtil.hexToByteArray(initData); |
| | | for (int sector = 0; sector < count; sector++) { |
| | | //验证扇区密码 |
| | | // 验证扇区密码 |
| | | boolean isOpen = false; |
| | | for (int i = 0; i < listKeyA.size(); i++) { |
| | | if (mfc.authenticateSectorWithKeyA(sector, listKeyA.get(i))) { |
| | |
| | | } |
| | | } |
| | | if (isOpen) { |
| | | //获取写的扇区的块的数量 |
| | | // 获取写的扇区的块的数量 |
| | | int blockCount = mfc.getBlockCountInSector(sector); |
| | | int blockIndex = mfc.sectorToBlock(sector); |
| | | for (int block = 0; block < blockCount; block++) { |
| | |
| | | } else { |
| | | mfc.writeBlock(blockIndex, initDataBytes); |
| | | } |
| | | //写卡 |
| | | // 写卡 |
| | | blockIndex++; |
| | | } |
| | | } |
| | |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | |
| | | } |
| | |
| | | } |
| | | |
| | | @Override |
| | | public boolean writeUserData(BaseUserCardCard userCard,int sector) { |
| | | public boolean writeUserData(BaseUserCardCard userCard, int sector) { |
| | | switch (BaseNfcActivity.adapterType) { |
| | | case ModelUtils.defaultType: |
| | | return nativeNfcWriteHelper.writeUserData(userCard, sector); |
| | | |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * 写用户数据(带回调) |
| | | * |
| | | * @param userCard 用户卡数据 |
| | | * @param sector 扇区 |
| | | * @param callBack 回调接口 |
| | | * @return 是否成功 |
| | | */ |
| | | public boolean writeUserData(BaseUserCardCard userCard, int sector, NFCCallBack callBack) { |
| | | switch (BaseNfcActivity.adapterType) { |
| | | case ModelUtils.defaultType: |
| | | return nativeNfcWriteHelper.writeUserData(userCard, sector, callBack); |
| | | } |
| | | return false; |
| | | } |
| | |
| | | public boolean writeData(byte[] str, int a, int b, NFCCallBack callBack) { |
| | | switch (BaseNfcActivity.adapterType) { |
| | | case ModelUtils.defaultType: |
| | | return nativeNfcWriteHelper.writeData(str, a, b,callBack); |
| | | return nativeNfcWriteHelper.writeData(str, a, b, callBack); |
| | | |
| | | } |
| | | return false; |
| | |
| | | public boolean writeData(byte[] str, int a, int b, boolean isConnect, NFCCallBack callBack) { |
| | | switch (BaseNfcActivity.adapterType) { |
| | | case ModelUtils.defaultType: |
| | | return nativeNfcWriteHelper.writeData(str, a, b,isConnect,callBack); |
| | | return nativeNfcWriteHelper.writeData(str, a, b, isConnect, callBack); |
| | | |
| | | } |
| | | return false; |
| | |
| | | return false; |
| | | } |
| | | |
| | | public boolean changePasword( List<byte[]> passWord, boolean isConnect, boolean isClose, NFCCallBack callBack) { |
| | | public boolean changePasword(List<byte[]> passWord, boolean isConnect, boolean isClose, NFCCallBack callBack) { |
| | | switch (BaseNfcActivity.adapterType) { |
| | | case ModelUtils.defaultType: |
| | | return nativeNfcWriteHelper.changePasword(passWord,isConnect, isClose,callBack); |
| | | return nativeNfcWriteHelper.changePasword(passWord, isConnect, isClose, callBack); |
| | | } |
| | | return false; |
| | | } |
| | |
| | | import com.dayu.baselibrary.view.TitleBar.ClickType_LEFT_IMAGE |
| | | import com.dayu.general.BaseApplication |
| | | import com.dayu.general.R |
| | | import com.dayu.general.bean.card.UserCard |
| | | import com.dayu.general.bean.db.CardRegistrationBean |
| | | import com.dayu.general.bean.net.ClientInfo |
| | | import com.dayu.general.bean.net.NewCardDataResult |
| | | import com.dayu.general.bean.net.PaymentMethod |
| | | import com.dayu.general.bean.net.PaymentMethodResponse |
| | | import com.dayu.general.dao.BaseDaoSingleton |
| | | import com.dayu.general.databinding.ActivityNewCardGeBinding |
| | | import com.dayu.general.net.ApiManager |
| | | import com.dayu.general.net.BaseResponse |
| | | import com.dayu.general.tool.CardCommon.Companion.USER_CARD_TYPE_1 |
| | | import com.dayu.general.tool.NfcReadHelper |
| | | import com.dayu.general.tool.NfcWreatHelper |
| | | import com.dayu.general.utils.DateUtils |
| | | import com.tencent.bugly.crashreport.CrashReport |
| | | import kotlinx.coroutines.launch |
| | | import java.util.Calendar |
| | | |
| | | /** |
| | | * Description: 用户开卡界面(同步修改白卡密码) |
| | |
| | | // 客户ID |
| | | private var clientId: String = "" |
| | | |
| | | private lateinit var clientInfo : ClientInfo |
| | | |
| | | // 是否已读卡 |
| | | private var isReadCard: Boolean = false |
| | | |
| | | private var orderId:String="" |
| | | |
| | | companion object { |
| | | private const val TAG = "NewCard2Activity" |
| | | } |
| | | |
| | | // 支付方式数据类 |
| | | data class PaymentMethod( |
| | | val id: Long, |
| | | val name: String, |
| | | val remarks: String, |
| | | val deleted: Int |
| | | ) |
| | | |
| | | // 支付方式接口返回数据类 |
| | | data class PaymentMethodResponse( |
| | | val itemTotal: Any?, |
| | | val obj: List<PaymentMethod>, |
| | | val pageCurr: Any?, |
| | | val pageSize: Any?, |
| | | val pageTotal: Any? |
| | | ) |
| | | |
| | | // 用户信息数据类 |
| | | data class ClientInfo( |
| | | val clientId: String, |
| | | val clientNum: String, |
| | | val name: String, |
| | | val districtNum: String, |
| | | val phone: String, |
| | | val idCard: String, |
| | | val villageName: String, |
| | | val address: String, |
| | | val cardCount: Int, |
| | | val operateDt: String |
| | | ) |
| | | |
| | | override fun onCreate(savedInstanceState: Bundle?) { |
| | | super.onCreate(savedInstanceState) |
| | |
| | | object : SubscriberListener<BaseResponse<ClientInfo>>() { |
| | | override fun onNext(response: BaseResponse<ClientInfo>) { |
| | | if (response.success) { |
| | | val clientInfo = response.content |
| | | clientInfo = response.content!! |
| | | if (clientInfo != null) { |
| | | // 显示客户信息到界面 |
| | | displayClientInfo(clientInfo) |
| | |
| | | // 构建请求参数 |
| | | val params = HashMap<String, Any>() |
| | | params["cardAddr"] = cardPhysicalId // 水卡地址(物理ID) |
| | | params["clientNum"] = binding.newCardFarmerCode.text.toString() // 农户编号 |
| | | params["cardCost"] = (cardFee * 100).toInt() // 购卡金额(工本费)转为分 |
| | | params["amount"] = (rechargeAmount * 100).toInt() // 充值金额转为分 |
| | | params["clientId"] = clientId // 农户ID |
| | | params["cardCost"] = cardFee // 购卡金额(工本费)(元) |
| | | params["amount"] = rechargeAmount // 充值金额(元) |
| | | params["paymentId"] = paymentId // 支付方式ID |
| | | params["remarks"] = remark // 备注 |
| | | params["protocol"] = "p206V1_0_1" // 协议 |
| | | params["operator"] = BaseApplication.userId // 操作人ID |
| | | |
| | | // 执行卡片激活API请求 |
| | | ApiManager.getInstance().requestPostLoading( |
| | | this, |
| | | "sell/card/active", |
| | | String::class.java, |
| | | "terminal/card/termActiveCard", |
| | | NewCardDataResult::class.java, |
| | | params, |
| | | object : SubscriberListener<BaseResponse<String>>() { |
| | | override fun onNext(response: BaseResponse<String>) { |
| | | object : SubscriberListener<BaseResponse<NewCardDataResult>>() { |
| | | override fun onNext(response: BaseResponse<NewCardDataResult>) { |
| | | if (response.success) { |
| | | orderId=response.content?.orderNo.toString() |
| | | // 保存开卡信息到数据库 |
| | | val cardRegistration = CardRegistrationBean( |
| | | cardNumber = cardPhysicalId, |
| | | userName = binding.newCardUserName.text.toString(), |
| | | idCard = binding.newCardIdCard.text.toString(), |
| | | farmerCode = binding.newCardFarmerCode.text.toString(), |
| | | clientId = clientId, |
| | | cardFee = cardFee, |
| | | remark = binding.newCardRemark.text.toString(), |
| | | paymentMethod = paymentId.toInt(), |
| | | isReported = true, |
| | | isCardWritten = true |
| | | ) |
| | | isCardWritten = true, |
| | | operatorId = orderId, |
| | | |
| | | ) |
| | | |
| | | // 使用协程在后台线程中保存数据 |
| | | lifecycleScope.launch { |
| | | try { |
| | | BaseDaoSingleton.getInstance(this@NewCard2Activity) |
| | | .cardRegistrationDao().insert(cardRegistration) |
| | | |
| | | Toast.makeText( |
| | | this@NewCard2Activity, |
| | | "开卡成功", |
| | | Toast.LENGTH_SHORT |
| | | ).show() |
| | | setResult(RESULT_OK) |
| | | finish() |
| | | Intent(this@NewCard2Activity, NfcWreatActivity::class.java).apply { |
| | | putExtra("cardType", USER_CARD_TYPE_1) |
| | | putExtra("orderId", orderId) |
| | | putExtra("cardAddr", cardPhysicalId) |
| | | var userCard = UserCard() |
| | | userCard.areaNumber =clientInfo.districtNum |
| | | userCard.userCode =clientInfo.clientNum |
| | | userCard.phoneNumber =clientInfo.phone |
| | | userCard.userCodeNumber = response.content?.cardNum?.toInt()!! |
| | | userCard.projectCode = response.content?.projectNo?.toInt()!! |
| | | userCard.balance = response.content?.balance?.toInt()!! |
| | | // userCard.surplusWater = response.content?.surplusWater?.toInt()!! |
| | | userCard.waterPrice = response.content?.waterPrice?.toFloat()!! |
| | | // userCard.electricPrice = response.content?.electricPrice?.toFloat()!! |
| | | userCard.rechargeDate = DateUtils.parseStringToCalendar(response.content?.time) |
| | | putExtra("userCard", userCard) |
| | | startActivity(this) |
| | | } |
| | | } catch (e: Exception) { |
| | | CrashReport.postCatchedException(e) |
| | | Toast.makeText( |
| | |
| | | package com.dayu.general.activity |
| | | package com.dayu.general.activity |
| | | |
| | | import android.content.Intent |
| | | import android.os.Bundle |
| | | import com.dayu.baselibrary.net.subscribers.SubscriberListener |
| | | import com.dayu.baselibrary.utils.ToastUtil |
| | | import com.dayu.general.bean.card.ClearCard |
| | | import com.dayu.general.bean.card.UserCard |
| | | import com.dayu.general.tool.CardCommon |
| | | import com.dayu.general.databinding.ActivityNfcWriteGeBinding |
| | | import com.dayu.general.net.ApiManager |
| | |
| | | var cardType = "" |
| | | var orderId = "" |
| | | var cardAddr = "" |
| | | private lateinit var userCard: UserCard |
| | | |
| | | override fun onCreate(savedInstanceState: Bundle?) { |
| | | super.onCreate(savedInstanceState) |
| | |
| | | cardType = intent?.getStringExtra("cardType") ?: "" |
| | | orderId = intent?.getStringExtra("orderId") ?: "" |
| | | cardAddr = intent?.getStringExtra("cardAddr") ?: "" |
| | | if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) { |
| | | userCard = intent?.getSerializableExtra("userCard", UserCard::class.java)!! |
| | | } else { |
| | | userCard = (intent?.getSerializableExtra("userCard") as? UserCard)!! |
| | | } |
| | | |
| | | if (cardType.isNotEmpty()) { |
| | | when (cardType) { |
| | | CardCommon.CLEAN_CARD_TYPE -> { |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | CardCommon.USER_CARD_TYPE_1 -> { |
| | | binding?.cardData?.text = "写用户卡" |
| | | nfcWreatHelper.writeUserData(userCard) |
| | | |
| | | } |
| | | } |
| | | } else { |
| | | ToastUtil.show("卡片错误,当前刷的卡与刚刚的卡不一致") |
| | |
| | | */ |
| | | class UserCard : BaseUserCardCard(), Serializable { |
| | | var cardType: String = USER_CARD_TYPE_1 // 卡类型:A1终端写卡 A8刷卡开泵后值 A2叠加充值 |
| | | var areaNumber: Int = 0 // 国家行政区域号(12位BCD,精确到村) |
| | | var areaNumber: String = "" // 国家行政区域号(12位BCD,精确到村) |
| | | var userCode: String = "" // 用户编号BCD |
| | | var userCodeNumber: Int = 0 // 用户卡编号(HEX) |
| | | var phoneNumber: String = "" // 手机号(BCD) |
| | |
| | | userCard.apply { |
| | | // 解析国家行政区域号(0-5位) |
| | | val areaCodeBytes = zero.copyOfRange(0, 6) |
| | | areaNumber = BcdUtil.bcdToStr(areaCodeBytes).toInt() |
| | | areaNumber = BcdUtil.bcdToStr(areaCodeBytes) |
| | | |
| | | // 解析用户卡编号(6-7位) |
| | | val userCodeNumberBytes = zero.copyOfRange(6, 8) |
| | |
| | | val cardNumber: String, // IC卡卡号 |
| | | val userName: String, // 姓名 |
| | | val idCard: String, // 身份证号 |
| | | val farmerCode: String, // 农户编号 |
| | | val clientId: String, // 农户Id |
| | | val cardFee: Double, // 工本费 |
| | | val remark: String, // 备注 |
| | | val paymentMethod: Int, // 支付方式 |
New file |
| | |
| | | package com.dayu.general.bean.net |
| | | |
| | | // 支付方式数据类 |
| | | data class PaymentMethod( |
| | | val id: Long, |
| | | val name: String, |
| | | val remarks: String, |
| | | val deleted: Int |
| | | ) |
| | | |
| | | // 支付方式接口返回数据类 |
| | | data class PaymentMethodResponse( |
| | | val itemTotal: Any?, |
| | | val obj: List<PaymentMethod>, |
| | | val pageCurr: Any?, |
| | | val pageSize: Any?, |
| | | val pageTotal: Any? |
| | | ) |
| | | |
| | | // 用户信息数据类 |
| | | data class ClientInfo( |
| | | val clientId: String, |
| | | val clientNum: String, |
| | | val name: String, |
| | | val districtNum: String, |
| | | val phone: String, |
| | | val idCard: String, |
| | | val villageName: String, |
| | | val address: String, |
| | | val cardCount: Int, |
| | | val operateDt: String |
| | | ) |
New file |
| | |
| | | package com.dayu.general.bean.net |
| | | |
| | | data class NewCardDataResult( |
| | | var projectNo: String, |
| | | var cardNum: String, |
| | | var balance: String, |
| | | var waterPrice: String, |
| | | var time: String, |
| | | var orderNo: String |
| | | ) |
| | |
| | | } |
| | | |
| | | /** |
| | | * 写卡(异步) |
| | | * |
| | | * @param userCard 用户卡内容 |
| | | * @param callBack 操作结果和消息回调 |
| | | */ |
| | | fun writeUserDataAsync(userCard: UserCard, callBack: NFCCallBack): Disposable { |
| | | showLoading() |
| | | val disposable = Observable.fromCallable { |
| | | writeUserData(userCard, callBack) |
| | | } |
| | | .subscribeOn(Schedulers.io()) |
| | | .observeOn(AndroidSchedulers.mainThread()) |
| | | .subscribe({ result -> |
| | | hideLoading() |
| | | // 结果已经在writeUserData中通过callBack回调了 |
| | | }, { error -> |
| | | hideLoading() |
| | | error.printStackTrace() |
| | | callBack.isSusses(false, "异步写卡异常: ${error.message}") |
| | | }) |
| | | |
| | | compositeDisposable.add(disposable) |
| | | return disposable |
| | | } |
| | | |
| | | /** |
| | | * 写卡 |
| | | * |
| | | * @param userCard 用户卡内容 |
| | |
| | | } |
| | | |
| | | /** |
| | | * 写卡 |
| | | * |
| | | * @param userCard 用户卡内容 |
| | | * @param callBack 回调接口 |
| | | */ |
| | | fun writeUserData(userCard: UserCard, callBack: NFCCallBack): Boolean { |
| | | try { |
| | | return adapter.writeUserData(userCard, 7, callBack) |
| | | } catch (e: java.lang.Exception) { |
| | | e.printStackTrace() |
| | | callBack.isSusses(false, "写卡异常: ${e.message}") |
| | | } |
| | | return false |
| | | } |
| | | |
| | | /** |
| | | * 修改密码(异步) |
| | | * |
| | | * @param ps 密码列表 |
New file |
| | |
| | | package com.dayu.general.utils |
| | | |
| | | import java.text.SimpleDateFormat |
| | | import java.util.Calendar |
| | | import java.util.Locale |
| | | |
| | | object DateUtils { |
| | | |
| | | private const val DATE_PATTERN = "yyyy-MM-dd HH:mm:ss" |
| | | private val sdf by lazy { SimpleDateFormat(DATE_PATTERN, Locale.getDefault()) } |
| | | |
| | | /** |
| | | * 将字符串转换为 Calendar 对象 |
| | | * @param dateStr 时间字符串,格式:yyyy-MM-dd HH:mm:ss |
| | | * @return 解析后的 Calendar 对象,失败返回 null |
| | | */ |
| | | fun parseStringToCalendar(dateStr: String?): Calendar? { |
| | | if (dateStr.isNullOrEmpty()) return null |
| | | return try { |
| | | val date = sdf.parse(dateStr) |
| | | val calendar = Calendar.getInstance() |
| | | calendar.time = date ?: return null |
| | | calendar |
| | | } catch (e: Exception) { |
| | | e.printStackTrace() |
| | | null |
| | | } |
| | | } |
| | | |
| | | } |