我正在使用NFC阅读Mifare Classic 1K卡。
该代码适用于Android 5.0及更低版本的所有Android设备,但当我在使用Android 5.1的设备上测试我的代码时,它无效。
我已经在Nexus 7(4.4,5.0),Nexus 5(5.0),Sony Xperia和Samsung设备上测试了我的代码,它运行得非常好。
但是当Android从5.0升级到5.1时,在某些新设备(Nexus 6,Moto x Play)中,我的程序无效。
我的代码,
MifareClassic mfc = MifareClassic.get(tagFromIntent);
当我在Android 5.1中扫描我的卡时,返回null
,否则在5.1以下的版本中,它会正常工作。
@SuppressLint("InlinedApi")
public String AuthenticateCard(Context context, Intent nfcIntent) {
String blockData = null;
//Get an instance of the TAG from the NfcAdapter
Tag tagFromIntent = nfcIntent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
String idFromIntent = ByteArrayToHexString(tagFromIntent.getId());
Log.v("onNewIntent()", "NfcAdapter TAG : " + tagFromIntent
+ "NfcAdapter ID : " + idFromIntent);
Log.v("onNewIntent()", "TAG TYPE : " + tagFromIntent.describeContents());
//Get an instance of the Mifare classic card from this TAG intent
//It works successfully with android 5.0 or below versions but returns null in devices with android 5.1.
MifareClassic mfc = MifareClassic.get(tagFromIntent);
try {
// Connect to card
mfc.connect();
// authenticate the sector
if (mfc.authenticateSectorWithKeyA(MY_SECTOR, MY_KEY)) {
for (int k = 0; k < 1; ++k) {
int block = mfc.sectorToBlock(MY_SECTOR) + k;
byte[] data = null;
try {
// Read the block
data = mfc.readBlock(block);
} catch (IOException e) {
Log.e("IOException", "\n" + "Block " + block
+ " data: " + e.getMessage());
continue;
}
// Convert the data into a string from Hex format.
blockData = ByteArrayToHexString(data);
// reading first 8 bytes only
blockData = blockData.substring(0, 8);
}
if (blockData != null) {
mp = MediaPlayer.create(context, R.raw.served);
} else {
mp = MediaPlayer.create(context, R.raw.coins);
}
} else {
Toast.makeText(context, R.string.not_valid_rfid,
Toast.LENGTH_SHORT).show();
mp = MediaPlayer.create(context, R.raw.professionals);
}
mfc.close();
} catch (IOException e) {
mp = MediaPlayer.create(context, R.raw.coins);
Toast.makeText(context, R.string.error_while_scanning,
Toast.LENGTH_SHORT).show();
} catch (NullPointerException e) {
// TODO: handle exception
mp = MediaPlayer.create(context, R.raw.coins);
Toast.makeText(context, R.string.error_while_scanning,
Toast.LENGTH_SHORT).show();
}finally {
try {
if (mfc != null)
mfc.close();
if (mp != null)
mp.start();
} catch (IOException e) {
e.printStackTrace();
}
}
return blockData;
}
答案 0 :(得分:4)
某些NFC芯片不支持Mifare Classic卡。请参阅此hasMifareClassic()方法。
答案 1 :(得分:3)
您遇到的问题可能与升级到Android 5.1无关。相反,为标记获取MifareClassic
对象的实例仅适用于支持MIFARE Classic的平台。因此,
MifareClassic.get(tagFromIntent)
将在不支持MIFARE Classic的平台上返回null
。这实际上意味着您的应用只适用于恩智浦NFC芯片组的设备。
请注意,系统功能com.nxp.mifare
应该表明设备是否支持MIFARE Classic(请参阅ThomasRS的回答)。但是,许多供应商都没有费心去正确配置它。因此,使用
if (getPackageManager().hasSystemFeature("com.nxp.mifare")) { ... }
不是识别支持MIFARE Classic的设备的非常可靠的方法。