| | |
| | | # Location of the SDK. This is only used by Gradle. |
| | | # For customization when using a Version Control System, please read the |
| | | # header note. |
| | | #Mon Aug 12 12:34:59 CST 2024 |
| | | sdk.dir=D\:\\AndroidStudio\\sdk |
| | | #Mon Aug 19 09:59:12 CST 2024 |
| | | sdk.dir=D\:\\android\\sdk |
| | |
| | | <activity |
| | | android:name=".activity.CardSearchActivity" |
| | | android:launchMode="singleTop" /> |
| | | <activity |
| | | android:name="com.dayu.qiheonlinelibrary.activity.InitialuzeActivity" |
| | | android:exported="true" |
| | | android:launchMode="singleTop"> |
| | | <intent-filter> |
| | | <action android:name="android.nfc.action.ACTION_NDEF_DISCOVERED" /> |
| | | <category android:name="android.intent.category.DEFAULT" /> |
| | | <data android:mimeType="text/plain" /> |
| | | </intent-filter> |
| | | </activity> |
| | | </application> |
| | | |
| | | </manifest> |
New file |
| | |
| | | package com.dayu.qiheonlinelibrary.activity; |
| | | |
| | | import android.content.Intent; |
| | | import android.nfc.NfcAdapter; |
| | | import android.os.Bundle; |
| | | import android.view.LayoutInflater; |
| | | import android.view.View; |
| | | |
| | | import com.dayu.baselibrary.utils.TipUtil; |
| | | import com.dayu.qiheonlinelibrary.databinding.ActivityInitQhlBinding; |
| | | import com.dayu.qiheonlinelibrary.tools.NFCWriteHelper; |
| | | import com.dayu.qiheonlinelibrary.view.ProgressDialog; |
| | | |
| | | /** |
| | | * author: zuo |
| | | * Date: 2024-08-20 |
| | | * Time: 15:59 |
| | | * 备注: |
| | | */ |
| | | public class InitialuzeActivity extends BaseNfcActivity { |
| | | |
| | | ActivityInitQhlBinding binding; |
| | | Intent intent; |
| | | |
| | | @Override |
| | | protected void onCreate(Bundle savedInstanceState) { |
| | | super.onCreate(savedInstanceState); |
| | | binding = ActivityInitQhlBinding.inflate(LayoutInflater.from(this)); |
| | | setContentView(binding.getRoot()); |
| | | |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public void onNewIntent(Intent intent) { |
| | | this.intent = intent; |
| | | binding.avi.setVisibility(View.VISIBLE); |
| | | if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) { |
| | | if (NFCWriteHelper.getInstence(intent, this).initCard()) { |
| | | TipUtil.show(this, "格式化成功!", () -> InitialuzeActivity.this.finish()); |
| | | binding.avi.hide(); |
| | | } |
| | | } |
| | | super.onNewIntent(intent); |
| | | } |
| | | |
| | | |
| | | } |
| | |
| | | import android.view.LayoutInflater; |
| | | import android.view.View; |
| | | |
| | | import com.dayu.baselibrary.tools.HexUtil; |
| | | import com.dayu.baselibrary.utils.MornyUtil; |
| | | import com.dayu.baselibrary.utils.TipUtil; |
| | | import com.dayu.baselibrary.view.ConfirmDialog; |
| | |
| | | import com.dayu.qiheonlinelibrary.card.DomainCard; |
| | | import com.dayu.qiheonlinelibrary.card.ElectricPriceCard; |
| | | import com.dayu.qiheonlinelibrary.card.ManageCard; |
| | | import com.dayu.qiheonlinelibrary.card.ManagerToUserCard; |
| | | import com.dayu.qiheonlinelibrary.card.RegionCard; |
| | | import com.dayu.qiheonlinelibrary.card.UserCard; |
| | | import com.dayu.qiheonlinelibrary.databinding.ActivityRedCardQhlBinding; |
| | | import com.dayu.qiheonlinelibrary.dbBean.AdminDataBean; |
| | | import com.dayu.qiheonlinelibrary.dbBean.UserCardBean; |
| | | import com.dayu.qiheonlinelibrary.net.ApiManager; |
| | | import com.dayu.qiheonlinelibrary.net.BaseResponse; |
| | | import com.dayu.qiheonlinelibrary.net.subscribers.SubscriberListener; |
| | | import com.dayu.qiheonlinelibrary.tools.NFCWriteHelper; |
| | | import com.dayu.qiheonlinelibrary.tools.NfcReadHelper; |
| | | import com.dayu.qiheonlinelibrary.utils.CardCommon; |
| | | import com.dayu.qiheonlinelibrary.view.ProgressDialog; |
| | | |
| | | |
| | | import java.util.Calendar; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | |
| | | if (!data.isEmpty()) { |
| | | if (!TextUtils.isEmpty(cardNumber)) { |
| | | userCard = UserCard.getBean(data); |
| | | getUserInfoAndCardInfo(cardNumber); |
| | | getUserInfoAndCardInfo(cardNumber,userCard.getMyUserCode()); |
| | | } else { |
| | | |
| | | } |
| | |
| | | * |
| | | * @param iccardCode |
| | | */ |
| | | public void getUserInfoAndCardInfo(String iccardCode) { |
| | | public void getUserInfoAndCardInfo(String iccardNum,String iccardCode) { |
| | | Map<String, Object> data = new HashMap<>(); |
| | | //ic卡信息id |
| | | data.put("iccardNum", iccardCode); |
| | | data.put("iccardNum", iccardNum); |
| | | data.put("iccardCode", iccardCode); |
| | | ApiManager.getInstance().requestPostLoading(this, "iccard/peasant/getIccardInfoVoByCardCode", CardInfoResult.class, data, new SubscriberListener<BaseResponse<CardInfoResult>>() { |
| | | @Override |
| | | public void onNext(BaseResponse<CardInfoResult> t) { |
| | |
| | | } |
| | | //获取卡内信息 |
| | | mOldUserCard = NfcReadHelper.getInstence(intent, this).getUserCardData(); |
| | | getUserInfoAndCardInfo(cardNumber); |
| | | getUserInfoAndCardInfo(cardNumber,mOldUserCard.getMyUserCode()); |
| | | |
| | | } |
| | | |
| | |
| | | * |
| | | * @param iccardCode |
| | | */ |
| | | public void getUserInfoAndCardInfo(String iccardCode) { |
| | | public void getUserInfoAndCardInfo(String iccardNum, String iccardCode) { |
| | | Map<String, Object> data = new HashMap<>(); |
| | | //ic卡信息id |
| | | data.put("iccardNum", iccardCode); |
| | | data.put("iccardNum", iccardNum); |
| | | data.put("iccardCode", iccardCode); |
| | | ApiManager.getInstance().requestPostLoading(this, "iccard/peasant/getIccardInfoVoByCardCode", CardInfoResult.class, data, new SubscriberListener<BaseResponse<CardInfoResult>>() { |
| | | @Override |
| | | public void onNext(BaseResponse<CardInfoResult> t) { |
| | |
| | | } |
| | | |
| | | }); |
| | | |
| | | //格式化卡 |
| | | adminBinding.adminInitCard.setOnClickListener(v -> { |
| | | Intent intent = new Intent(this, InitialuzeActivity.class); |
| | | startActivity(intent); |
| | | }); |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | |
| | | /** |
| | | * 返回完整的用户编号 |
| | | * |
| | | * @return |
| | | */ |
| | | public String getMyUserCode() { |
| | | return userCode + String.format("%04d", userCodeNumber); |
| | | // return ""; |
| | | } |
| | | |
| | | /** |
| | | * 通过byte转bean |
| | | * |
| | | * @param data |
| | |
| | | |
| | | byte[] arerNumberByte = new byte[4]; |
| | | System.arraycopy(zero, 1, arerNumberByte, 0, arerNumberByte.length); |
| | | userCard.arerNumber = HexUtil.get16To10LowHightByBytes(arerNumberByte); |
| | | userCard.arerNumber = HexUtil.get16To10LowHightByBytes(arerNumberByte); |
| | | byte[] userCodeByte = new byte[6]; |
| | | System.arraycopy(zero, 5, userCodeByte, 0, userCodeByte.length); |
| | | userCard.userCode= BcdUtil.bcdToStr(userCodeByte); |
| | | userCard.userCode = BcdUtil.bcdToStr(userCodeByte); |
| | | byte[] userCodeNumber = new byte[2]; |
| | | System.arraycopy(zero, 11, userCodeNumber, 0, userCodeNumber.length); |
| | | userCard.userCodeNumber=HexUtil.get16To10LowHightByBytes(userCodeNumber); |
| | | userCard.userCodeNumber = HexUtil.get16To10LowHightByBytes(userCodeNumber); |
| | | byte[] cardWriteState = new byte[1]; |
| | | System.arraycopy(zero, 13, cardWriteState, 0, cardWriteState.length); |
| | | userCard.cardWriteState=HexUtil.get16To10LowHightByBytes(cardWriteState); |
| | | userCard.cardWriteState = HexUtil.get16To10LowHightByBytes(cardWriteState); |
| | | byte[] cardState = new byte[1]; |
| | | System.arraycopy(zero, 14, cardState, 0, cardState.length); |
| | | userCard.cardState=HexUtil.get16To10LowHightByBytes(cardState); |
| | | userCard.cardState = HexUtil.get16To10LowHightByBytes(cardState); |
| | | //第1块解析 |
| | | byte[] one = data.get(1); |
| | | byte[] balanceByte = new byte[4]; |
| | | System.arraycopy(one, 0, balanceByte, 0, balanceByte.length); |
| | | userCard.balance =HexUtil.get16To10LowHightByBytes(balanceByte); |
| | | userCard.balance = HexUtil.get16To10LowHightByBytes(balanceByte); |
| | | |
| | | byte[] surplusWaterByte = new byte[4]; |
| | | System.arraycopy(one, 4, surplusWaterByte, 0, surplusWaterByte.length); |
| | |
| | | * 公司密码 |
| | | */ |
| | | public byte[] companyKey; |
| | | |
| | | //齐河欧标密码 |
| | | public byte[] companyKey2; |
| | | //密码a区 |
| | | String companyKeyA; |
| | | //密码B区 |
| | |
| | | //decryptedBytes3 对应202311202048 |
| | | companyKeyB = new String(decryptedBytes2, StandardCharsets.UTF_8); |
| | | |
| | | |
| | | //010203:qeg4DUWf0ni9JfRWtD2krA== |
| | | byte[] encryptedBytes4 = Base64.decode("qeg4DUWf0ni9JfRWtD2krA==", Base64.DEFAULT); |
| | | byte[] decryptedBytes4 = cipher.doFinal(encryptedBytes4); |
| | | String companyKeyA = new String(decryptedBytes4, StandardCharsets.UTF_8); |
| | | companyKey2 = HexUtil.hexToByteArray(companyKeyA); |
| | | } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | |
| | | BadPaddingException | IllegalBlockSizeException e) { |
| | | e.printStackTrace(); |
| | |
| | | } |
| | | |
| | | /** |
| | | * 初始化卡 |
| | | * |
| | | * @return |
| | | */ |
| | | public boolean initCard() { |
| | | try { |
| | | MifareClassic mfc = MifareClassic.get(tag); |
| | | if (null != mfc) { |
| | | try { |
| | | //连接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 = mfc.authenticateSectorWithKeyA(sector, defauleKey); |
| | | if (!isOpen) { |
| | | isOpen = mfc.authenticateSectorWithKeyA(sector, companyKey2); |
| | | if (isOpen){ |
| | | mfc.authenticateSectorWithKeyB(sector, companyKey2); |
| | | } |
| | | } |
| | | if (!isOpen) { |
| | | isOpen = mfc.authenticateSectorWithKeyA(sector, companyKey); |
| | | if (isOpen){ |
| | | mfc.authenticateSectorWithKeyB(sector, companyKey); |
| | | } |
| | | } |
| | | if (isOpen) { |
| | | //获取写的扇区的块的数量 |
| | | int blockCount = mfc.getBlockCountInSector(sector); |
| | | int blockIndex = mfc.sectorToBlock(sector); |
| | | for (int block = 0; block < blockCount ; block++) { |
| | | // 跳过第 0 扇区的第 0 块 |
| | | if (sector == 0 && block == 0) { |
| | | blockIndex++; |
| | | continue; |
| | | } |
| | | |
| | | if (block < 3) { |
| | | mfc.writeBlock(blockIndex, data); |
| | | } else { |
| | | mfc.writeBlock(blockIndex, initDataBytes); |
| | | } |
| | | //写卡 |
| | | |
| | | blockIndex++; |
| | | } |
| | | } |
| | | } |
| | | return true; |
| | | } 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; |
| | | } |
| | | |
| | | /** |
| | | * 返回监听类 |
| | | */ |
| | | public interface NFCCallback { |
| | |
| | | android:visibility="visible" |
| | | android:textColor="@color/text_selecter_color" |
| | | android:textSize="@dimen/text_size" /> |
| | | |
| | | <TextView |
| | | android:id="@+id/admin_initCard" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="wrap_content" |
| | | android:layout_marginLeft="20dp" |
| | | android:layout_marginTop="20dp" |
| | | android:padding="5dp" |
| | | android:text="格式化卡" |
| | | android:visibility="visible" |
| | | android:textColor="@color/text_selecter_color" |
| | | android:textSize="@dimen/text_size" /> |
| | | </LinearLayout> |
| | | |
| | | |
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?> |
| | | <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
| | | xmlns:app="http://schemas.android.com/apk/res-auto" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="match_parent" |
| | | android:orientation="vertical"> |
| | | |
| | | <com.dayu.baselibrary.view.TitleBar |
| | | android:id="@+id/titleBar" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="@dimen/dimen_title_height" |
| | | android:background="@color/title_bar_bg" |
| | | app:centerText="格式化卡片" |
| | | app:leftImage="@mipmap/icon_back" /> |
| | | |
| | | <LinearLayout |
| | | android:id="@+id/read_imgLL" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="match_parent" |
| | | android:layout_below="@id/titleBar" |
| | | android:background="#ffffff" |
| | | android:orientation="vertical" |
| | | android:visibility="visible"> |
| | | |
| | | <TextView |
| | | android:layout_width="match_parent" |
| | | android:layout_height="wrap_content" |
| | | android:layout_below="@id/titleBar" |
| | | android:layout_marginTop="20dp" |
| | | android:gravity="center" |
| | | android:text="请将卡贴在设备上进行格式化" |
| | | android:textSize="@dimen/text_size" /> |
| | | |
| | | |
| | | <ImageView |
| | | android:layout_width="match_parent" |
| | | android:layout_height="match_parent" |
| | | android:layout_below="@id/textView" |
| | | android:scaleType="fitCenter" |
| | | android:src="@mipmap/nfc_write" /> |
| | | </LinearLayout> |
| | | |
| | | <com.wang.avi.AVLoadingIndicatorView |
| | | android:id="@+id/avi" |
| | | style="@style/AVLoadingIndicatorView" |
| | | android:layout_width="80dp" |
| | | android:layout_height="80dp" |
| | | android:layout_centerHorizontal="true" |
| | | android:layout_centerVertical="true" |
| | | android:visibility="invisible" |
| | | app:indicatorColor="@color/title_bg" |
| | | app:indicatorName="BallClipRotatePulseIndicator" /> |
| | | </RelativeLayout> |