1

I'm using PN512 in card emulation mode as a NFC tag and am developing an Android application to read and write into the tag. The problem is, as long as the tag is in the NFC field, the program will keep reading and writing to the tag, but I want stop the program from overwriting the same tag once successfully writen. Are there any solutions for that?

(I know there is no way to programmatically disable NFC based on Android SDK)

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    btn = (Button) findViewById(R.id.btn_OK);
    mEditText = (EditText) findViewById(R.id.text_username);
    btn.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            prefs = getSharedPreferences(prefName, MODE_PRIVATE);
            SharedPreferences.Editor editor = prefs.edit();
            editor.putString(TEXT_VALUE_KEY, mEditText.getText().toString());
            editor.commit();

            String outtxt = "please touch and hold phone to tag";
            Toast toastedit12 = Toast.makeText(getApplicationContext(), outtxt, Toast.LENGTH_SHORT);
            toastedit12.show();
        }
    });

    resolveIntent(getIntent());
}


// This method/task executes when the tag is read
void resolveIntent(Intent intent)
{
    NdefMessage msg1, msg2;
    // Parse the intent
    String action = intent.getAction();

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

        try
        {
            mRecord=createRecord();
        }
        catch (Exception e)
        {
            Toast toaste = Toast.makeText(getApplicationContext(), "exception in call to create record", Toast.LENGTH_SHORT);
            toaste.show();
        }

        // When a tag is discovered we send it to the service to be save. We
        // include a PendingIntent for the service to call back onto. This
        // will cause this activity to be restarted with onNewIntent(). At
        // that time we read it from the database and view it.
       Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
       NdefMessage[] msgs;

       if (rawMsgs != null)
       {
            msgs = new NdefMessage[rawMsgs.length];
            for (int i = 0; i < rawMsgs.length; i++)
            {
                msgs[i] = (NdefMessage) rawMsgs[i];
            }

            msg1 = msgs[0];
            myPayload=msg1.getRecords()[0].getPayload();
        }
        else {
            // Unknown tag type
            byte[] empty = new byte[] {};
            NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN, empty, empty, empty);
            msg2 = new NdefMessage(new NdefRecord[] {record});
            msgs = new NdefMessage[] {msg2};
        }
        writeToNfcTag(intent);
    }


    public NdefRecord createRecord() throws UnsupportedEncodingException {
        SharedPreferences prefs = getSharedPreferences(prefName, MODE_PRIVATE);
        mEditText.setText(prefs.getString(TEXT_VALUE_KEY, "def"))

        String lang       = "en";

        byte[] textBytes  = mEditText.getText().toString().getBytes();

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

        // Set status byte (see NDEF spec for actual bits)
        payload[0] = (byte) langLength;

        // Copy langbytes and textbytes into payload
        System.arraycopy(langBytes, 0, payload, 1, langLength);
        System.arraycopy(textBytes, 0, payload, 1+langLength, textLength);
        NdefRecord record = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,
                                           NdefRecord.RTD_TEXT,
                                           new byte[0],
                                           payload);
        return record;
    }


    public void writeToNfcTag(Intent intent)
    {
        Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        try
        {
            write(tag);
        }
        catch (Exception e)
        {
            // Toast this; bail
        }
    }


    public void write(Tag tag) throws IOException, FormatException {
        NdefRecord[] records = { mRecord };
        NdefMessage  message = new NdefMessage(records);

        // Get an instance of Ndef for the tag.
        Ndef ndef = Ndef.get(tag);

        // Enable I/O
        ndef.connect();

        // Write the message
        ndef.writeNdefMessage(message);

        // Close the connection
        ndef.close();

        Intent myIntent = null;
        myIntent = new Intent(MyAndroidAppActivity.this, TagDeactivatedActivity.class);

        myIntent.setFlags(myIntent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(myIntent);
        finish();
    }
}
4

2 回答 2

3

在您写入标签后,您可以执行此操作,但请记住,此过程是不可逆的。

    Ndef ndef = Ndef.get(tag);  
    if (ndef != null) { 
        ndef.makeReadOnly();
    }
于 2014-08-06T20:06:09.047 回答
-1

是的,可以使活动只读取和写入标签一次。我通过将标志声明为全局变量并使用该标志来控制我的标签读写来解决了我的问题。

在您的班级中将标志声明为布尔值。认为 :

public class YourClass{
Boolean flag= false;
.
.
.
.
void resolveIntent(Intent intent)
{
    NdefMessage msg1, msg2;
// Parse the intent
    String action = intent.getAction();
if(flag== false){
flag = true;
    if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action) ||
        NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {

        try
        {
            mRecord=createRecord();
        }
        catch (Exception e)
        {
            Toast toaste = Toast.makeText(getApplicationContext(), 
"exception in call to create record", Toast.LENGTH_SHORT);
            toaste.show();
        }

        // When a tag is discovered we send it to the service to be save. We
        // include a PendingIntent for the service to call back onto. This
        // will cause this activity to be restarted with onNewIntent(). At
        // that time we read it from the database and view it.
       Parcelable[] rawMsgs = 
intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
       NdefMessage[] msgs;

       if (rawMsgs != null)
       {
            msgs = new NdefMessage[rawMsgs.length];
            for (int i = 0; i < rawMsgs.length; i++)
            {
                msgs[i] = (NdefMessage) rawMsgs[i];
            }

            msg1 = msgs[0];
            myPayload=msg1.getRecords()[0].getPayload();
        } 
        else {
            // Unknown tag type
            byte[] empty = new byte[] {};
            NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN, 
empty, empty, empty);
            msg2 = new NdefMessage(new NdefRecord[] {record});
            msgs = new NdefMessage[] {msg2};
        }
        writeToNfcTag(intent);
       }
    }
.
.
.
.
}

希望能帮助到你。

于 2017-05-02T02:13:13.520 回答