Question

I followed a tutorial on how to write a NDEF message to a tag. and now when I run it. it detects the tag and when I press the button to write the message and the app crashes. it gives me JAVA.LANG.ArrayIndexOutOfBoundsException can someone please help me on what I'm doing wrong.

this is the error I see in logcat.enter image description here

any help is appreciated.

Here is the code:

import java.io.IOException;
import java.io.UnsupportedEncodingException;

import android.nfc.FormatException;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.Ndef;
import android.os.Bundle;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class WriteMessage extends Activity {

    NfcAdapter adapter;
    PendingIntent pendingIntent;
    IntentFilter writeTagFilters[];
    boolean writeMode;
    Tag myTag;
    Context ctx;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_write_message);
        ctx=this;

        Button WriteTag = (Button) findViewById (R.id.WriteTag);
        final TextView Message = (TextView) findViewById (R.id.MessageBox);

        WriteTag.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                try{
                    if(myTag==null){
                        Toast.makeText(ctx, "Error_detected", Toast.LENGTH_LONG).show();
                    }else{
                        write(Message.getText().toString(), myTag);
                        Toast.makeText(ctx, "Ok_Writing", Toast.LENGTH_LONG).show();
                    }
                }catch(IOException e){
                    Toast.makeText(ctx, "Error_Writing", Toast.LENGTH_LONG).show();
                    e.printStackTrace();

                //} catch(FormatException e){

                    e.printStackTrace();
                } catch (FormatException e) {
                    // TODO Auto-generated catch block
                    Toast.makeText(ctx, "Error_Writing", Toast.LENGTH_LONG).show();
                    e.printStackTrace();
                }



        }
        });

        adapter = NfcAdapter.getDefaultAdapter(this);
        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);
        writeTagFilters = new IntentFilter[] {tagDetected };

    }




    private void write(String text, Tag myTag)throws IOException, FormatException {

        NdefRecord[] records = {createRecord(text)};
        NdefMessage message = new NdefMessage(records);
        Ndef ndef = Ndef.get(myTag);
        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(langBytes, 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){
        if(NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())){
            myTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);    
            Toast.makeText(this, "ok_detection" + myTag.toString(), Toast.LENGTH_LONG ).show();
        }
    }

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

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

    private void WriteModeOn(){
        writeMode = true;
        adapter.enableForegroundDispatch(this, pendingIntent, writeTagFilters, null);
    }

    private void WriteModeOff(){
        writeMode = false;
        adapter.disableForegroundDispatch(this);
    }



}
Was it helpful?

Solution

Looks like createRecord() is copying langBytes into payload twice instead of copying textBytes, but with the length of textBytes. If textBytes is longer than langBytes, it won't find enough data to copy from the source.

See the documentation on arraycopy.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top