本示例使用的发卡器: https://item.taobao.com/item.htm?spm=a1z10.5-c-s.w4002-21818769070.11.3513789erHXVGx&id=615391857885
<?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=".NtagActivity">
<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="ntag213、215、216卡、复旦11rf32测试页"
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="120dp"
android:padding="3dp"
android:text="操作结果"
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="5dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/toolbar"
app:layout_constraintBottom_toTopOf="@+id/sample_text"
android:scrollbars="horizontal"
>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="3dp"
>
<Button
android:id="@+id/butt_requestntag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="搜寻Ntag卡获取卡号"
android:textSize="12sp"
android:onClick="RequestNtag"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textViewtitleuid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="UID:"
app:layout_constraintBottom_toBottomOf="@+id/butt_requestntag"
app:layout_constraintLeft_toRightOf="@+id/butt_requestntag"
app:layout_constraintTop_toTopOf="@+id/butt_requestntag" />
<TextView
android:id="@+id/textViewuid"
android:layout_width="130dp"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:background="@drawable/shape4border"
android:gravity="center"
android:textColor="#FF0000"
android:text=""
app:layout_constraintBottom_toBottomOf="@+id/textViewtitleuid"
app:layout_constraintLeft_toRightOf="@+id/textViewtitleuid"
app:layout_constraintTop_toTopOf="@+id/textViewtitleuid" />
<Button
android:id="@+id/butt_getversiontype"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:onClick="getversiontype"
android:text="卡片版本及型号"
android:textSize="12sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/butt_requestntag" />
<Button
android:id="@+id/butt_getsign"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="getcardsign"
android:text="卡片签名信息"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/butt_getversiontype"
app:layout_constraintLeft_toRightOf="@+id/butt_getversiontype"
app:layout_constraintTop_toTopOf="@+id/butt_getversiontype" />
<Button
android:id="@+id/butt_getcountervalue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="getcountervalue"
android:text="卡片单向计数器值"
android:textSize="11sp"
app:layout_constraintBottom_toBottomOf="@+id/butt_getsign"
app:layout_constraintLeft_toRightOf="@+id/butt_getsign"
app:layout_constraintTop_toTopOf="@+id/butt_getsign" />
<Button
android:id="@+id/butt_getStaticlock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:onClick="getStaticlock"
android:text="读取卡片静态锁值"
android:textSize="12sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/butt_getversiontype" />
<TextView
android:id="@+id/textViewtitlelock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="静态锁标识:"
app:layout_constraintBottom_toBottomOf="@+id/butt_getStaticlock"
app:layout_constraintLeft_toRightOf="@+id/butt_getStaticlock"
app:layout_constraintTop_toTopOf="@+id/butt_getStaticlock" />
<EditText
android:id="@+id/edit_Staticlock"
android:layout_width="120dp"
android:layout_height="wrap_content"
android:layout_marginLeft="2dp"
android:background="@drawable/shape4border"
android:digits="01"
android:gravity="center"
android:inputType="textCapCharacters"
android:maxLength="16"
android:text="0000000000000000"
android:textColor="#0000FF"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/textViewtitlelock"
app:layout_constraintLeft_toRightOf="@+id/textViewtitlelock"
app:layout_constraintTop_toTopOf="@+id/textViewtitlelock" />
<Button
android:id="@+id/butt_Staticlock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="Staticlock"
android:text="将卡片加上静态锁"
android:textSize="12sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/butt_getStaticlock" />
<TextView
android:id="@+id/textViewtitlenote"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="警告:16位静态锁标识代表0-15块的锁定状态,0表示块未锁定、1表示块锁定,块如果锁定将不能再次修改!"
android:textColor="#FF0000"
app:layout_constraintBottom_toBottomOf="@+id/butt_Staticlock"
app:layout_constraintLeft_toRightOf="@+id/butt_Staticlock"
app:layout_constraintTop_toTopOf="@+id/butt_Staticlock" />
<CheckBox
android:id="@+id/check_seleauthkeyen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="选择先认证密钥再继续以下操作,8位16进制认证密钥:"
android:textColor="#0000FF"
android:textSize="11sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/butt_Staticlock" />
<EditText
android:id="@+id/edit_authkey"
android:layout_width="70dp"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:background="@drawable/shape4border"
android:digits="0123456789ABCDEFabcdef"
android:textColor="#FF0000"
android:gravity="center"
android:inputType="textCapCharacters"
android:maxLength="8"
android:maxLines="1"
android:text="12345678"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/check_seleauthkeyen"
app:layout_constraintLeft_toRightOf="@+id/check_seleauthkeyen"
app:layout_constraintTop_toTopOf="@+id/check_seleauthkeyen" />
<Button
android:id="@+id/butt_initntag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:onClick="InitNtagCard"
android:text="设置Ntag卡密钥机制"
android:textSize="12sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/check_seleauthkeyen" />
<Spinner
android:id="@+id/spin_seleopencloskey"
android:layout_width="220dp"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:entries="@array/NtagKeyEn"
android:theme="@style/my_spinner_style"
app:layout_constraintLeft_toRightOf="@+id/butt_initntag"
app:layout_constraintTop_toTopOf="@+id/butt_initntag" />
<Spinner
android:id="@+id/spin_selereadauth"
android:layout_width="220dp"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:entries="@array/NtagReadAuthEn"
android:theme="@style/my_spinner_style"
app:layout_constraintBottom_toBottomOf="@+id/butt_initntag"
app:layout_constraintLeft_toRightOf="@+id/butt_initntag" />
<TextView
android:id="@+id/textViewtitlefrom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:textSize="12sp"
android:text="选择从第:"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/butt_initntag" />
<EditText
android:id="@+id/edit_initbeginblock"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:background="@drawable/shape4border"
android:digits="0123456789"
android:gravity="center"
android:textColor="#FF0000"
android:inputType="textCapCharacters"
android:maxLength="4"
android:maxLines="1"
android:text="20"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/textViewtitlefrom"
app:layout_constraintLeft_toRightOf="@+id/textViewtitlefrom"
app:layout_constraintTop_toTopOf="@+id/textViewtitlefrom" />
<TextView
android:id="@+id/textViewtitle0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="2dp"
android:layout_marginTop="3dp"
android:text="块开始有密钥保护功能,卡片新密钥:"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/edit_initbeginblock"
app:layout_constraintLeft_toRightOf="@+id/edit_initbeginblock"
app:layout_constraintTop_toTopOf="@+id/edit_initbeginblock" />
<EditText
android:id="@+id/edit_newkey"
android:layout_width="70dp"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:background="@drawable/shape4border"
android:digits="0123456789ABCDEFabcdef"
android:textColor="#FF0000"
android:gravity="center"
android:inputType="textCapCharacters"
android:maxLength="8"
android:maxLines="1"
android:text="12345678"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/textViewtitle0"
app:layout_constraintLeft_toRightOf="@+id/textViewtitle0"
app:layout_constraintTop_toTopOf="@+id/textViewtitle0" />
<TextView
android:id="@+id/textViewpack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:textSize="12sp"
android:text="PACK密钥确认码:"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textViewtitlefrom" />
<EditText
android:id="@+id/edit_packkey"
android:layout_width="40dp"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:background="@drawable/shape4border"
android:digits="0123456789ABCDEFabcdef"
android:gravity="center"
android:textColor="#FF0000"
android:inputType="textCapCharacters"
android:maxLength="4"
android:maxLines="1"
android:text="1616"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/textViewpack"
app:layout_constraintLeft_toRightOf="@+id/textViewpack"
app:layout_constraintTop_toTopOf="@+id/textViewpack" />
<TextView
android:id="@+id/textViewtitle1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="2dp"
android:layout_marginTop="3dp"
android:text=",允许密钥认证失败次数(0不限制):"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/edit_packkey"
app:layout_constraintLeft_toRightOf="@+id/edit_packkey"
app:layout_constraintTop_toTopOf="@+id/edit_packkey" />
<EditText
android:id="@+id/edit_limitauthfailed"
android:layout_width="40dp"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:background="@drawable/shape4border"
android:digits="0123456789"
android:gravity="center"
android:inputType="textCapCharacters"
android:maxLength="4"
android:maxLines="1"
android:text="0"
android:textColor="#FF0000"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/textViewtitle1"
app:layout_constraintLeft_toRightOf="@+id/textViewtitle1"
app:layout_constraintTop_toTopOf="@+id/textViewtitle1" />
<Button
android:id="@+id/butt_readntag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="轻松从Ntag卡读数据"
android:textSize="12sp"
android:onClick="ReadNtagCard"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textViewpack" />
<Button
android:id="@+id/butt_writentag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="轻松写数据到Ntag卡"
android:textSize="12sp"
android:onClick="WriteNtagCard"
app:layout_constraintBottom_toBottomOf="@+id/butt_readntag"
app:layout_constraintLeft_toRightOf="@+id/butt_readntag"
app:layout_constraintTop_toTopOf="@+id/butt_readntag" />
<TextView
android:id="@+id/textViewtitle2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:text="本次读写操作起始块:"
android:textSize="12sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/butt_readntag" />
<EditText
android:id="@+id/edit_RWbeginblock"
android:layout_width="48dp"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:background="@drawable/shape4border"
android:digits="0123456789"
android:gravity="center"
android:inputType="textCapCharacters"
android:maxLength="4"
android:maxLines="1"
android:text="4"
android:textColor="#FF0000"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/textViewtitle2"
app:layout_constraintLeft_toRightOf="@+id/textViewtitle2"
app:layout_constraintTop_toTopOf="@+id/textViewtitle2" />
<TextView
android:id="@+id/textViewtitle3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="40dp"
android:layout_marginTop="3dp"
android:text="本次读写块数:"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/edit_RWbeginblock"
app:layout_constraintLeft_toRightOf="@+id/edit_RWbeginblock"
app:layout_constraintTop_toTopOf="@+id/edit_RWbeginblock" />
<EditText
android:id="@+id/edit_RWblocks"
android:layout_width="48dp"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:background="@drawable/shape4border"
android:digits="0123456789"
android:gravity="center"
android:inputType="textCapCharacters"
android:maxLength="4"
android:maxLines="1"
android:text="10"
android:textColor="#FF0000"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/textViewtitle3"
app:layout_constraintLeft_toRightOf="@+id/textViewtitle3"
app:layout_constraintTop_toTopOf="@+id/textViewtitle3" />
<TextView
android:id="@+id/textViewtitle4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:text="读写标签内数据:"
android:textSize="12sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textViewtitle2" />
<EditText
android:id="@+id/edit_rwdata"
android:layout_width="match_parent"
android:layout_height="130dp"
android:background="@drawable/shape4border"
android:digits="0123456789ABCDEFabcdef "
android:inputType="textCapCharacters"
android:maxLines="8"
android:gravity="left"
android:text="00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
android:textSize="12sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textViewtitle4" />
</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.CheckBox;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import com.reader.ourmifare;
public class NtagActivity extends AppCompatActivity {
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ntag);
androidx.appcompat.widget.Toolbar toolbar=findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
tv = findViewById(R.id.sample_text);
tv.setText("操作结果");
Spinner spls = findViewById(R.id.spin_seleopencloskey);
spls.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();
}
public void RequestNtag(View view){
byte status; //存放返回值
byte[] mypiccserial = new byte[7]; //7字节卡号
tv.setText("");
TextView ctruid=findViewById(R.id.textViewuid);
ctruid.setText("");
status = ourmifare.piccrequestul(mypiccserial);//& 0xff用于转为无符号行数据
if (status == 0) {
ourmifare.pcdbeep(38);
String uidstr = "";
for (int i = 0; i < 7; i++) {
String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);
uidstr = uidstr + bytestr.substring(bytestr.length() - 2, bytestr.length()) ;
}
ctruid.setText(uidstr);
tv.setText("获取7字节卡序号:" + uidstr);
} else {
PrintErrInf(status); //返回代码提示
}
}
public void getversiontype(View view){
byte status; //存放返回值
byte[] mypiccserial = new byte[7]; //7字节卡号
byte[] mypiccversiondata=new byte[8];
tv.setText("");
TextView ctruid=findViewById(R.id.textViewuid);
ctruid.setText("");
status = ourmifare.piccrequestul(mypiccserial);
if (status == 0) {
String uidstr = "";
for (int i = 0; i < 7; i++) {
String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);
uidstr = uidstr + bytestr.substring(bytestr.length() - 2, bytestr.length()) ;
}
ctruid.setText(uidstr);
status = ourmifare.piccgetversionntag(mypiccversiondata);
if (status == 0) {
ourmifare.pcdbeep(38);
String verdstr = "";
for (int i = 0; i < 8; i++) {
String bytestr = "00" + Integer.toHexString(mypiccversiondata[i] & 0xff);
verdstr = verdstr + bytestr.substring(bytestr.length() - 2, bytestr.length()) + " ";
}
tv.setText("读取卡片版本型号成功!"+"\n卡片序号:" + uidstr+"\n"+"版本型号:"+verdstr);
}else {
PrintErrInf(status); //返回代码提示
}
} else {
PrintErrInf(status); //返回代码提示
}
}
public void getcardsign(View view){
byte status; //存放返回值
byte[] mypiccserial = new byte[7]; //7字节卡号
byte[] piccsigdata=new byte[32];
tv.setText("");
TextView ctruid=findViewById(R.id.textViewuid);
ctruid.setText("");
status = ourmifare.piccrequestul(mypiccserial);
if (status == 0) {
String uidstr = "";
for (int i = 0; i < 7; i++) {
String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);
uidstr = uidstr + bytestr.substring(bytestr.length() - 2, bytestr.length()) ;
}
ctruid.setText(uidstr);
status = ourmifare.piccgetversionntag(piccsigdata);
if (status == 0) {
ourmifare.pcdbeep(38);
String verdstr = "";
for (int i = 0; i < 32; i++) {
String bytestr = "00" + Integer.toHexString(piccsigdata[i] & 0xff);
verdstr = verdstr + bytestr.substring(bytestr.length() - 2, bytestr.length()) + " ";
}
tv.setText("读取卡片签名信息成功!"+"\n卡片序号:" + uidstr+"\n"+"签名信息:"+verdstr);
}else {
PrintErrInf(status); //返回代码提示
}
} else {
PrintErrInf(status); //返回代码提示
}
}
public void getcountervalue(View view){
byte status; //存放返回值
byte[] mypiccserial = new byte[7]; //7字节卡号
byte[] mypicccntdata=new byte[3];
tv.setText("");
TextView ctruid=findViewById(R.id.textViewuid);
ctruid.setText("");
status = ourmifare.piccrequestul(mypiccserial);
if (status == 0) {
String uidstr = "";
for (int i = 0; i < 7; i++) {
String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);
uidstr = uidstr + bytestr.substring(bytestr.length() - 2, bytestr.length()) ;
}
ctruid.setText(uidstr);
status = ourmifare.piccreadcntntag(mypicccntdata);
if (status == 0) {
ourmifare.pcdbeep(38);
String verdstr = "";
for (int i = 0; i < 3; i++) {
String bytestr = "00" + Integer.toHexString(mypicccntdata[i] & 0xff);
verdstr = verdstr + bytestr.substring(bytestr.length() - 2, bytestr.length()) + " ";
}
tv.setText("读取卡片单向计数器值成功!"+"\n卡片序号:" + uidstr+"\n"+"计数器值:"+verdstr);
}else {
tv.setText("读取卡片单向计数器值失败!错误代码:"+Integer.toString(status)+"\n卡片序号:" + uidstr+"\n"+"可能是计数器功能尚未启用或卡本身不支持计数功能!");
}
} else {
PrintErrInf(status); //返回代码提示
}
}
public void getStaticlock(View view){
byte status; //存放返回值
byte[] mypiccserial = new byte[7]; //7字节卡号
byte[] mypiccdata=new byte[16];
tv.setText("");
TextView ctruid=findViewById(R.id.textViewuid);
ctruid.setText("");
status = ourmifare.piccrequestul(mypiccserial);
if (status == 0) {
String uidstr = "";
for (int i = 0; i < 7; i++) {
String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);
uidstr = uidstr + bytestr.substring(bytestr.length() - 2, bytestr.length());
}
ctruid.setText(uidstr);
status = ourmifare.piccreadul((byte) 0,mypiccdata);
if (status == 0) {
ourmifare.pcdbeep(38);
String verdstr = "";
for (int i = 10; i < 12; i++) {
String bytestr = "00000000" + Integer.toBinaryString(mypiccdata[i] & 0xff);
verdstr = verdstr + bytestr.substring(bytestr.length() - 8, bytestr.length()) ;
}
EditText ctrstationlock=findViewById(R.id.edit_Staticlock);
ctrstationlock.setText(verdstr);
String tagtypestr="";
switch(mypiccdata[14]){
case 0x12:
tagtypestr="Ntag213,144 Bytes";
break;
case 0x3e:
tagtypestr="Ntag215,504 Bytes";
break;
case 0x6D:
tagtypestr="Ntag216,888 Bytes";
break;
default:
tagtypestr="OtherNtag";
break;
}
tv.setText("读取卡片静态锁标识成功!"+"\n卡片序号:" + uidstr+"\n芯片类型:"+tagtypestr+"\n静态锁标识:"+verdstr);
}else {
PrintErrInf(status); //返回代码提示
}
} else {
PrintErrInf(status); //返回代码提示
}
}
public void Staticlock(View view){
byte status; //存放返回值
byte[] mypiccserial = new byte[7]; //7字节卡号
byte[] mypiccdata=new byte[4];
tv.setText("");
TextView ctruid=findViewById(R.id.textViewuid);
ctruid.setText("");
EditText ctrstaticlock=findViewById(R.id.edit_Staticlock);
String staticlockstr=ctrstaticlock.getText().toString().trim();
if (staticlockstr.length()!=16){
tv.setText("静态锁标识输入错误,请输入16位2进制静态锁标识值!");
return;
}
status = ourmifare.piccrequestul(mypiccserial);
if (status == 0) {
String uidstr = "";
for (int i = 0; i < 7; i++) {
String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);
uidstr = uidstr + bytestr.substring(bytestr.length() - 2, bytestr.length());
}
ctruid.setText(uidstr);
mypiccdata[0]=0;
mypiccdata[1]=0;
mypiccdata[2]=(byte)Integer.parseInt(staticlockstr.substring(0,8),2);
mypiccdata[3]=(byte)Integer.parseInt(staticlockstr.substring(staticlockstr.length() - 8, staticlockstr.length()),2);
status = ourmifare.picclockntag((byte) 0,mypiccdata);
if (status == 0) {
ourmifare.pcdbeep(38);
tv.setText("卡片加入静态锁成功!"+"\n卡片序号:" + uidstr+"\n");
}else {
PrintErrInf(status); //返回代码提示
}
} else {
PrintErrInf(status); //返回代码提示
}
}
public void InitNtagCard(View view){
byte status; //存放返回值
byte[] mypicckey = new byte[4]; //4个字节的卡旧密码
byte[] newPickey = new byte[44]; //4个字节的新密码
byte[] mypiccserial = new byte[7]; //7字节卡号
byte ReadNeedKey = 0; //取值0读卡不需要认证密码,非0读卡也要认证密码
byte myctrlword ; //取值0不需要认证密码,16要认证卡密码 对卡操作
byte KeyErrNum=0; //对卡操作允许密码错误次数(0为不限次)
byte[] mypiccdata=new byte[16]; //本次对卡的配置信息
tv.setText("");
TextView ctruid=findViewById(R.id.textViewuid);
ctruid.setText("");
CheckBox ctrauthen=findViewById(R.id.check_seleauthkeyen);
if (ctrauthen.isChecked()){
myctrlword=16;
EditText ctrauthkey=findViewById(R.id.edit_authkey);
String authkeystr=ctrauthkey.getText().toString().trim();
if (authkeystr.length() != 8)
{
tv.setText("认证密钥是8位16进制数据,请输入正确的认证密钥!");
return;
}else {
for (int i = 0; i < 4; i++) {
mypicckey[i] = (byte) Integer.parseInt(authkeystr.substring(i * 2, i * 2 + 2), 16);//只有用Integer.parseInt才能杜绝大于128时的错误
}
}
}else{myctrlword=0;}
EditText ctrbeginblock=findViewById(R.id.edit_initbeginblock);
byte beginblock=(byte) Integer.parseInt(ctrbeginblock.getText().toString().trim());
EditText ctrliminub=findViewById(R.id.edit_limitauthfailed);
KeyErrNum=(byte) Integer.parseInt(ctrliminub.getText().toString().trim());
Spinner ctrreadkeyen=findViewById(R.id.spin_selereadauth);
ReadNeedKey=(byte)ctrreadkeyen.getSelectedItemId();
Spinner spls = findViewById(R.id.spin_seleopencloskey);
if (spls.getSelectedItemId()==0){ //卡片开启密码保护功能,开启后要记住卡密码,否则卡报废!!!
myctrlword=(byte)(myctrlword+4);
mypiccdata[3]=beginblock; //配置:密码保护起始页,要根据不同类型的卡来设置
myctrlword=(byte)(myctrlword+1);
mypiccdata[4]=(byte)(KeyErrNum % 8); //配置:最大卡密码认证错误次数
if(ReadNeedKey>0){ //配置:读卡时需要认证卡密码
mypiccdata[4]=(byte)(mypiccdata[4]+(byte)(0x80));
}
myctrlword=(byte)(myctrlword+2); //配置:启用计数器
EditText ctrnewkey=findViewById(R.id.edit_newkey);
String newkeystr=ctrnewkey.getText().toString().trim();
if (newkeystr.length() != 8)
{
tv.setText("密钥是8位16进制数据,请输入正确的新密钥!");
return;
}else {
for (int i = 0; i < 4; i++) {
newPickey[i] = (byte) Integer.parseInt(newkeystr.substring(i * 2, i * 2 + 2), 16);//只有用Integer.parseInt才能杜绝大于128时的错误
mypiccdata[8+i]= (byte) Integer.parseInt(newkeystr.substring(i * 2, i * 2 + 2), 16);//只有用Integer.parseInt才能杜绝大于128时的错误
}
}
EditText ctrpack=findViewById(R.id.edit_packkey);
String packkeystr=ctrpack.getText().toString().trim();
if (packkeystr.length() != 4)
{
tv.setText("PACK密钥确认码是4位16进制数据,请输入正确的密钥确认码!");
return;
}else {
for (int i = 0; i < 2; i++) {
mypiccdata[12+i] = (byte) Integer.parseInt(packkeystr.substring(i * 2, i * 2 + 2), 16);//只有用Integer.parseInt才能杜绝大于128时的错误
}
}
}else{ //卡片取消密码保护功能
mypiccdata[3]=(byte)(0xff);
myctrlword=(byte)(myctrlword+1);
myctrlword=(byte)(myctrlword+2);
}
status = ourmifare.piccinitntag(myctrlword,mypiccserial,mypicckey,mypiccdata) ;
if (status == 0) {
ourmifare.pcdbeep(38);
String uidstr = "";
for (int i = 0; i < 7; i++) {
String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);
uidstr = uidstr + bytestr.substring(bytestr.length() - 2, bytestr.length()) ;
}
ctruid.setText(uidstr);
tv.setText("设置卡密码及保护机制成功!"+"\n卡片序号:" + uidstr);
} else {
PrintErrInf(status); //返回代码提示
}
}
public void ReadNtagCard(View view){
byte status=1; //存放返回值
byte[] mypiccserial = new byte[7]; //7字节卡号
byte[] mypicckey=new byte[4]; //4个字节的卡密码
byte[] mypiccdata=new byte[48]; //48个字节读卡的数据缓冲
byte myblockaddr; //读起始页地址
byte myblocksize; //读卡页数
byte myctrlword; //取值0不认证密码,16要认证卡密码
tv.setText("");
TextView ctruid=findViewById(R.id.textViewuid);
ctruid.setText("");
EditText ctrrwdata=findViewById(R.id.edit_rwdata);
ctrrwdata.setText("");
CheckBox ctrauthen=findViewById(R.id.check_seleauthkeyen);
if (ctrauthen.isChecked()){
myctrlword=16;
EditText ctrauthkey=findViewById(R.id.edit_authkey);
String authkeystr=ctrauthkey.getText().toString().trim();
if (authkeystr.length() != 8)
{
tv.setText("认证密钥是8位16进制数据,请输入正确的认证密钥!");
return;
}else {
for (int i = 0; i < 4; i++) {
mypicckey[i] = (byte) Integer.parseInt(authkeystr.substring(i * 2, i * 2 + 2), 16);//只有用Integer.parseInt才能杜绝大于128时的错误
}
}
}else{myctrlword=0;}
EditText ctrblokadd=findViewById(R.id.edit_RWbeginblock);
myblockaddr=(byte)Integer.parseInt(ctrblokadd.getText().toString().trim());
EditText ctrbloknum=findViewById(R.id.edit_RWblocks);
myblocksize=(byte)Integer.parseInt(ctrbloknum.getText().toString().trim());
//使用循环的方式读取,每次读一个块,这样可以连续读取标签N个块数据
if (myblocksize<1){
tv.setText("请输入本次读写块数!");
return;
}
int j=0;
String readdatastr="";
while (j<myblocksize){
status = ourmifare.piccreadexntag(myctrlword,mypiccserial,mypicckey,(byte)(myblockaddr+j),(byte)1,mypiccdata) ;
if (status==0){
for (int i=0;i<4;i++ ){
String bytestr = "00" + Integer.toHexString(mypiccdata[i] & 0xFF);
readdatastr = readdatastr + bytestr.substring(bytestr.length() - 2, bytestr.length())+" ";
}
j++;
}else{ j=myblocksize;}
}
if (status == 0) {
ourmifare.pcdbeep(38);
String uidstr = "";
for (int i = 0; i < 7; i++) {
String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xFF);
uidstr = uidstr + bytestr.substring(bytestr.length() - 2, bytestr.length()) ;
}
ctruid.setText(uidstr);
ctrrwdata.setText(readdatastr);
tv.setText("读取Ntag卡块数据成功!"+"\n卡片序号:" + uidstr);
} else {
PrintErrInf(status); //返回代码提示
}
/* 执行一次读卡操作,每次最多可以读12个块
if (myblocksize<1 || myblocksize>12){
tv.setText("读写块数必须>=1,13<=");
return;
}
status = ourmifare.piccreadexntag(myctrlword,mypiccserial,mypicckey,myblockaddr,myblocksize,mypiccdata) ;
if (status == 0) {
ourmifare.pcdbeep(38);
String uidstr = "";
for (int i = 0; i < 7; i++) {
String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xFF);
uidstr = uidstr + bytestr.substring(bytestr.length() - 2, bytestr.length()) ;
}
ctruid.setText(uidstr);
String databuf="";
for (int i = 0; i < myblocksize*4; i++) {
String bytestr = "00" + Integer.toHexString(mypiccdata[i] & 0xFF);
databuf = databuf + bytestr.substring(bytestr.length() - 2, bytestr.length()) + " ";
}
ctrrwdata.setText(databuf);
tv.setText("读取Ntag卡块数据成功!"+"\n卡片序号:" + uidstr);
} else {
PrintErrInf(status); //返回代码提示
}*/
}
public void WriteNtagCard(View view){
byte status=1; //存放返回值
byte[] mypiccserial = new byte[7]; //7字节卡号
byte[] mypicckey=new byte[4]; //4个字节的卡密码
byte[] mypiccdata=new byte[48]; //48个字节读卡的数据缓冲
byte myblockaddr; //读起始页地址
byte myblocksize; //读卡页数
byte myctrlword; //取值0不认证密码,16要认证卡密码
tv.setText("");
TextView ctruid=findViewById(R.id.textViewuid);
ctruid.setText("");
CheckBox ctrauthen=findViewById(R.id.check_seleauthkeyen);
if (ctrauthen.isChecked()){
myctrlword=16;
EditText ctrauthkey=findViewById(R.id.edit_authkey);
String authkeystr=ctrauthkey.getText().toString().trim();
if (authkeystr.length() != 8)
{
tv.setText("认证密钥是8位16进制数据,请输入正确的认证密钥!");
return;
}else {
for (int i = 0; i < 4; i++) {
mypicckey[i] = (byte) Integer.parseInt(authkeystr.substring(i * 2, i * 2 + 2), 16);//只有用Integer.parseInt才能杜绝大于128时的错误
}
}
}else{myctrlword=0;}
EditText ctrblokadd=findViewById(R.id.edit_RWbeginblock);
myblockaddr=(byte)Integer.parseInt(ctrblokadd.getText().toString().trim());
EditText ctrbloknum=findViewById(R.id.edit_RWblocks);
myblocksize=(byte)Integer.parseInt(ctrbloknum.getText().toString().trim());
if (myblocksize<1){
tv.setText("请输入本次读写块数!");
return;
}
EditText ctrrwdata=findViewById(R.id.edit_rwdata);
String rwdatahex=ctrrwdata.getText().toString().trim();
String[] strArr = rwdatahex.split("\\ "); /*分割接收到的数据后再分析、处理、返回指令*/
if (strArr.length<myblocksize*4) {
tv.setText("写入数据不足,请输入" + Integer.toString(myblocksize*4 * 2) + "位16进制写入数据!");
return;
}
//使用循环的方式写卡,每次写一个块,这样可以连续写入N个块数据
int j=0;
while (j<myblocksize) {
for (int i=0;i<4;i++){
mypiccdata[i]=(byte)(Integer.parseInt(strArr[j*4+i],16));
}
status = ourmifare.piccwriteexntag(myctrlword, mypiccserial, mypicckey, (byte)(myblockaddr+j), (byte)1, mypiccdata);
if (status==0){
j++;
}else{j=myblocksize;}
}
if (status == 0) {
ourmifare.pcdbeep(38);
String uidstr = "";
for (int i = 0; i < 7; i++) {
String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xFF);
uidstr = uidstr + bytestr.substring(bytestr.length() - 2, bytestr.length()) ;
}
ctruid.setText(uidstr);
tv.setText("写入Ntag卡块数据成功!"+"\n卡片序号:" + uidstr);
} else {
PrintErrInf(status); //返回代码提示
}
/* //执行一次写卡操作,每次最多可以读11个块
if (myblocksize<1 || myblocksize>11){
tv.setText("读写块数必须>=1,12<=");
return;
}
for (int i=0;i<strArr.length;i++){
mypiccdata[i]=(byte)(Integer.parseInt(strArr[i],16));
}
status = ourmifare.piccwriteexntag(myctrlword, mypiccserial, mypicckey, myblockaddr, myblocksize, mypiccdata);
if (status == 0) {
ourmifare.pcdbeep(38);
String uidstr = "";
for (int i = 0; i < 7; i++) {
String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xFF);
uidstr = uidstr + bytestr.substring(bytestr.length() - 2, bytestr.length()) ;
}
ctruid.setText(uidstr);
tv.setText("写入Ntag卡块数据成功!"+"\n卡片序号:" + uidstr);
} 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:
System.out.print("错误代码:25,发送字数不够!");
break;
case 26:
System.out.print("错误代码:26,发送的CRC错!");
break;
case 27:
System.out.print("错误代码:27,接收的字数不够!");
break;
case 28:
System.out.print("错误代码:28,接收的CRC错!");
break;
default:
System.out.print("未知错误,错误代码:"+Integer.toString(errcode));
break;
}
tv = findViewById(R.id.sample_text);
tv.setText(dispstr);
}
}