0

enter image description here I am newbie java programmer working on a NFC reader project. I've been trying to read the content of a NFC card in Android but I can't get it to work. I can only retrieve the UID of the NFC card. I went through documentation for NFC in Android and also some tutorials but I don't really understand it. I've searched a lot but I didn't a clear solution or article about reading Mifare Classic 1K text records. How can I achieve that? Really I don't know anything so please excuse me if the question is a little bit unclear. I'm using the NFC tools desktop app to write text records(screenshot below) I will appreciate any help. Thanks in advance

Here the code snippet I am using to fetch records after getting the intent on android


    private void readFromIntent(Intent intent) {
        System.out.println("Came huered ");
        String action = intent.getAction();
        if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
                || NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)
                || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
           
            Parcelable[] rawMessages = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
            NdefMessage[] messages ;
            
            if (rawMessages != null) {
                messages = new NdefMessage[rawMessages.length];
                for (int i = 0; i < rawMessages.length; i++) {
                    messages[i] = (NdefMessage) rawMessages[i];
                    NdefRecord [] records = messages[i].getRecords();
                    System.out.println("RECORDS "+records);
                    //if you are sure you have text then you don't need to test TNF
                    for(NdefRecord record: records){
                        processRecord(record);
                    }
                }
            }
        }
    }
public void processRecord(NdefRecord record) {

        short tnf = record.getTnf();
        switch (tnf) {


            case NdefRecord.TNF_MIME_MEDIA: {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    if (record.toMimeType().equals("MIME/Type")) {
                        // handle this as you want
                        System.out.println("HEREEEE");
                    } else {
                        //Record is not our MIME
                    }
                }
            }
            // you can write more cases
            default: {
                //unsupported NDEF Record
            }
        }
    }
Andrew
  • 8,198
  • 2
  • 15
  • 35
  • Have you checked to see if Mifare Classic cards are supported on your Android Hardware? Mifare Classic Cards do not conform to the NFC standards and are not supported on all Android Hardware. Also for people to help you should show what code you have done so far in your attempts to read these cards. – Andrew May 17 '22 at 10:19
  • @Andrew thanks for your response. Yes the Mifare classic cards are supported on my device. – Ousmane Elhadji May 17 '22 at 10:31
  • How are you causing the `Intent` with the Tag data to be delivered to your App? Do you have manifest entries so the system starts your App and deliver the `Intent` with Tag data in it for reading in `onCreate`or have you used `enableForegroundDispatch` for it to be delivered to `onNewIntent`? – Andrew May 17 '22 at 10:54
  • onNewIntent I tried to trigger the ACTION_TAG_DISCOVERED action and it is reading the Tag. Yes everything is configured in my manifest file. I also used enableForegroundDispach in my onResume method. here the link to my file: https://github.com/ousmane12/FizzBuzz/blob/master/ScanActivity.java – Ousmane Elhadji May 17 '22 at 11:17

1 Answers1

0

Your Processing of the record is not looking for a Ndef Text Record.

case NdefRecord.TNF_MIME_MEDIA: {

is not right for Text records

use

short tnf = record.getTnf();
byte[] type = record.getType();

if (tnf == NdefRecord.TNF_WELL_KNOWN &&
        Arrays.equals(type, NdefRecord.RTD_TEXT) {
  // Correct TNF and Type for Text record
  // Now process the Text Record encoding
}

Note as toMimeType does actually convert RTD_TEXT to a mime Type but for that

if (record.toMimeType().equals("MIME/Type")) {

would need to be

if (record.toMimeType().equals("text/plain")) {

For processing the Text record see https://stackoverflow.com/a/59515909/2373819

update

Should have also said that

if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
                || NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)
                || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {

is wrong as your are trying to parse for Ndef data when the Tag does not have Ndef data in it.

should be

if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {

update2 I checked out the github link to the code you gave

It won't trigger on Ndef records because you are testing for the wrong type of Intent

The Intent dispatch system only sends the highest type of NFC Intent possible with the order as:-

ACTION_NDEF_DISCOVERED -> ACTION_TECH_DISCOVERED -> ACTION_TAG_DISCOVERED

Therefore if the Tag contains NDEF data only the action type of ACTION_NDEF_DISCOVERED is set.

Thus

public void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        if (intent.getAction().equals(NfcAdapter.ACTION_TAG_DISCOVERED)) {
...

will never trigger the processing of the Intent

that code should be

public void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        if (intent.getAction().equals(NfcAdapter.ACTION_NDEF_DISCOVERED)) {
...
Andrew
  • 8,198
  • 2
  • 15
  • 35
  • Thank you for your answer. I am going to try and get back to you – Ousmane Elhadji May 17 '22 at 11:41
  • I tried your solution but it doesn't even trigger the processRecord method because the intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES) is null – Ousmane Elhadji May 17 '22 at 12:09
  • I just saw your updates. I replaced my onNewIntent but seems like I am not getting that intent at all – Ousmane Elhadji May 17 '22 at 12:55
  • Using `enableForegroundDispatch` is not the best API and it has a number of flaws, there is a better and newer NFC API called `enableReaderMode` an example of that is at https://stackoverflow.com/a/64921434/2373819 – Andrew May 17 '22 at 13:00
  • Thank you for your guidance. I did that too but no change. I updated my code here https://github.com/ousmane12/FizzBuzz/blob/master/ScanActivity.java please check it out – Ousmane Elhadji May 17 '22 at 15:40
  • This leads me back to my first question "Have you checked to see if Mifare Classic cards are supported on your Android Hardware?" How did you check this? As that code example is fully tested and works and it looks like you implemented it OK. I suggest you use the NXP TagInfo App https://play.google.com/store/apps/details?id=com.nxp.taginfolite&gl=US and list the Tag technology details from a full scan of the card. – Andrew May 17 '22 at 15:57
  • I am using a sunmi V2s pro hardware and as its technical specifications it supports Mifare Classic cards. Alright I'll download that app thanks – Ousmane Elhadji May 18 '22 at 09:25
  • @Andrew Could you please check [this question](https://stackoverflow.com/questions/72431616/android-nfc-mifare-classic-restore-and-transfer-not-working)? – ysfcyln May 31 '22 at 11:11