Android NFC tag received with broadcastreceiver

z_z_z_z picture z_z_z_z · Jan 31, 2011 · Viewed 9.5k times · Source

I'm trying to catch NFC tag in broadcast receiver so I wrote a simple BR that prints "asd" in the onReceive(). In the manifest xml it's desribed like that:

and I receive only this and no print at all....

01-31 16:37:18.980: ERROR/MediaPlayer(990): setAudioStream called in state 8
01-31 16:37:18.980: ERROR/MediaPlayer(990): error (-38, 0)
01-31 16:37:18.980: ERROR/MediaPlayer(990): start called in state 0
01-31 16:37:18.980: ERROR/MediaPlayer(990): error (-38, 0)
01-31 16:37:18.988: ERROR/MediaPlayer(990): Error (-38,0)

When I use activity to handle the intent like this:

<activity android:name="TagViewer"
            android:theme="@android:style/Theme.NoTitleBar">
            <intent-filter>
                <action android:name="android.nfc.action.TAG_DISCOVERED"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
</activity>

The activity is started and working perfectly, so how can I make it work with BroadcastReceiver?

Answer

Dave MacLean picture Dave MacLean · Mar 16, 2011

You can't. As you pointed out, the NFC adapter is using something very much like startActivity() to send out an intent with tag information in it. It's not exactly like what we can do within the Android SDK, since NFC tags are special. For instance, you cannot emulate the startActivity() on your own for anything except TAG_DISCOVERED, which is the action of last resort and not terribly useful.

I think the reason for this is due to the special handling of NFC intents. When a tag is discovered by the NFC hardware, it goes looking for something that will handle the tag. Foreground activities get first try. It tries an NDEF_DISCOVERED intent next if it can, and looks for an activity to take it. If it can't find one, it tries an intent with TECH_DISCOVERED. Again, if no activity can be found, it finally tries TAG_DISCOVERED. If it used a broadcast, how could it do this fall-back logic to keep trying to find something to handle the tag? How would it know if anything was acting on the tag intent? And how could it ensure that only one thing was going to act on the tag?