How can I send a simple String using NFC - android

I am designing an app that needs to transfer a simple string using NFC, I have tried with multiple devices and still not working, something seems to be going wrong even though this is code snippet was taken directly from the android developer website
1 here is the code I have tried with no luck:(
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_nfcdisplay);
TextView textView = (TextView) findViewById(R.id.nfctesttext);
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (mNfcAdapter == null) {
Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show();
finish();
return;
}
// Register callback
mNfcAdapter.setNdefPushMessageCallback(this, this);
}
#Override
public NdefMessage createNdefMessage(NfcEvent nfcEvent) {
String text = ("Beam me up, Android!\n\n" +
"Beam Time: " + System.currentTimeMillis());
NdefMessage msg = new NdefMessage(
new NdefRecord[] { createMime(
"application/vnd.com.example.android.beam", text.getBytes())
/**
* The Android Application Record (AAR) is commented out. When a device
* receives a push with an AAR in it, the application specified in the AAR
* is guaranteed to run. The AAR overrides the tag dispatch system.
* You can add it back in to guarantee that this
* activity starts when receiving a beamed message. For now, this code
* uses the tag dispatch system.
*/
//,NdefRecord.createApplicationRecord("com.example.android.beam")
});
return msg;
}
#Override
public void onResume() {
super.onResume();
// Check to see that the Activity started due to an Android Beam
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
processIntent(getIntent());
}
}
#Override
public void onNewIntent(Intent intent) {
// onResume gets called after this to handle the intent
setIntent(intent);
}
/**
* Parses the NDEF Message from the intent and prints to the TextView
*/
void processIntent(Intent intent) {
textView = (TextView) findViewById(R.id.textView);
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(
NfcAdapter.EXTRA_NDEF_MESSAGES);
// only one message sent during the beam
NdefMessage msg = (NdefMessage) rawMsgs[0];
// record 0 contains the MIME type, record 1 is the AAR, if present
textView.setText(new String(msg.getRecords()[0].getPayload()));
}
}

Related

Stay in current activity upon NFC reception

I have an application that seems to work fine and can transmit data via NFC perfectly well. I have a main activity, an activity to transmit the data, and a different activity to receive data.
The sender activity works great, but when the receiver gets the NFC intent, it restarts the app back to the main activity.
I'm not exactly sure why this is. I would like it to decline any pushes unless the user is already in that activity, and if they are, to stay in that activity and handle the NFC intent.
Here is the manifest:
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".Timer" />
<activity android:name=".AddSlaves"
android:label="Add Slave Devices"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
<activity android:name=".JoinSrv"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
Here is the sender class:
public class JoinSrv extends Activity implements NfcAdapter.OnNdefPushCompleteCallback, NfcAdapter.CreateNdefMessageCallback {
//The array lists to hold our messages
private ArrayList<String> messagesToSendArray = new ArrayList<>();
private ArrayList<String> messagesReceivedArray = new ArrayList<>();
//Text boxes to add and display our messages
private NfcAdapter mNfcAdapter;
//Save our Array Lists of Messages for if the user navigates away
#Override
public void onSaveInstanceState(#NonNull Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putStringArrayList("messagesToSend", messagesToSendArray);
savedInstanceState.putStringArrayList("lastMessagesReceived", messagesReceivedArray);
}
//Load our Array Lists of Messages for when the user navigates back
#Override
public void onRestoreInstanceState(#NonNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
messagesToSendArray = savedInstanceState.getStringArrayList("messagesToSend");
messagesReceivedArray = savedInstanceState.getStringArrayList("lastMessagesReceived");
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_join_srv);
//Check if NFC is available on device
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (mNfcAdapter != null) {
//Handle some NFC initialization here
} else {
Toast.makeText(this, "NFC not available on this device",
Toast.LENGTH_SHORT).show();
}
//Check if NFC is available on device
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (mNfcAdapter != null) {
//This will refer back to createNdefMessage for what it will send
mNfcAdapter.setNdefPushMessageCallback(this, this);
//This will be called if the message is sent successfully
mNfcAdapter.setOnNdefPushCompleteCallback(this, this);
}
}
#Override
public NdefMessage createNdefMessage(NfcEvent event) {
//This will be called when another NFC capable device is detected.
//We'll write the createRecords() method in just a moment
NdefRecord[] recordsToAttach = createRecords();
//When creating an NdefMessage we need to provide an NdefRecord[]
return new NdefMessage(recordsToAttach);
}
#Override
public void onNdefPushComplete(NfcEvent event) {
//This is called when the system detects that our NdefMessage was
//Successfully sent.
messagesToSendArray.clear();
}
public NdefRecord[] createRecords() {
NdefRecord[] records = new NdefRecord[1];
//To Create Messages Manually if API is less than
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
byte[] payload = "192.168.1.100".
getBytes(Charset.forName("UTF-8"));
NdefRecord record = new NdefRecord(
NdefRecord.TNF_WELL_KNOWN, //Our 3-bit Type name format
NdefRecord.RTD_TEXT, //Description of our payload
new byte[0], //The optional id for our Record
payload); //Our payload for the Record
records[1] = record;
}
//Api is high enough that we can use createMime, which is preferred.
else {
byte[] payload = "192.168.1.100".
getBytes(Charset.forName("UTF-8"));
NdefRecord record = NdefRecord.createMime("text/plain",payload);
records[1] = record;
}
records[messagesToSendArray.size()] =
NdefRecord.createApplicationRecord(getPackageName());
return records;
}
private void handleNfcIntent(Intent NfcIntent) {
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(NfcIntent.getAction())) {
Parcelable[] receivedArray =
NfcIntent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (receivedArray != null) {
messagesReceivedArray.clear();
NdefMessage receivedMessage = (NdefMessage) receivedArray[0];
NdefRecord[] attachedRecords = receivedMessage.getRecords();
for (NdefRecord record : attachedRecords) {
String string = new String(record.getPayload());
//Make sure we don't pass along our AAR (Android Application Record)
if (string.equals(getPackageName())) {
continue;
}
messagesReceivedArray.add(string);
}
Toast.makeText(this, "Received " + messagesReceivedArray.size() +
" Messages", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "Received Blank Parcel", Toast.LENGTH_LONG).show();
}
}
}
#Override
public void onNewIntent(Intent intent) {
handleNfcIntent(intent);
}
#Override
public void onResume() {
super.onResume();
handleNfcIntent(getIntent());
}
}
Here is the receiver class:
public class AddSlaves extends Activity implements NfcAdapter.OnNdefPushCompleteCallback, NfcAdapter.CreateNdefMessageCallback{
//The array lists to hold our messages
private ArrayList<String> messagesToSendArray = new ArrayList<>();
private ArrayList<String> messagesReceivedArray = new ArrayList<>();
//Text boxes to add and display our messages
private EditText txtBoxAddMessage;
private TextView txtReceivedMessages;
private TextView txtMessagesToSend;
private NfcAdapter mNfcAdapter;
private void updateTextViews() {
txtReceivedMessages.setText("Messages Received:\n");
//Populate our list of messages we have received
if (messagesReceivedArray.size() > 0) {
for (int i = 0; i < messagesReceivedArray.size(); i++) {
txtReceivedMessages.append(messagesReceivedArray.get(i));
txtReceivedMessages.append("\n");
}
}
}
//Save our Array Lists of Messages for if the user navigates away
#Override
public void onSaveInstanceState(#NonNull Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putStringArrayList("lastMessagesReceived",messagesReceivedArray);
}
//Load our Array Lists of Messages for when the user navigates back
#Override
public void onRestoreInstanceState(#NonNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
messagesReceivedArray = savedInstanceState.getStringArrayList("lastMessagesReceived");
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_slaves);
txtReceivedMessages = (TextView) findViewById(R.id.txtMessagesReceived);
Button btnAddMessage = (Button) findViewById(R.id.buttonAddMessage);
//Check if NFC is available on device
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
if(mNfcAdapter != null) {
//Handle some NFC initialization here
}
else {
Toast.makeText(this, "NFC not available on this device",
Toast.LENGTH_SHORT).show();
}
//Check if NFC is available on device
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
if(mNfcAdapter != null) {
//This will refer back to createNdefMessage for what it will send
mNfcAdapter.setNdefPushMessageCallback(this, this);
//This will be called if the message is sent successfully
mNfcAdapter.setOnNdefPushCompleteCallback(this, this);
}
}
#Override
public NdefMessage createNdefMessage(NfcEvent event) {
//This will be called when another NFC capable device is detected.
return null;
}
#Override
public void onNdefPushComplete(NfcEvent event) {
//This is called when the system detects that our NdefMessage was
//Successfully sent.
messagesToSendArray.clear();
}
private void handleNfcIntent(Intent NfcIntent) {
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(NfcIntent.getAction())) {
Parcelable[] receivedArray =
NfcIntent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if(receivedArray != null) {
messagesReceivedArray.clear();
NdefMessage receivedMessage = (NdefMessage) receivedArray[0];
NdefRecord[] attachedRecords = receivedMessage.getRecords();
for (NdefRecord record:attachedRecords) {
String string = new String(record.getPayload());
//Make sure we don't pass along our AAR (Android Application Record)
if (string.equals(getPackageName())) { continue; }
messagesReceivedArray.add(string);
}
Toast.makeText(this, "Received " + messagesReceivedArray.size() +
" Messages", Toast.LENGTH_LONG).show();
updateTextViews();
}
else {
Toast.makeText(this, "Received Blank Parcel", Toast.LENGTH_LONG).show();
}
}
}
#Override
public void onNewIntent(Intent intent) {
handleNfcIntent(intent);
}
#Override
public void onResume() {
super.onResume();
updateTextViews();
handleNfcIntent(getIntent());
}
}
You have qute a few issues in your code of the sender activity:
You store messagesToSendArray, but you never actually fill this array list with data (i.e. messagesToSendArray.size() is always 0). Since you freshly create the NDEF message whenever createNdefMessage() is invoked, there is no need to save and restore messagesToSendArray.
You wrote that you want to send NDEF messages in one activity, but you want to receive NFC events in another activity. However, you registered your sender activity to receive NDEF_DISCOVERED events in the manifest. There is no need for the NDEF_DISCOVERED intent filter in the manifest if you do not want to receive and process these events.
Moreover, there is no need to handle the NDEF_DISCOVERED intent in your sender activity (i.e. you can safely remove the methods onNewIntent() and handleNfcIntent()).
On Android versions below Jelly Bean you create an NFC Forum Text record with an invalid structure. The Text RTD requres a payload that is encoded in the form (also see this post)
+----------+---------------+--------------------------------------+
| Status | Language Code | Text |
| (1 byte) | (n bytes) | (m bytes) |
+----------+---------------+--------------------------------------+
where Status equals to the length n of the Language Code if the Text is UTF-8 encoded and Language Code is an IANA language code (e.g. "en" for English). Consequently, the proper way to encode that record would be:
public static NdefRecord createTextRecord(String language, String text) {
byte[] languageBytes;
byte[] textBytes;
try {
languageBytes = language.getBytes("US-ASCII");
textBytes = text.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
throw new AssertionError(e);
}
byte[] recordPayload = new byte[1 + (languageBytes.length & 0x03F) + textBytes.length];
recordPayload[0] = (byte)(languageBytes.length & 0x03F);
System.arraycopy(languageBytes, 0, recordPayload, 1, languageBytes.length & 0x03F);
System.arraycopy(textBytes, 0, recordPayload, 1 + (languageBytes.length & 0x03F), textBytes.length);
return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, null, recordPayload);
}
It's unclear to me why you create an NFC Forum Text record on Android versions below Jelly Bean while you create a MIME type record on Jelly Bean and above. You should be consistent and create the same record type on all platforms (see Method NdefRecord.createTextRecord("en" , "string") not working below API level 21):
String text = "192.168.1.100";
String language = "en";
NdefRecord record;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
record = NdefRecord.createTextRecord(language, text);
} else {
record = createTextRecord(language, text);
}
Finally, in createRecords() you create the array records as
NdefRecord[] records = new NdefRecord[1];
Consequently, the array has one element accessible at index 0. Hoever, you try to access element 1 later on:
records[1] = record;
This results in an IndexOutOfBounds exception. Since createRecords() is called by Android through the createNdefMessage() callback, the callback fails (due to the runtime exception) and Android will not use your NDEF message. Instead, Android will use a default NDEF message for your app. This default NDEF message contains an Android Application record that will cause your main activity to be called (since none of your other activities are registered to be started for the specific contents of the default NDEF message); see NFC tag detection is not calling onNewIntent and it's Launching From Main Activity. Consequently, you need to change the offset in records where you store your newly created NDEF record to 0:
records[0] = record;
Moreover, you need to remove the line
records[messagesToSendArray.size()] =
NdefRecord.createApplicationRecord(getPackageName());
since this would then overwrite the previously stored NDEF record at index 0 (messagesToSendArray.size() is 0) with an Android Application record. Again, this would cause your main activity to be started since you did not register for that specific record type in your manifest.
Finally, if you want to decline pushes unless the user is inside the receiver activity, you should consider using the foreground dispatch system. In that case, you would complete remove all NDEF_DISCOVERED intent filters from your manifest and instead register each activity (receiver, sender, and main) with the foreground dispatch system. In the receiver, you would then receive the NDEF messages through onNewIntent(). In the sender and in the main activity, you would simply ignore and drop any received NDEF message. See Android app enable NFC only for one Activity for an example.

NFC Tag Reading

I got an application that reads and writes nfc tags with ndef data format. This all seems to be ok. But whenever i try to get closer a tag to my phone, it produces a new activity. I only want to obtain data on the tag without opening new intent. So i can make my app decide whether the tag has been tapped two times in a row.
The code that i handle coming tags:
public class MainActivity extends Activity {
public static Context myContext;
private Button myButton;
private int currentID, currentBalance;
protected void onCreate(Bundle savedInstanceState) { // Firstly Created when
// a tag tapped to
// the phone
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myButton = (Button) findViewById(R.id.button1);
currentID = 0;
currentBalance = 0;
myButton.setOnClickListener(new View.OnClickListener() { // Tag write
// function
// places
// here
public void onClick(View arg0) {
Intent i = new Intent(getApplicationContext(), nfcWrite.class);
i.putExtra("id",currentID);
i.putExtra("balance",currentBalance);
startActivity(i);
}
});
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
Intent intent = getIntent();
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefRecord myRecord = ((NdefMessage) rawMsgs[0]).getRecords()[0];
String nfcData = new String(myRecord.getPayload());
String[] splitData = nfcData.split("-");
currentID = Integer.parseInt(splitData[0]);
currentBalance = Integer.parseInt(splitData[1]);
Toast.makeText(getApplicationContext(), nfcData, Toast.LENGTH_LONG).show();
}
}
}
Add android:launchMode="singleTask" to the <activity> element for MainActivity. Note that if the activity is already running, onNewIntent() will be called, instead of onCreate(), to deliver the NDEF Intent to you. Hence, you will need to handle the NDEF Intent in both onCreate() (if the activity was not already running) and onNewIntent() (if the activity was already running).
This sample project illustrates the technique.
Instead of setting the launch-mode of the activity that receives the NFC intents to "singleTask" (see CommonsWare's answer), the preferred way for NFC applications to receive NFC-related intents while the app is in foreground is the foreground dispatch system (or alternatively the reader mode API when using only Android 4.4).
In order to use the foreground dispatch, you would create a pending intent like this:
PendingIntent pendingIntent = PendingIntent.getActivity(
this,
0,
new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),
0);
Then, in your activity's onResume() method, you would enable the foreground dispatch like this:
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
nfcAdapter.enableForegroundDispatch(this, pendingIntent, null, null);
You will then receive intents notifying you about discovered tags through the activity's onNewIntent() method:
public void onNewIntent(Intent intent) {
...
}
Moreover, you have to disable the foreground dispatch in your activity's onPause() method:
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
nfcAdapter.disableForegroundDispatch(this);

Sending URL from Android to Windows Phone via NFC gives Play Store link

I am trying to use NFC to send a URL from an Android app to a WP8 phone.
When beaming to an Android device, the URL is sent correctly. However, when beaming to WP8, IE loads a link to the Play Store instead of the one I want to send (e.g. "http://www.stackoverflow.com").
The Play Store link is: "https://play.google.com/store/apps/details?id=com.example.conductrnfc&feature=beam". Where "com.example.conductrnfc" is the package name in the project.
The code I used to generate the NFC message is given below. Is there something I'm doing wrong here that breaks compatibility with WP8?
NfcAdapter nfc = NfcAdapter.getDefaultAdapter(this);
nfc.setNdefPushMessageCallback(new NfcAdapter.CreateNdefMessageCallback() {
#Override
public NdefMessage createNdefMessage(NfcEvent event)
{
NdefRecord uriRecord = NdefRecord.createUri(urlString);
return new NdefMessage(new NdefRecord[] { uriRecord });
}
},
this);
Can you try this:
NfcAdapter nfc = NfcAdapter.getDefaultAdapter(this);
nfc.setNdefPushMessageCallback(new NfcAdapter.CreateNdefMessageCallback() {
#Override
public NdefMessage createNdefMessage(NfcEvent event)
{
byte[] payload = urlString.getBytes();
NdefRecord uriRecord = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI, new byte[0], payload);
return new NdefMessage(new NdefRecord[] { uriRecord });
}
},
this);
Eventhough I still miss some more debugging results from the OP, I thought I'd give it a shot:
As the discussion in the commands revealed that the createNdefMessage callback is not called when interacting with a WP8 phone, it would be interesting why this appens and how to prevent this. Unfortunately I have no details about the actual lifecycle of the activity, so I can only guess what might go wrong.
One reason why a registered createNdefMessage callback may not be called is that the activity that registered the callback is no longer in the foreground. So there may be a difference between an Android device and a WP8 device that causes the current activity to be paused.
Another reason would be that the WP8 device interupts communication before the Android NFC stack had the time to call the createNdefMessage callback method. However, this should be detectable as the Beam UI would typically disappear before the user is able to click it.
One cause for reason 1 may be that the WP8 device itself sends an NDEF message that causes intent processing on the Android device. If that's the case, a method to overcome this problem may be to register for the foreground dispatch system. This would prevent regular intent processing and would directly send all incoming NDEF messages to the current activity:
#Override
public void onResume() {
super.onResume();
NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this);
PendingIntent pi = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
adapter.enableForegroundDispatch(this, pi, null, null);
}
#Override
public void onNewIntent(Intent intent) {
if (intent != null) {
String action = intent.getAction();
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action) ||
NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action) ||
NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {
Log.d("NdefTest", "This problem was actually caused by an incoming NDEF message.");
}
}
}

send data from a broadcast to an activity . how to do send?

how to send data from a broadcatReceiver to an activity in android as saying catch the received SMS and send the SMS (is the data) to the activity its my first time that i work with broadcatReceiver so can anyone help me i will appreciate any help.
i read several tutorials about the data transferring that have some steps :
create a class that extends activity
create a class that extends broadcastReceiver
but i did not know how is the communication between these 2 classes.
I would do something like that:
public class YourActivity extends Activity
{
private Handler handler = null;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.id.main_layout);
this.handler = new Handler() {
#Override
public void handleMessage(Message msg)
{
SmsMessage sms = (SmsMessage) msg.obj;
String senderNumber = sms.getOriginatingAddress();
}
};
// Register a new receiver that will trigger on SMS_RECEIVED event
IntentFiler filer = new IntentFilert("android.provider.Telephony.SMS_RECEIVED");
registerReceiver(mSmsReceiver, filter);
}
#Override
protected void onDestroy()
{
super.onDestroy();
// Unregister the receiver
unregisterReceiver(mSmsReceiver);
}
private mSmsReceiver = new BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent)
{
Bundle bundle = intent.getExtras();
if (bundle == null || bundle.containsKey("pdus") return;
// Decode the message
SmsMessage sms = SmsMessage.createFromPdu((byte[]) pdus[0]);
// Notify the activity with the message
Message msg = new Message;
msg.obj = sms;
YourActivity.this.handler.sendMessage(msg);
}
};
}
The receiver and the Activity are separate entities and do not usually interact directly. Imagine the following scenario: you have a receiver getting lots of SMS messages, and every time you get one, you launch an Activity to show the message received. Wouldn't this be very annoying to the user?
I'd says that you can interact with the user by creating a Notification and if the user clicks on it, then you open the Activity you want to show the details.
As how to pass the data to the Activity (hopefully using a notification first), given that SMS messages are short in nature you can just put the data in the Intent.
How to set a Notification to launch an Activity: see Open application after clicking on Notification

Start emulation between two nfc devices,I am using that code but nothing happends, what to do?

i am using that code but nothing happends, whats the problem with this code.
It's running and not showing any error.
I have to share tag from one device to another.
Please share me some code for sharing tag from one device to another.
package com.app.app.nfctag;
import java.nio.charset.Charset;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.os.Bundle;
import android.os.Parcelable;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class DemoNFCtagActivity extends Activity {
NdefMessage msg;
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
processIntent(getIntent());
}
mNfcAdapter.enableForegroundNdefPush(this,msg );
}
#Override
public void onNewIntent(Intent intent) {
// onResume gets called after this to handle the intent
setIntent(intent);
}
NfcAdapter mNfcAdapter;
TextView textView;
Button btnEmulation;
PendingIntent mNfcPendingIntent;
IntentFilter[] mNdefExchangeFilters;
NdefMessage message;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// TextView textView = (TextView) findViewById(R.id.textView);
// Check for available NFC Adapter
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (mNfcAdapter == null) {
Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show();
finish();
return;
}
// Register callback
// mNfcAdapter.setNdefPushMessageCallback(this, this);
String text = ("Beam me up, Android!\n\n" +
"Beam Time: " + System.currentTimeMillis());
msg = new NdefMessage(
new NdefRecord[] { createMimeRecord(
"application/com.example.android.beam", text.getBytes())
/**
* The Android Application Record (AAR) is commented out. When a device
* receives a push with an AAR in it, the application specified in the AAR
* is guaranteed to run. The AAR overrides the tag dispatch system.
* You can add it back in to guarantee that this
* activity starts when receiving a beamed message. For now, this code
* uses the tag dispatch system.
*/
//,NdefRecord.createApplicationRecord("com.example.android.beam")
});
}
public NdefRecord createMimeRecord(String mimeType, byte[] payload) {
byte[] mimeBytes = mimeType.getBytes(Charset.forName("US-ASCII"));
NdefRecord mimeRecord = new NdefRecord(
NdefRecord.TNF_MIME_MEDIA, mimeBytes, new byte[0], payload);
return mimeRecord;
}
void processIntent(Intent intent) {
textView = (TextView) findViewById(R.id.textView);
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(
NfcAdapter.EXTRA_NDEF_MESSAGES);
// only one message sent during the beam
NdefMessage msg = (NdefMessage) rawMsgs[0];
// record 0 contains the MIME type, record 1 is the AAR, if present
textView.setText(new String(msg.getRecords()[0].getPayload()));
}
}
Try this Android boilerplate project - it does the following
Detect, then
Read or write content
Also see the NFC Eclipse plugin project for a graphical NDEF editor - comes with an utility app which reads and writes to tags, also has NFC reader integration :-)

Categories

Resources