12 March, 2014

NFC beam

As we know, NFC supports three modes: read/write tag, P2P, card emulation.
Android beam feature is introduced in API level 14, which is android 4.0.

Here are some Q/As:
  • Beam requirements:
To make beam work, items below are required:
1.  Android Beam from the settings of Android OS must be turned on in both mobile phones.
2.  The application on the mobile phone that wants to beam must be running in the foreground.
3.  The screen of the mobile phone that will receive the beam must not be locked.
4.  The user must touch to the screen of the mobile phone that will beam.

  • What's the min SDK version required:
API Level 14

  • What's the permission we need to ask for:
<uses-permission android:name="android.permission.NFC" />


  • How to push beam message:
We have two ways: static / dynamical:
setNdefPushMessage(): Accepts an NdefMessage to set as the message to beam. Automatically beams the message when two devices are in close enough proximity.
setNdefPushMessageCallback(): Accepts a callback that contains a createNdefMessage() which is called when a device is in range to beam data to. The callback lets you create the NDEF message only when necessary.
An activity can only push one NDEF message at a time, so setNdefPushMessageCallback() takes precedence over setNdefPushMessage() if both are set.
Normally we use the second one to get a flexible way to handle the message.

  • How to disable the beam push:
there are serveral ways: return null message in CreateNdefMessageCallback, or set message null in setNdefPushMessage, or set message null in setNdefPushMessageCallback.

  • How to create MIME type ndef record manually:
NdefRecord mimeRecord = new NdefRecord(
    NdefRecord.TNF_MIME_MEDIA ,
    "application/vnd.com.example.android.beam".getBytes(Charset.forName("US-ASCII")),
    new byte[0], beamedMessage.getBytes(Charset.forName("US-ASCII")));

  • How to force your own app to response the intent filter:
There are two ways: create a unique MIME type, or include AAR in message. AAR means Android Application Record.

  • How to disable the default nfc beam:
<application ...>
     <meta-data android:name="android.nfc.disable_beam_default"
         android:value="true" />
 </application>

  • How to receive beam:
Define the intent filter in manifest for handling activity
<intent-filter>
  <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
  <category android:name="android.intent.category.DEFAULT"/>
  <data android:mimeType="application/vnd.com.example.android.beam"/>
</intent-filter>

In the handling activity:
@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);
}