Reputation: 445
Good morning, I would like to use the write method I found on the page: https://developer.android.com/guide/topics/connectivity/nfc/advanced-nfc.html, to write on an ultralight mifare. I have not yet succeeded.
public void writeTag(Tag tag, String tagText) {
MifareUltralight ultralight = MifareUltralight.get(tag);
try {
ultralight.connect();
ultralight.writePage(4, "abcd".getBytes(Charset.forName("US-ASCII")));
ultralight.writePage(5, "efgh".getBytes(Charset.forName("US-ASCII")));
ultralight.writePage(6, "ijkl".getBytes(Charset.forName("US-ASCII")));
ultralight.writePage(7, "mnop".getBytes(Charset.forName("US-ASCII")));
} catch (IOException e) {
Log.e(TAG, "IOException while closing MifareUltralight...", e);
} finally {
try {
ultralight.close();
} catch (IOException e) {
Log.e(TAG, "IOException while closing MifareUltralight...", e);
}
}
}
How do I call it from the main?
I think it would be necessary to insert a button to check if the tag is present.
I added the "foreground dispatch system" to my activity (not the main activity) but I still do not understand how to make a message appear if the tag is present or not, what to check before using read and write methods?
package com.example.administrator.myapplication3;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.MifareUltralight;
import android.nfc.tech.Ndef;
import android.nfc.tech.NfcA;
import android.nfc.tech.NfcB;
import android.nfc.tech.NfcF;
import android.nfc.tech.NfcV;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.io.IOException;
import java.nio.charset.Charset;
public class DisplayMessageActivity extends AppCompatActivity {
private NfcAdapter mAdapter;
private PendingIntent pendingIntent;
private IntentFilter[] mFilters;
private String[][] mTechLists;
private static final String TAG = MainActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_message);
// Get the Intent that started this activity and extract the string
Intent intent = getIntent();
String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
// Capture the layout's TextView and set the string as its text
TextView textView = (TextView) findViewById(R.id.textView);
textView.setText(message);
pendingIntent = PendingIntent.getActivity( this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
mAdapter = NfcAdapter.getDefaultAdapter(this);
pendingIntent = PendingIntent.getActivity(
this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
// Setup an intent filter for all MIME based dispatches
IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
try {
ndef.addDataType("*/*");
} catch (IntentFilter.MalformedMimeTypeException e) {
throw new RuntimeException("fail", e);
}
IntentFilter td = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
mFilters = new IntentFilter[] {
ndef, td
};
// Setup a tech list for all NfcF tags
mTechLists = new String[][] { new String[] { MifareUltralight.class.getName(), Ndef.class.getName(), NfcA.class.getName()}};
Button b = (Button) findViewById(R.id.button2);
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
TextView tv = (TextView) findViewById(R.id.textView);
Tag tag = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);
tv.setText("Click!");
//byte[] x=tag.getId();
writeTag(tag,"x");
Log.e(TAG,"cc");
}
});
}
@Override
public void onResume()
{
super.onResume();
mAdapter.enableForegroundDispatch(this, pendingIntent, mFilters, mTechLists);
}
@Override
public void onPause()
{
super.onPause();
mAdapter.disableForegroundDispatch(this);
}
@Override
public void onNewIntent(Intent intent){
// fetch the tag from the intent
Tag t = (Tag)intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
// String tlist = getTechList(t);
// android.util.Log.v("NFC", "Discovered tag ["+tlist+"]["+t+"] with intent: " + intent);
// android.util.Log.v("NFC", "{"+t+"}");
}
public void writeTag(Tag tag, String tagText) {
MifareUltralight ultralight = MifareUltralight.get(tag);
try {
ultralight.connect();
ultralight.writePage(4, "abcd".getBytes(Charset.forName("US-ASCII")));
ultralight.writePage(5, "efgh".getBytes(Charset.forName("US-ASCII")));
ultralight.writePage(6, "ijkl".getBytes(Charset.forName("US-ASCII")));
ultralight.writePage(7, "mnop".getBytes(Charset.forName("US-ASCII")));
} catch (IOException e) {
Log.e(TAG, "IOException while closing MifareUltralight...", e);
} finally {
try {
ultralight.close();
} catch (IOException e) {
Log.e(TAG, "IOException while closing MifareUltralight...", e);
}
}
}
public String readTag(Tag tag) {
MifareUltralight mifare = MifareUltralight.get(tag);
try {
mifare.connect();
byte[] payload = mifare.readPages(4);
return new String(payload, Charset.forName("US-ASCII"));
} catch (IOException e) {
Log.e(TAG, "IOException while writing MifareUltralight message...", e);
} finally {
if (mifare != null) {
try {
mifare.close();
}
catch (IOException e) {
Log.e(TAG, "Error closing tag...", e);
}
}
}
return null;
}
}
Thanks!
Upvotes: 7
Views: 721
Reputation: 396
onNewIntent(Intent intent) gets called as soon as a new NFC tag is scanned. So for example, if you wanted to write onto every scanned tag, your onNewIntent() method would look like this:
//This method is called whenever a new tag is scanned while the activity is running
//Whatever you want to do with scanned tags, do it in here
@Override
public void onNewIntent(Intent intent){
// fetch the tag from the intent
Tag tag = (Tag)intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
//Write a String onto the tag
writeTag(tag, "Put any string here");
}
Your writeTag method of course is still not using the String its been given, but you probably know that.
If you want to instead keep a boolean up to date that you can check for available tags, do the following:
@Override
public void onNewIntent(Intent intent){
(new Thread(new Runnable() {
@Override
public void run() {
// fetch the tag from the intent
Tag tag = (Tag)intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
MifareUltralight myTag = MifareUltralight.get(tag);
/* Alternative to MifareUltralight:
NfcA myTag = NfcA.get(tag);
*/
myTag.connect();
while(true){
//someBoolean is just a Boolean that you can use in other threads to ask if tag is still there
someBoolean = true;
//Keep reading the tag until it ends in an exception
//when the exception occurs, you know the tag is gone
try{
myTag.transceive(new byte[] {
(byte) 0xXX, // READ command for your tag here
(byte) 0xXX, // Address of serial or UID field of your tag here
});
}catch(IOException e){
myTag.disconnect();
break;
}
}
//When loop breaks, the tag is gone, so we set the variable back to false
someBoolean = false;
}
})).start();
}
Upvotes: 5
Reputation: 396
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<tech-list>
<tech>android.nfc.tech.NfcA</tech>
</tech-list>
<tech-list>
<tech>android.nfc.tech.Ndef</tech>
</tech-list>
</resources>
This is what my xml file looks like. MifareUltralight and NfcA are pretty much interchangable. Just use NfcA and it should work.
Upvotes: 0