0

How to read nfc card with android phone,

The error written on the console is below, this application opens, but when I read the card to NFC, it gives an error,

Can you help me fix this code? How to read nfc card with android phone,

The error written on the console is below, this application opens, but when I read the card to NFC, it gives an error,

Can you help me fix this code?

D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.myapplication, PID: 17885
    java.lang.NullPointerException: Attempt to read from null array
        at com.example.myapplication.MainActivity.buildTagViews(MainActivity.java:126)
        at com.example.myapplication.MainActivity.readfromIntent(MainActivity.java:114)
        at com.example.myapplication.MainActivity.onNewIntent(MainActivity.java:180)
        at android.app.Activity.performNewIntent(Activity.java:8113)
        at android.app.Instrumentation.callActivityOnNewIntent(Instrumentation.java:1410)
        at android.app.Instrumentation.callActivityOnNewIntent(Instrumentation.java:1423)
        at android.app.ActivityThread.deliverNewIntents(ActivityThread.java:3724)
        at android.app.ActivityThread.handleNewIntent(ActivityThread.java:3736)
        at android.app.servertransaction.NewIntentItem.execute(NewIntentItem.java:53)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2108)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:236)
        at android.app.ActivityThread.main(ActivityThread.java:7876)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:656)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)
D/OOMEventManagerFK: checkEventAndDumpForJE: 0
I/Process: Sending signal. PID: 17885 SIG: 9

`public class MainActivity extends AppCompatActivity {

public static final String Error_Detected = "No NFC Tag Detected";
public static final String Write_Success = "Text Written Successfully!";
public static final String Write_Error = "Error During Writing, Try Again!";
NfcAdapter nfcAdapter;
PendingIntent pendingIntent;
IntentFilter writingTagFilters[];
boolean writeMode;
Tag myTag;
Context context;
TextView edit_message;
TextView nfc_contents;
Button ActivateButton;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    edit_message = (TextView) findViewById(R.id.edit_message);
    nfc_contents = (TextView) findViewById(R.id.nfc_contents);
    ActivateButton = (Button) findViewById(R.id.ActivateButton);
    context = this;
    ActivateButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            try {
                if(myTag == null){

                    Toast.makeText(context,Error_Detected,Toast.LENGTH_LONG).show();

                }else {
                    write("PlainTset|" + edit_message.getText().toString(),myTag);
                    Toast.makeText(context,Write_Success,Toast.LENGTH_LONG).show();

                }

            } catch (IOException e) {

                Toast.makeText(context,Write_Error,Toast.LENGTH_LONG).show();
                e.printStackTrace();

            }catch (FormatException e){
                Toast.makeText(context,Write_Error,Toast.LENGTH_LONG).show();
                e.printStackTrace();
            }




        }
    });

    nfcAdapter = NfcAdapter.getDefaultAdapter(this);
    if(nfcAdapter == null){

        Toast.makeText(this,"This device does not support NFC",Toast.LENGTH_LONG).show();
        finish();

    }
    readfromIntent(getIntent());
    pendingIntent = PendingIntent.getActivity(this,0,new Intent(this,getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),0);
    IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
    tagDetected.addCategory(Intent.CATEGORY_DEFAULT);
    writingTagFilters = new IntentFilter[] { tagDetected };

}

private void readfromIntent(Intent intent){
    String action = intent.getAction();
    if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
        || NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)
            || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)){

        Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
        NdefMessage[] msgs = null;
        if(rawMsgs != null){
            msgs = new NdefMessage[rawMsgs.length];
            for (int i = 0; i < rawMsgs.length; i++) {

                msgs[i] = (NdefMessage) rawMsgs[i];

            }
        }

        buildTagViews(msgs);



    }

}

private void buildTagViews(NdefMessage[] msgs){
    if (msgs == null || msgs.length == 0){

        String text = "";
        byte[] payload = msgs[0].getRecords()[0].getPayload();
        String textEncoding = ((payload[0] & 128) == 0) ? "UTF-8" : "UTF-16";
        int languageCodeLength = payload[0] & 0063;

        try {
            text = new String(payload,languageCodeLength+1, payload.length - languageCodeLength - 1, textEncoding);
        } catch (UnsupportedEncodingException e) {
            Log.e("UnsupportedEncoding", e.toString());
        }

        Log.d("myTag", text);

        nfc_contents.setText("NFC Content" + text);

    }

}

private void  write (String text,Tag tag) throws IOException,FormatException{
    NdefRecord[] records = { createRecord(text) };
    NdefMessage message = new NdefMessage(records);

    Ndef ndef = Ndef.get(tag);

    ndef.connect();

    ndef.writeNdefMessage(message);

    ndef.close();

}
private NdefRecord createRecord(String text) throws UnsupportedEncodingException {

    String lang      ="en";
    byte[] textBytes = text.getBytes();
    byte[] langBytes = lang.getBytes("US-ASCII");
    int langLength   = langBytes.length;
    int textLength   = textBytes.length;
    byte[] payload   = new byte[1 + langLength + textLength];

    payload[0] = (byte) langLength;

    System.arraycopy(langBytes,0,  payload,1, langLength);
    System.arraycopy(textBytes,0,payload,1 + langLength,textLength);

    NdefRecord recordNFC = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], payload);

    return recordNFC;
}
@Override
protected  void onNewIntent(Intent intent){

    super.onNewIntent(intent);
    setIntent(intent);
    readfromIntent(intent);
    if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())){

        myTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

    }
}
@Override
public void onPause(){
    super.onPause();
    WriteModeOff();

}
@Override
public void onResume(){
    super.onResume();
    WriteModeOn();

}
private void WriteModeOn(){
    writeMode = true;
    nfcAdapter.enableForegroundDispatch(this, pendingIntent, writingTagFilters,null);
}
private void WriteModeOff(){
    writeMode = false;
    nfcAdapter.disableForegroundDispatch(this);
}

} `

1 Answers1

0

Simple logic error

In buildTagViews

The line if (msgs == null || msgs.length == 0){

Logically says if we have no msgs then try and process the non existent msgs, thus when you try to access msgs you get the null pointer.

Should be if (msgs != null && msgs.length != 0){

But probably the underlying reasons for the null msgs is that you are trying to extract NDef messages from events that might not have any.

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

should be

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

as ACTION_TAG_DISCOVERED and ACTION_TECH_DISCOVERED can also be triggered by NFC Tags that have no Ndef messages.

Andrew
  • 8,198
  • 2
  • 15
  • 35
  • I'm reading an nfc card, nfc reading sound is heard on the phone, but the console keeps blank information I/AdrenoGLES-0: Build Config : S P 10.0.6 AArch64 I/AdrenoGLES-0: Driver Path : /vendor/lib64/egl/libGLESv2_adreno.so I/AdrenoGLES-0: PFP: 0x016ee190, ME: 0x00000000 E/LB: fail to open file: No such file or directory W/System: A resource failed to call close. W/System: A resource failed to call close. D/tag: null D/tag: null – Ufuk Sipor Mar 21 '23 at 12:47
  • Using `enableForegroundDispatch` is not the best API to use for NFC `enableReaderMode` is better. But the other problem with your code that might cause this is that your `IntentFilter` is asking to be notified about all Tag's again even if they don't/can't store Ndef Data to read. There are also other problems with your code as you should not be writing to NFC from the main thread. Instead of trying to fix all the problems use `enableReaderMode` instead, an example https://stackoverflow.com/questions/64920307/how-to-write-ndef-records-to-nfc-tag/64921434#64921434 – Andrew Mar 21 '23 at 14:07