本示例使用的发卡器:
https://item.taobao.com/item.htm?id=615391857885&spm=a1z10.5-c-s.w4002-21818769070.11.66af789eLeok2R
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="3dp"
tools:context=".IcCardActivity">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="30dp"
android:background="?attr/colorPrimary"
app:navigationIcon="@drawable/baseline_arrow_back_ios_24"
app:titleTextColor="@color/white"
tools:ignore="MissingConstraints"
tools:layout_editor_absoluteY="0dp">
<TextView
android:id="@+id/TextViewlabelDispleft"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="返回"
android:textColor="@color/white"
android:textSize="16sp"
android:gravity="center"
android:onClick="retmain" />
<TextView
android:id="@+id/TextViewlabelDisp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="IC卡测试页"
android:textColor="@color/white"
android:gravity="center_horizontal|bottom"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/TextViewlabelDispleft"
app:layout_constraintTop_toTopOf="parent" />
</androidx.appcompat.widget.Toolbar>
<TextView
android:id="@+id/sample_text"
android:layout_width="fill_parent"
android:layout_height="150dp"
android:padding="3dp"
android:text="操作结果"
android:textSize="12sp"
android:background="@drawable/shape4border"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
<ScrollView
android:id="@+id/scrollViewIC"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_marginBottom="3dp"
android:scrollbars="horizontal"
app:layout_constraintBottom_toTopOf="@+id/sample_text"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/toolbar"
app:layout_constraintVertical_bias="0.0">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="3dp">
<Button
android:id="@+id/btnPiccrequest"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:onClick="piccrequest"
android:padding="3dp"
android:text="读取IC卡卡号"
android:textSize="12sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<TextView
android:id="@+id/TextViewlabeluid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="UID:"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/btnPiccrequest"
app:layout_constraintLeft_toRightOf="@+id/btnPiccrequest"
app:layout_constraintTop_toTopOf="@+id/btnPiccrequest" />
<EditText
android:id="@+id/TextViewuid"
android:layout_width="75dp"
android:layout_height="wrap_content"
android:text=""
android:background="@drawable/shape4border"
android:digits="0123456789ABCDEFabcdef"
android:gravity="center"
android:textSize="14sp"
android:textColor="#FF0000"
app:layout_constraintBottom_toBottomOf="@+id/TextViewlabeluid"
app:layout_constraintLeft_toRightOf="@+id/TextViewlabeluid"
app:layout_constraintTop_toTopOf="@+id/TextViewlabeluid" />
<TextView
android:id="@+id/TextViewlabelconv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="转8H10D码:"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/TextViewuid"
app:layout_constraintLeft_toRightOf="@+id/TextViewuid"
app:layout_constraintTop_toTopOf="@+id/TextViewuid" />
<TextView
android:id="@+id/TextViewlabel8h10d"
android:layout_width="95dp"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:background="@drawable/shape4border"
android:text=""
android:textSize="14sp"
android:gravity="center"
android:textColor="#FF0000"
app:layout_constraintBottom_toBottomOf="@+id/TextViewlabelconv"
app:layout_constraintLeft_toRightOf="@+id/TextViewlabelconv"
app:layout_constraintTop_toTopOf="@+id/TextViewlabelconv" />
<Button
android:id="@+id/btnwriteuid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:textSize="12sp"
android:onClick="piccwriteserial"
android:text="将上面UID号写入到CUID卡内"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnPiccrequest" />
<Button
android:id="@+id/butt_writekeytoe2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:textSize="12sp"
android:onClick="writekeytoe2"
android:text="将下面的卡片认证密钥装载到发卡器内部芯片,使密钥不外泄"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnwriteuid" />
<TextView
android:id="@+id/TextViewlabelArea"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:text="选择读写区号:"
android:textSize="12sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/butt_writekeytoe2" />
<Spinner
android:id="@+id/SpinnerArea"
android:layout_width="130dp"
android:layout_height="wrap_content"
android:entries="@array/AreaNumber"
android:spinnerMode="dropdown"
android:theme="@style/my_spinner_style"
app:layout_constraintBottom_toBottomOf="@+id/TextViewlabelArea"
app:layout_constraintLeft_toRightOf="@+id/TextViewlabelArea"
app:layout_constraintTop_toTopOf="@+id/TextViewlabelArea" />
<TextView
android:id="@+id/TextViewlabelkeymodel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginTop="5dp"
android:text="密钥方式:"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/SpinnerArea"
app:layout_constraintLeft_toRightOf="@+id/SpinnerArea"
app:layout_constraintTop_toTopOf="@+id/SpinnerArea" />
<Spinner
android:id="@+id/SpinnerInOutKey"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="2dp"
android:entries="@array/M1InOutKey"
android:spinnerMode="dropdown"
android:theme="@style/my_spinner_style"
app:layout_constraintBottom_toBottomOf="@+id/TextViewlabelkeymodel"
app:layout_constraintLeft_toRightOf="@+id/TextViewlabelkeymodel"
app:layout_constraintTop_toTopOf="@+id/TextViewlabelkeymodel" />
<TextView
android:id="@+id/TextViewlabelSelABkey"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="密钥认证类型:"
android:textSize="12sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/TextViewlabelArea" />
<Spinner
android:id="@+id/SpinnerSelABKey"
android:layout_width="130dp"
android:layout_height="wrap_content"
android:entries="@array/M1AuthABKey"
android:spinnerMode="dropdown"
android:theme="@style/my_spinner_style"
app:layout_constraintBottom_toBottomOf="@+id/TextViewlabelSelABkey"
app:layout_constraintLeft_toRightOf="@+id/TextViewlabelSelABkey"
app:layout_constraintTop_toTopOf="@+id/TextViewlabelSelABkey" />
<TextView
android:id="@+id/TextViewlabelkey"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginTop="5dp"
android:text="认证密钥:"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/SpinnerSelABKey"
app:layout_constraintLeft_toRightOf="@+id/SpinnerSelABKey"
app:layout_constraintTop_toTopOf="@+id/SpinnerSelABKey" />
<EditText
android:id="@+id/EdittextAuthkey"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:background="@drawable/shape4border"
android:digits="0123456789ABCDEFabcdef"
android:gravity="center"
android:textSize="12sp"
android:maxLength="12"
android:textColor="#0000FF"
android:text="FFFFFFFFFFFF"
app:layout_constraintBottom_toBottomOf="@+id/TextViewlabelkey"
app:layout_constraintLeft_toRightOf="@+id/TextViewlabelkey"
app:layout_constraintTop_toTopOf="@+id/TextViewlabelkey" />
<Button
android:id="@+id/btnPiccreadex"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:onClick="piccreadex"
android:textSize="12sp"
android:text="轻松读取选定扇区数据"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/TextViewlabelSelABkey" />
<Button
android:id="@+id/btnPiccwriteex"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="piccwriteex"
android:text="轻松写数据到选定扇区"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/btnPiccreadex"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@+id/btnPiccreadex" />
<TextView
android:id="@+id/TextViewlabelblock0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="第0块:"
android:textSize="12sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnPiccreadex" />
<EditText
android:id="@+id/Edittextblock0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:background="@drawable/shape4border"
android:digits="0123456789ABCDEFabcdef "
android:gravity="left"
android:maxLength="47"
android:text="00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/TextViewlabelblock0"
app:layout_constraintLeft_toRightOf="@+id/TextViewlabelblock0"
app:layout_constraintTop_toTopOf="@+id/TextViewlabelblock0" />
<TextView
android:id="@+id/TextViewlabelblock1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="第1块:"
android:textSize="12sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/TextViewlabelblock0" />
<EditText
android:id="@+id/Edittextblock1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:background="@drawable/shape4border"
android:digits="0123456789ABCDEFabcdef "
android:gravity="left"
android:maxLength="47"
android:text="00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/TextViewlabelblock1"
app:layout_constraintLeft_toRightOf="@+id/TextViewlabelblock1"
app:layout_constraintTop_toTopOf="@+id/TextViewlabelblock1" />
<TextView
android:id="@+id/TextViewlabelblock2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="第2块:"
android:textSize="12sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/TextViewlabelblock1" />
<EditText
android:id="@+id/Edittextblock2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:background="@drawable/shape4border"
android:digits="0123456789ABCDEFabcdef "
android:gravity="left"
android:maxLength="47"
android:text="00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/TextViewlabelblock2"
app:layout_constraintLeft_toRightOf="@+id/TextViewlabelblock2"
app:layout_constraintTop_toTopOf="@+id/TextViewlabelblock2" />
<TextView
android:id="@+id/TextViewlabelblock3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="第3块:"
android:textSize="12sp"
android:textColor="#0000FF"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/TextViewlabelblock2" />
<EditText
android:id="@+id/Edittextblock3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:background="@drawable/shape4border"
android:digits="0123456789ABCDEFabcdef "
android:gravity="left"
android:maxLength="47"
android:textColor="#0000FF"
android:text="FF FF FF FF FF FF FF 07 80 69 FF FF FF FF FF FF"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/TextViewlabelblock3"
app:layout_constraintLeft_toRightOf="@+id/TextViewlabelblock3"
app:layout_constraintTop_toTopOf="@+id/TextViewlabelblock3" />
<TextView
android:id="@+id/TextViewlabelnote4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:text="密钥块"
android:textSize="12sp"
android:textColor="#0000FF"
app:layout_constraintBottom_toBottomOf="@+id/Edittextblock3"
app:layout_constraintLeft_toRightOf="@+id/Edittextblock3"
app:layout_constraintTop_toTopOf="@+id/Edittextblock3" />
<Button
android:id="@+id/btnPiccchangesinglekeyex"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:onClick="piccchangesinglekeyex"
android:text="修改卡片密钥"
android:textSize="12sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/TextViewlabelblock3" />
<Spinner
android:id="@+id/SpinnerchangeKey"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="2dp"
android:entries="@array/M1changeKey"
android:spinnerMode="dropdown"
android:theme="@style/my_spinner_style"
app:layout_constraintBottom_toBottomOf="@+id/btnPiccchangesinglekeyex"
app:layout_constraintLeft_toRightOf="@+id/btnPiccchangesinglekeyex"
app:layout_constraintTop_toTopOf="@+id/btnPiccchangesinglekeyex" />
<TextView
android:id="@+id/TextViewlabelnewkeya"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="新A密钥:"
android:textSize="12sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnPiccchangesinglekeyex" />
<EditText
android:id="@+id/Edittextnewkeya"
android:layout_width="90dp"
android:layout_height="wrap_content"
android:background="@drawable/shape4border"
android:digits="0123456789ABCDEFabcdef"
android:gravity="center"
android:textSize="12sp"
android:maxLength="12"
android:textColor="#0000FF"
android:text="FFFFFFFFFFFF"
app:layout_constraintBottom_toBottomOf="@+id/TextViewlabelnewkeya"
app:layout_constraintLeft_toRightOf="@+id/TextViewlabelnewkeya"
app:layout_constraintTop_toTopOf="@+id/TextViewlabelnewkeya" />
<TextView
android:id="@+id/TextViewlabelctr"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:text="控制字:"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/Edittextnewkeya"
app:layout_constraintLeft_toRightOf="@+id/Edittextnewkeya"
app:layout_constraintTop_toTopOf="@+id/Edittextnewkeya" />
<EditText
android:id="@+id/Edittextnewctr"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:background="@drawable/shape4border"
android:digits="0123456789ABCDEFabcdef"
android:gravity="center"
android:textSize="12sp"
android:maxLength="8"
android:textColor="#0000FF"
android:text="FF078069"
app:layout_constraintBottom_toBottomOf="@+id/TextViewlabelctr"
app:layout_constraintLeft_toRightOf="@+id/TextViewlabelctr"
app:layout_constraintTop_toTopOf="@+id/TextViewlabelctr" />
<TextView
android:id="@+id/TextViewlabelnewkeyb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:text="B密钥:"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/Edittextnewctr"
app:layout_constraintLeft_toRightOf="@+id/Edittextnewctr"
app:layout_constraintTop_toTopOf="@+id/Edittextnewctr" />
<EditText
android:id="@+id/Edittextnewkeyb"
android:layout_width="90dp"
android:layout_height="wrap_content"
android:background="@drawable/shape4border"
android:digits="0123456789ABCDEFabcdef"
android:gravity="center"
android:textSize="12sp"
android:maxLength="12"
android:textColor="#0000FF"
android:text="FFFFFFFFFFFF"
app:layout_constraintBottom_toBottomOf="@+id/TextViewlabelnewkeyb"
app:layout_constraintLeft_toRightOf="@+id/TextViewlabelnewkeyb"
app:layout_constraintTop_toTopOf="@+id/TextViewlabelnewkeyb" />
<Button
android:id="@+id/btnPiccreadex1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:onClick="piccreadexevery200ms"
android:textSize="12sp"
android:text="启动连续每隔0.2秒读一次卡"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/TextViewlabelnewkeya" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
package com.usbreadertest;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import com.reader.ourmifare;
import java.util.Timer;
import java.util.TimerTask;
public class IcCardActivity extends AppCompatActivity {
private TextView tv;
private static final byte BLOCK0_EN = 0x01;
private static final byte BLOCK1_EN = 0x02;
private static final byte BLOCK2_EN = 0x04;
private static final byte NEEDSERIAL = 0x08;
private static final byte EXTERNKEY = 0x10;
private static final byte NEEDHALT = 0x20;
private long proctimes;
private Timer timer = null;
private TimerTask task = null;
private boolean iscontinue = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ic_card);
androidx.appcompat.widget.Toolbar toolbar=findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
tv = findViewById(R.id.sample_text);
tv.setText("操作结果");
Spinner ctrkeymod=findViewById(R.id.SpinnerInOutKey);
ctrkeymod.setSelection(1);
Spinner ctrselauth=findViewById(R.id.SpinnerSelABKey);
ctrselauth.setSelection(1);
}
@Override
public void onBackPressed(){
super.onBackPressed();
finish();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId()==android.R.id.home){
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
public void retmain(View view)
{
finish();
}
//读IC卡卡号
public void piccrequest(View view)
{
byte status;//存放返回值
byte[] mypiccserial = new byte[7];
long cardhao;
String strls;
EditText ctruid=findViewById(R.id.TextViewuid);
ctruid.setText("");
TextView ctr8h10d=findViewById(R.id.TextViewlabel8h10d);
ctr8h10d.setText("");
tv.setText("");
status = ourmifare.piccrequest(mypiccserial);
if(status == 0)
{
ourmifare.pcdbeep(38);
String serialnumber = "";
for (int i = 0; i < 4; i++) {
String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);
serialnumber = serialnumber + bytestr.substring(bytestr.length() - 2, bytestr.length());
}
serialnumber=serialnumber.toUpperCase();
ctruid.setText(serialnumber);
cardhao = mypiccserial[3] & 0xff;
cardhao *= 256;
cardhao += mypiccserial[2] & 0xff;
cardhao *= 256;
cardhao += mypiccserial[1] & 0xff;
cardhao *= 256;
cardhao += mypiccserial[0] & 0xff;
String strls1 = "000000000"+Long.toString(cardhao);//0305887634 123B7992
strls1=strls1.substring(strls1.length()-10,strls1.length());
ctr8h10d.setText(strls1);
strls = "读取成功!16进制卡号为:" +serialnumber+"\n转8H10D卡号:"+ strls1;
tv.setText(strls);
}
else
{
PrintErrInf(status);
}
}
public void piccwriteserial(View view){
byte status;//存放返回值
byte authmode;//密码类型,用A密码或B密码
byte myctrlword;//控制字
byte[] mypiccserial = new byte[4];//卡序列号
byte[] mypicckey = new byte[6];//密码
byte[] mypiccdata = new byte[48];//卡数据缓冲
byte[] myblockdata=new byte[16];//第三块数据
TextView ctr8h10d=findViewById(R.id.TextViewlabel8h10d);
ctr8h10d.setText("");
tv.setText("");
myctrlword = BLOCK0_EN ; //控制字指定,控制字的含义请查看本公司网站提供的动态库说明
Spinner ctrauthmode=findViewById(R.id.SpinnerInOutKey);
if (ctrauthmode.getSelectedItemId()==1){
myctrlword=(byte)(myctrlword + EXTERNKEY); //选用外部密钥认证
}
Spinner crtauthabkey=findViewById(R.id.SpinnerSelABKey);
authmode =(byte)crtauthabkey.getSelectedItemId(); //大于0表示用A密码认证,推荐用A密码认证
EditText ctrauthkey=findViewById(R.id.EdittextAuthkey); //认证密钥
String authkeystr=ctrauthkey.getText().toString().trim();
if (authkeystr.length()!=12){
tv.setText("认证密钥为12位16进制数,请输入正确的卡认证密钥!");
return;
}
for (int i=0;i<6;i++){
mypicckey[i]=(byte) Integer.parseInt(authkeystr.substring(i * 2, i * 2 + 2), 16);//只有用Integer.parseInt才能杜绝大于128时的错误
}
EditText ctruid=findViewById(R.id.TextViewuid);
String newuidstr=ctruid.getText().toString().trim();
if (newuidstr.length()!=8){
tv.setText("UID为8位16进制数,请输入正确的UID号!");
return;
}
byte edc=0;
for (int i=0;i<4;i++){
myblockdata[i]=(byte) Integer.parseInt(newuidstr.substring(i * 2, i * 2 + 2), 16);//只有用Integer.parseInt才能杜绝大于128时的错误
edc=(byte)(edc ^ myblockdata[i]); //UID校验字
}
myblockdata[4]=edc;
EditText ctrblock0=findViewById(R.id.Edittextblock0); //如果第0块显示有数据,将第0块的第5字节以后的数据也写入
String blockstr0=ctrblock0.getText().toString().trim();
String[] strArr= blockstr0.split("\\ "); /*分割接收到的数据后再分析、处理、返回指令 */
if (strArr.length==16){
for(int p=5;p<16;p++) {
myblockdata[p]=(byte)(Integer.parseInt(strArr[p],16));
}
}
status=ourmifare.piccwriteserial(myctrlword,mypiccserial,(byte)0,authmode,mypicckey,myblockdata);
if(status == 0)
{
status = ourmifare.piccrequest(mypiccserial);
if(status == 0)
{
ourmifare.pcdbeep(38);
String serialnumber = "";
for (int i = 0; i < 4; i++) {
String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);
serialnumber = serialnumber + bytestr.substring(bytestr.length() - 2, bytestr.length());
}
serialnumber=serialnumber.toUpperCase();
ctruid.setText(serialnumber);
long cardhao;
cardhao = mypiccserial[3] & 0xff;
cardhao *= 256;
cardhao += mypiccserial[2] & 0xff;
cardhao *= 256;
cardhao += mypiccserial[1] & 0xff;
cardhao *= 256;
cardhao += mypiccserial[0] & 0xff;
String strls1 = "000000000"+Long.toString(cardhao);//0305887634 123B7992
strls1=strls1.substring(strls1.length()-10,strls1.length());
ctr8h10d.setText(strls1);
String strls = "写UID卡号成功!16进制卡号为:" +serialnumber+"\n转8H10D卡号:"+ strls1;
tv.setText(strls);
}
else
{
PrintErrInf(status);
}
}
else
{
PrintErrInf(status);
}
}
public void writekeytoe2(View view){
byte status;//存放返回值
byte myareano;//区号
byte authmode;//密码类型,用A密码或B密码
byte[] mypicckey = new byte[6];//密码
tv.setText("");
Spinner spls= findViewById(R.id.SpinnerArea);
myareano = (byte)(spls.getSelectedItemId()); //指定区号
String strl="";
Spinner crtauthabkey=findViewById(R.id.SpinnerSelABKey);
authmode =(byte)crtauthabkey.getSelectedItemId(); //大于0表示用A密码认证,推荐用A密码认证
if(authmode==0){
strl="B认证密钥";
}else {strl="A认证密钥";}
EditText ctrauthkey=findViewById(R.id.EdittextAuthkey); //认证密钥
String authkeystr=ctrauthkey.getText().toString().trim();
if (authkeystr.length()!=12){
tv.setText("认证密钥为12位16进制数,请输入正确的卡认证密钥!");
return;
}
for (int i=0;i<6;i++){
mypicckey[i]=(byte) Integer.parseInt(authkeystr.substring(i * 2, i * 2 + 2), 16);//只有用Integer.parseInt才能杜绝大于128时的错误
}
status = ourmifare.pcdwritekeytoe2(myareano,authmode,mypicckey);
if(status == 0) {
ourmifare.pcdbeep(38);
tv.setText("第"+Integer.toString(myareano)+"区内部"+strl+"写入到发卡器芯片内成功!");
}else{
PrintErrInf(status);
}
}
//轻松读卡,返回4字节卡号及48字节扇区数据
public void piccreadex(View view)
{
byte status;//存放返回值
byte myareano;//区号
byte authmode;//密码类型,用A密码或B密码
byte myctrlword;//控制字
byte[] mypiccserial = new byte[4];//卡序列号
byte[] mypicckey = new byte[6];//密码
byte[] mypiccdata = new byte[48];//卡数据缓冲
byte[] myblockdata=new byte[16];//第三块数据
EditText ctruid=findViewById(R.id.TextViewuid);
ctruid.setText("");
TextView ctr8h10d=findViewById(R.id.TextViewlabel8h10d);
ctr8h10d.setText("");
tv.setText("");
myctrlword = BLOCK0_EN + BLOCK1_EN + BLOCK2_EN; //控制字指定,控制字的含义请查看本公司网站提供的动态库说明
Spinner ctrauthmode=findViewById(R.id.SpinnerInOutKey);
if (ctrauthmode.getSelectedItemId()==1){
myctrlword=(byte)(myctrlword + EXTERNKEY); //选用外部密钥认证
}
Spinner spls= findViewById(R.id.SpinnerArea);
myareano = (byte)(spls.getSelectedItemId()); //指定区号
Spinner crtauthabkey=findViewById(R.id.SpinnerSelABKey);
authmode =(byte)crtauthabkey.getSelectedItemId(); //大于0表示用A密码认证,推荐用A密码认证
EditText ctrauthkey=findViewById(R.id.EdittextAuthkey); //认证密钥
String authkeystr=ctrauthkey.getText().toString().trim();
if (authkeystr.length()!=12){
tv.setText("认证密钥为12位16进制数,请输入正确的卡认证密钥!");
return;
}
for (int i=0;i<6;i++){
mypicckey[i]=(byte) Integer.parseInt(authkeystr.substring(i * 2, i * 2 + 2), 16);//只有用Integer.parseInt才能杜绝大于128时的错误
}
status = ourmifare.piccreadexfm11rf32(myctrlword,mypiccserial,myareano,authmode,mypicckey,mypiccdata);
if(status == 0)
{
ourmifare.pcdbeep(38);
String serialnumber = "";
for (int i = 0; i < 4; i++) {
String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);
serialnumber = serialnumber + bytestr.substring(bytestr.length() - 2, bytestr.length());
}
serialnumber=serialnumber.toUpperCase();
ctruid.setText(serialnumber);
long cardhao;
cardhao = mypiccserial[3] & 0xff;
cardhao *= 256;
cardhao += mypiccserial[2] & 0xff;
cardhao *= 256;
cardhao += mypiccserial[1] & 0xff;
cardhao *= 256;
cardhao += mypiccserial[0] & 0xff;
String strls1 = "000000000"+Long.toString(cardhao);//0305887634 123B7992
strls1=strls1.substring(strls1.length()-10,strls1.length());
ctr8h10d.setText(strls1);
String strls = "读取扇区数据成功!16进制卡号为:" +serialnumber+"\n转8H10D卡号:"+ strls1;
tv.setText(strls);
strls= "";
for(int i = 0;i < 16;i++)
{
strls1 = "00"+Integer.toHexString(mypiccdata[i] & 0xFF);
strls = strls + strls1.substring(strls1.length()-2) +" ";
}
EditText ctrblock0=findViewById(R.id.Edittextblock0);
ctrblock0.setText(strls.toUpperCase());
strls= "";
for(int i = 16;i < 32;i++)
{
strls1 = "00"+Integer.toHexString(mypiccdata[i] & 0xFF);
strls = strls + strls1.substring(strls1.length()-2) +" ";
}
EditText ctrblock1=findViewById(R.id.Edittextblock1);
ctrblock1.setText(strls.toUpperCase());
strls= "";
for(int i = 32;i < 48;i++)
{
strls1 = "00"+Integer.toHexString(mypiccdata[i] & 0xFF);
strls = strls + strls1.substring(strls1.length()-2) +" ";
}
EditText ctrblock2=findViewById(R.id.Edittextblock2);
ctrblock2.setText(strls.toUpperCase());
status= ourmifare.piccread((byte)(myareano*4+3),myblockdata); //读块第三块密钥块
if (status==0){
strls= "";
for(int i = 0;i < 16;i++)
{
strls1 = "00"+Integer.toHexString(myblockdata[i] & 0xFF);
strls = strls + strls1.substring(strls1.length()-2) +" ";
}
EditText ctrblock3=findViewById(R.id.Edittextblock3);
ctrblock3.setText(strls.toUpperCase());
}else{
tv.setText( "读取扇区数据成功!16进制卡号为:" +serialnumber+"\n读第3块时错误:"+Integer.toString(status));
}
}
else
{
PrintErrInf(status);
}
mypiccserial = null;
mypicckey = null;
mypiccdata = null;
}
//轻松读卡,返回4字节卡号及48字节扇区数据
public void piccreadexevery200ms(View view)
{
if(((Button)findViewById(R.id.btnPiccreadex1)).getText() =="启动连续每隔0.2秒读一次卡")
{
((Button)findViewById(R.id.btnPiccreadex1)).setText("停止连续读卡");
timer = new Timer();
task = new TimerTask() {
@Override
public void run() {
if(iscontinue) {
iscontinue = false;
piccreadex(view);
iscontinue = true;
proctimes++;
tv.setText(tv.getText() + "\n执行次数:" + Long.toString(proctimes));
}
}
};
timer.schedule(task, 0,200);
}
else
{
((Button)findViewById(R.id.btnPiccreadex1)).setText("启动连续每隔0.2秒读一次卡");
if(timer != null) {
timer.cancel();
proctimes = 0;
}
timer = null;
}
}
//轻松写卡:8区,密码12个F,数据1-48,返回4字节卡号"
public void piccwriteex(View view)
{
byte status;//存放返回值
byte myareano;//区号
byte authmode;//密码类型,用A密码或B密码
byte myctrlword;//控制字
byte[] mypiccserial = new byte[4];//卡序列号
byte[] mypicckey = new byte[6];//密码
byte[] mypiccdata = new byte[48];//卡数据缓冲
EditText ctruid=findViewById(R.id.TextViewuid);
ctruid.setText("");
TextView ctr8h10d=findViewById(R.id.TextViewlabel8h10d);
ctr8h10d.setText("");
tv.setText("");
myctrlword = BLOCK0_EN + BLOCK1_EN + BLOCK2_EN; //控制字指定,控制字的含义请查看本公司网站提供的动态库说明
Spinner ctrauthmode=findViewById(R.id.SpinnerInOutKey);
if (ctrauthmode.getSelectedItemId()==1){
myctrlword=(byte)(myctrlword + EXTERNKEY); //选用外部密钥认证
}
Spinner spls= findViewById(R.id.SpinnerArea);
myareano = (byte)(spls.getSelectedItemId()); //指定区号
Spinner crtauthabkey=findViewById(R.id.SpinnerSelABKey);
authmode =(byte)crtauthabkey.getSelectedItemId(); //大于0表示用A密码认证,推荐用A密码认证
EditText ctrauthkey=findViewById(R.id.EdittextAuthkey); //认证密钥
String authkeystr=ctrauthkey.getText().toString().trim();
if (authkeystr.length()!=12){
tv.setText("认证密钥为12位16进制数,请输入正确的卡认证密钥!");
return;
}
for (int i=0;i<6;i++){
mypicckey[i]=(byte) Integer.parseInt(authkeystr.substring(i * 2, i * 2 + 2), 16);//只有用Integer.parseInt才能杜绝大于128时的错误
}
String[] strArr;
EditText ctrblock0=findViewById(R.id.Edittextblock0);
String blockstr0=ctrblock0.getText().toString().trim();
strArr= blockstr0.split("\\ "); /*分割接收到的数据后再分析、处理、返回指令 */
if (strArr.length!=16){
tv.setText("第0块写入数据不足,请输入32位16进制写入数据!");
return;
}
EditText ctrblock1=findViewById(R.id.Edittextblock1);
String blockstr1=ctrblock1.getText().toString().trim();
strArr= blockstr1.split("\\ "); /*分割接收到的数据后再分析、处理、返回指令 */
if (strArr.length!=16){
tv.setText("第1块写入数据不足,请输入32位16进制写入数据!");
return;
}
EditText ctrblock2=findViewById(R.id.Edittextblock2);
String blockstr2=ctrblock2.getText().toString().trim();
strArr= blockstr2.split("\\ "); /*分割接收到的数据后再分析、处理、返回指令 */
if (strArr.length!=16){
tv.setText("第2块写入数据不足,请输入32位16进制写入数据!");
return;
}
String writedatastr=blockstr0+" "+blockstr1+" "+blockstr2;
strArr= writedatastr.split("\\ ");
for(int p=0;p<strArr.length;p++) {
mypiccdata[p]=(byte)(Integer.parseInt(strArr[p],16));
}
status = ourmifare.piccwriteexfm11rf32(myctrlword,mypiccserial,myareano,authmode,mypicckey,mypiccdata);
if(status == 0)
{
ourmifare.pcdbeep(38);
String serialnumber = "";
for (int i = 0; i < 4; i++) {
String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);
serialnumber = serialnumber + bytestr.substring(bytestr.length() - 2, bytestr.length());
}
serialnumber=serialnumber.toUpperCase();
ctruid.setText(serialnumber);
long cardhao;
cardhao = mypiccserial[3] & 0xff;
cardhao *= 256;
cardhao += mypiccserial[2] & 0xff;
cardhao *= 256;
cardhao += mypiccserial[1] & 0xff;
cardhao *= 256;
cardhao += mypiccserial[0] & 0xff;
String strls1 = "000000000"+Long.toString(cardhao);//0305887634 123B7992
strls1=strls1.substring(strls1.length()-10,strls1.length());
ctr8h10d.setText(strls1);
String strls = "扇区写入数据成功!16进制卡号为:" +serialnumber+"\n转8H10D卡号:"+ strls1;
tv.setText(strls);
}
else
{
PrintErrInf(status);
}
}
//改单区密码:8区,密码12个F,改成12个F,返回4字节卡号"
public void piccchangesinglekeyex(View view)
{
byte status;//存放返回值
byte myareano;//区号
byte authmode;//密码类型,用A密码或B密码
byte myctrlword=0;//控制字
byte[] mypiccserial = new byte[4];//卡序列号
byte[] mypicckeyold = new byte[6];//密码
byte[] mypicckeynew = new byte[17];//卡数据缓冲
EditText ctruid=findViewById(R.id.TextViewuid);
ctruid.setText("");
TextView ctr8h10d=findViewById(R.id.TextViewlabel8h10d);
ctr8h10d.setText("");
tv.setText("");
Spinner ctrauthmode=findViewById(R.id.SpinnerInOutKey);
if (ctrauthmode.getSelectedItemId()==1){
myctrlword=(byte)(myctrlword + EXTERNKEY); //选用外部密钥认证
}
Spinner spls= findViewById(R.id.SpinnerArea);
myareano = (byte)(spls.getSelectedItemId()); //指定区号
Spinner crtauthabkey=findViewById(R.id.SpinnerSelABKey);
authmode =(byte)crtauthabkey.getSelectedItemId(); //大于0表示用A密码认证,推荐用A密码认证
EditText ctrauthkey=findViewById(R.id.EdittextAuthkey); //认证密钥
String authkeystr=ctrauthkey.getText().toString().trim();
if (authkeystr.length()!=12){
tv.setText("认证密钥为12位16进制数,请输入正确的卡认证密钥!");
return;
}
for (int i=0;i<6;i++){
mypicckeyold[i]=(byte) Integer.parseInt(authkeystr.substring(i * 2, i * 2 + 2), 16);//只有用Integer.parseInt才能杜绝大于128时的错误
}
//新A密钥
EditText ctrkeya=findViewById(R.id.Edittextnewkeya);
String newkeyastr=ctrkeya.getText().toString().trim();
if (newkeyastr.length()!=12){
tv.setText("新A密钥输入错误,请输入12位16进制新A密钥!");
return;
}
for (int i=0;i<6;i++){
mypicckeynew[i]=(byte)Integer.parseInt(newkeyastr.substring(i * 2, i * 2 + 2), 16);//只有用Integer.parseInt才能杜绝大于128时的错误
}
//新控制位
EditText ctrnewctr=findViewById(R.id.Edittextnewctr);
String newctrstr=ctrnewctr.getText().toString().trim();
if (newctrstr.length()!=8){
tv.setText("新控制字输入错误,请输入8位16进制控制字!");
return;
}
for (int i=0;i<4;i++){
mypicckeynew[6+i]=(byte)Integer.parseInt(newctrstr.substring(i * 2, i * 2 + 2), 16);//只有用Integer.parseInt才能杜绝大于128时的错误
}
//新B密钥
EditText ctrkeyb=findViewById(R.id.Edittextnewkeyb);
String newkeybstr=ctrkeyb.getText().toString().trim();
if (newkeyastr.length()!=12){
tv.setText("新B密钥输入错误,请输入12位16进制新B密钥!");
return;
}
for (int i=0;i<6;i++){
mypicckeynew[10+i]=(byte)Integer.parseInt(newkeybstr.substring(i * 2, i * 2 + 2), 16);//只有用Integer.parseInt才能杜绝大于128时的错误
}
//选项之
Spinner ctrnewkey=findViewById(R.id.SpinnerchangeKey);
byte selechangkey=(byte)ctrnewkey.getSelectedItemId();
switch (selechangkey){
case 0:
mypicckeynew[16] = (byte)0x00;//为0表示只改A官密码
break;
case 1:
mypicckeynew[16] = (byte)0x01;//为1表示改A密码同时也改B密码
break;
case 2:
mypicckeynew[16] = (byte)0x03;//为3表示改AB密码及访问位,警示:不要轻易改访问位,FF078069 为出可使用7F 07 88 69控制
break;
}
status = ourmifare.piccchangesinglekeyexfm11rf32(myctrlword,mypiccserial,myareano,authmode,mypicckeyold,mypicckeynew);
if(status == 0)
{
ourmifare.pcdbeep(38);
String serialnumber = "";
for (int i = 0; i < 4; i++) {
String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);
serialnumber = serialnumber + bytestr.substring(bytestr.length() - 2, bytestr.length());
}
serialnumber=serialnumber.toUpperCase();
ctruid.setText(serialnumber);
long cardhao;
cardhao = mypiccserial[3] & 0xff;
cardhao *= 256;
cardhao += mypiccserial[2] & 0xff;
cardhao *= 256;
cardhao += mypiccserial[1] & 0xff;
cardhao *= 256;
cardhao += mypiccserial[0] & 0xff;
String strls1 = "000000000"+Long.toString(cardhao);//0305887634 123B7992
strls1=strls1.substring(strls1.length()-10,strls1.length());
ctr8h10d.setText(strls1);
String strls = "更改卡片密钥成功!16进制卡号为:" +serialnumber+"\n转8H10D卡号:"+ strls1;
tv.setText(strls);
}
else
{
PrintErrInf(status);
}
}
public void PrintErrInf(byte errcode) {
String dispstr;
switch(errcode){
case 1:
dispstr="错误代码:1,0~2块都没读出来,可能刷卡太块。但卡序列号已被读出来!";
break;
case 2:
dispstr="错误代码:2,第0块已被读出,但1~2块读取失败。卡序列号已被读出来!";
break;
case 3:
dispstr="错误代码:3,第0、1块已被读出,但2块读取失败。卡序列号已被读出来!";
break;
case 8:
dispstr="错误代码:8,未寻到卡,请重新拿开卡后再放到感应区!";
break;
case 9:
dispstr="错误代码:9,有多张卡在感应区,寻卡过程中防冲突失败,读序列吗错误!";
break;
case 10:
dispstr="错误代码:10,该卡可能已被休眠,无法选中卡片!";
break;
case 11:
dispstr="错误代码:11,密码装载失败!";
break;
case 12:
dispstr="错误代码:12,卡片密码认证失败!";
break;
case 13:
dispstr="错误代码:13,读本块失败,原因是刷卡太快或本块所对应的区还没通过密码认证!";
break;
case 14:
dispstr="错误代码:14,写本块失败,原因是刷卡太快或本块所对应的区还没通过密码认证!";
break;
case 21:
dispstr="错误代码:21,没有动态库!";
break;
case 22:
dispstr="错误代码:22,动态库或驱动程序异常!";
break;
case 23:
dispstr="错误代码:23,发卡器未连接!";
break;
case 24:
dispstr="错误代码:24,操作超时,一般是动态库没有反映!";
break;
case 25:
dispstr="错误代码:25,发送字数不够!";
break;
case 26:
dispstr="错误代码:26,发送的CRC错!";
break;
case 27:
dispstr="错误代码:27,接收的字数不够!";
break;
case 28:
dispstr="错误代码:28,接收的CRC错!";
break;
default:
dispstr="未知错误,错误代码:"+Integer.toString(errcode);
break;
}
tv.setText(dispstr);
}
}