Sometimes we may wish to make use of NFC, a very short range communication technology, to transfer data or to interact with NFC tags.
We can query the NfcAdapter
instance for the status of the hardware as well as to be notified when a new tag is detected:
[assembly: UsesPermission(Manifest.Permission.Nfc)]
Required
property to true
:[assembly: UsesFeature( PackageManager.FeatureNfc, Required = true)]
However, if our app runs fine on a device without NFC, we set the Required
property to false
:
[assembly: UsesFeature( PackageManager.FeatureNfc, Required = false)]
NfcAdapter
instance:adapter = NfcAdapter.GetDefaultAdapter(this);
EnableForegroundDispatch()
method:if (adapter != null && adapter.IsEnabled) { var tagDetected = new IntentFilter( NfcAdapter.ActionTagDiscovered); var pendingIntent = PendingIntent.GetActivity( this, 0, new Intent(this, GetType()), 0); adapter.EnableForegroundDispatch( this, pendingIntent, new[]{ tagDetected }, null); }
adapter.DisableForegroundDispatch(this);
OnNewIntent()
method. We will receive the type of technology detected via the Tag
extra:protected override void OnNewIntent(Intent intent) { var tag = intent.GetParcelableExtra( NfcAdapter.ExtraTag) as Tag; if (tag != null) { string[] techs = tag.GetTechList(); } }
NdefMessages
extra:var ndefMessages = intent.GetParcelableArrayExtra( NfcAdapter.ExtraNdefMessages); if (ndefMessages != null) { foreach (var msg in ndefMessages.Cast<NdefMessage>()) { foreach (var record in msg.GetRecords()) { byte[] typeBytes = record.GetTypeInfo(); byte[] payloadBytes = record.GetPayload() var type = Encoding.UTF8.GetString(typeBytes); var payload = Encoding.UTF8.GetString(payloadBytes); } } }
Like Bluetooth, NFC is a wireless communication technology for use over short distances. However, in the case of NFC, the distance is less than 10 centimeters. Unlike Bluetooth, which uses radio transmissions, NFC uses electromagnetic radio fields to communicate. More information on NFC and how it works can be found on the official NFC website: http://www.nearfieldcommunication.org.
We can use the Android NFC API to do several things, including reading or writing to passive tags and communicating with other devices.
Like any other hardware feature we want to use, we have to request permission to do so. There is the usual NFC permission that we need to request as well as an additional feature that we have to specify. The feature is used by the package manager to let the store know that we may require a device that supports NFC. The feature can be set to required
or optional
.
Before we can interact via NFC, we have to obtain the NfcAdapter
instance from the current context. Once we have the adapter, we start listening for NFC tags or devices using the EnableForegroundDispatch()
method. We provide the ActionTagDiscovered
action filter to this method and a PendingIntent
instance that holds an Intent
instance to return to our activity. We could specify any activity here.
Once the listener is started, we need to make sure we stop it as soon as the app leaves the foreground; otherwise, an exception will be thrown. We can cancel the NFC listener by invoking the DisableForegroundDispatch()
method.
Because we specified that the listener should return to our activity, the OnNewIntent()
method is invoked, along with the Intent
instance we specified in the PendingIntent
instance, as soon as a tag is detected.
The Intent
instance will contain the NFC extras that we can use to read the tags and message. If we request the ExtraTag
extra from the intent, we will obtain the Tag
instance that initiated the event. We can use this Tag
instance to read various details out as well as to write to the tag.
We can also read any of the messages stored in the tag using the ExtraNdefMessages
extra. This extra is an array of NdefMessage
types, each of which contains one or more NdefRecord
types. On each record, we can get type information, such as the MIME type, from the GetTypeInfo()
method. We can also get the actual payload using the GetPayload()
method.
Some tags support being written to, and we can do this by creating NdefMessage
and NdefRecord
instances. We can also use these messages to send data to another device.