I'm trying to create an application for smartphones that will copy the NFC tag. I was faced with the problem of inability in some cases to have a label for the tag type.
There is a method:
/**
* Callback when a new tag is discovered by the system.
* <p>
* <p>Communication with the card should take place here.
*
* @param tag Discovered tag
*/
@Override
public void onTagDiscovered(Tag tag) {
... ... ... ... ... ...
MifareClassic mifareClassic = MifareClassic.get(tag);
if (mifareClassic != null) {
mAccountCallback.get().onTagsTypeReceived(
TECH_TYPE_MFR_CLASS, mifareClassic.getType());
mAccountCallback.get().onMifareClassicReceived(mifareClassic);
}
... ... ... ... ... ...
NfcA nfcA = NfcA.get(tag);
if (nfcA != null) {
mAccountCallback.get().onNfcAReceived(nfcA);
}
... ... ... ... ... ...
}
For the tag, which contains the list of MifareUltralight MifareClassic technology or access type of label is through the method:
.getType()
But if these technologies are not available, this method becomes unavailable. However, by reading the same labels you use the PC-connected reader b programs Arduino 1.8.5 their data is read without problems:
A screenshot of the monitor output from programs Arduino 1.8.5
What to do to be able to type any labels?
For an arbitrary NFC tag task yet failed to solve. The solution is found only for NFC type A. the Document company "NXP Semiconductors" AN10833 "MIFARE Type Identification Procedure" in section 3.2 Coding of Select Acknowledge (SAK) defines the corresponding values of SAK different types of tags. On the basis of this code has appeared:
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
String type = "";
int mSak = (int) (sak & 0x7F);
if (mTagType.getText().toString().equals(getString(R.string.tag_type))) {
switch (mSak) {
case 0x04:
type = getString(R.string.sak_indicates_uid_is_not_complete);
break;
case 0x09:
type = getString(R.string.mifare_classic_protocol_320_bytes);
break;
case 0x08:
type = getString(R.string.mifare_classic_protocol_1kb);
break;
case 0x18:
type = getString(R.string.mifare_classic_protocol_4kb);
break;
case 0x00:
type = getString(R.string.mifare_ultralight_or_ultralight_c);
break;
case 0x10:
case 0x11:
type = getString(R.string.mifare_plus);
break;
case 0x01:
type = getString(R.string.only_mentioned_in_nxp_an_10833_mifare_type_identification_procedure);
break;
case 0x20:
type = getString(R.string.picc_compliant_with_iso_iec_14443_4);
break;
case 0x40:
type = getString(R.string.picc_compliant_with_iso_iec_18092_nfc);
break;
default:
type = getString(R.string.picc_type_unknown);
break;
}
mTagType.setText(type);
}
}
});
To get the value SAK is the method of the class android.nfc.tech.NfcA:
.getSak()