Android Tutorial NFC - Reading and Writing

Status
Not open for further replies.
NFC v2.00 adds support for low level access to the NFC features. This allows reading and writing from NFC tags.

The NFC library provides three features:
- Reading Ndef tags based intent filters: Reading NDEF data from NFC tags
- Sending data between two devices (Android Beam): https://www.b4x.com/android/forum/threads/60731/#content
- Low level access to the tag.

This tutorial explains how you can use the low level access to read and write Ndef tags. It is also possible to extend it to other types of tags. However you will need to implement the required protocol yourself.

upload_2016-3-9_16-12-25.png


When a tag is scanned, the system sends an intent. The first step is to call NFC.EnableForegroundDispatch in Activity_Resume. This will force the system to send the intent to our activity instead of sending it to a different app.
You should call NFC.DisableForegroundDispatch in Activity_Pause.

Activity_Resume will be called when an intent is sent to our activity. We need to check two things:
1. This intent is related to a tag discovery.
2. This is a new intent.

B4X:
Sub Activity_Resume
   'forces all nfc intents to be sent to this activity
   nfc.EnableForegroundDispatch
   Dim si As Intent = Activity.GetStartingIntent
   'check that the intent is a new intent
   If si.IsInitialized = False Or si = prevIntent Then Return
   prevIntent = si
   If si.Action.EndsWith("TECH_DISCOVERED") Or si.Action.EndsWith("NDEF_DISCOVERED") Or si.Action.EndsWith("TAG_DISCOVERED") Then
      'work with the intent
     End If
   End If
End Sub

Each NFC tag can support multiple types of technologies.
NFC.GetTechList will return the list of supported technologies.
You can see the full list of technologies here: http://developer.android.com/reference/android/nfc/tech/TagTechnology.html

Assuming that the tag supports a technology that is relevant to our app, we create a TagTechnology object with the technology name and then connect to the tag:
B4X:
If techs.IndexOf("android.nfc.tech.Ndef") > -1 Then
   TagTech.Initialize("TagTech", "android.nfc.tech.Ndef" , si)
   'Connect to the tag
   TagTech.Connect
Else
The technology class sets the actual type of TagTech.

The Connected event will be raised when the connection is established. Make sure to check the success parameter as it can fail if the user moved the device during the connection.

Once connected we can start calling the technology specific APIs. The NFC library doesn't expose these APIs. You should instead use JavaObject or TagTechnology.RunAsync to call these methods.
You can find the APIs here: http://developer.android.com/reference/android/nfc/tech/NfcA.html (for NfcA).

There are two types of methods: blocking (I/O) and non-blocking.
You should use TagTechnology.RunAsync to call any of the blocking methods. The RunAsync event will be raised when the operation completed (the call itself will be executed on a background thread).

Example of reading Ndef records (API: http://developer.android.com/reference/android/nfc/tech/Ndef.html):
B4X:
Private Sub ReadNdef
   TagTech.RunAsync("ReadNdef", "getNdefMessage", Null, 0)
End Sub

Private Sub ReadNdef_RunAsync (Flag As Int, Success As Boolean, Result As Object)
   Log($"Reading completed. Success=${Success}, Flag=${Flag}"$)
   ListView1.Clear
   If Success Then
     If Result = Null Then
       ToastMessageShow("No records found.", False)
     Else
       Dim message As JavaObject = Result
       Dim records() As Object = message.RunMethod("getRecords", Null)
       For Each r As NdefRecord In records
         Dim b() As Byte = r.GetPayload
         ListView1.AddSingleLine(BytesToString(b, 0, b.Length, "utf8"))
       Next
     End If
   End If
End Sub

The attached example shows how to read and write to Ndef tags. This is a popular and simple format.

Similar example based on the "reader API" and without the platform sounds: https://www.b4x.com/android/forum/t...lt-read-notification-sound-be-removed.142345/
 

Attachments

  • Project.zip
    15.4 KB · Views: 939
Last edited:

Dey

Active Member
Licensed User
Longtime User
Help
Tabled
HANNSPAD 13.3" SN14T71
NO NFC

ACR122U USB EXTERNAL +
External NFC Reader Service
https://play.google.com/store/apps/details?id=com.skjolberg.nfc.external

NFCAdvenced
Log:
LogCat connected to: 23NB9EZV7P
--------- beginning of /dev/log/system
--------- beginning of /dev/log/main
** Service (starter) Create **
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
main_activity_resume (java line: 349)
java.lang.NullPointerException
at anywheresoftware.b4a.objects.NFC.EnableForegroundDispatch(NFC.java:91)
at b4a.example.main._activity_resume(main.java:349)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:169)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:153)
at b4a.example.main.afterFirstLayout(main.java:108)
at b4a.example.main.access$000(main.java:17)
at b4a.example.main$WaitForLayout.run(main.java:80)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:801)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:617)
at dalvik.system.NativeStart.main(Native Method)


:(
 

DonManfred

Expert
Licensed User
Longtime User
EnableForegroundDispatch
This is only available when the device has NFC

http://developer.android.com/intl/es/reference/android/nfc/NfcAdapter.html


I think you need to get the nfc reader to work another way.

From the app description from the link to ap you posted:
Note to non-developers: It is pretty close, but this is not a drop-in replacement for built-in NFC. That would require a custom ROM.

Check out the public API at https://github.com/skjolber/external-nfc-api.

See https://github.com/skjolber/external-nfc-api
 

DavideV

Active Member
Licensed User
Longtime User
ok i thougth it was javaobject. But now i can't understand how to integrate these lines into the example in the first post :(
 

Duncan H Williamson

Member
Licensed User
Longtime User
You can use this code to get the id:
B4X:
Dim jo As JavaObject = TagTech
Dim tag As JavaObject = jo.RunMethod("getTag", Null)
Dim rawId() As Byte = tag.RunMethod("getId", Null)
Log(bc.HexFromBytes(rawId)) 'bc = ByteConverter
I really apreciate the help I have recieved on this topic... but I have yet another question... I am trying to write a URL to a tag so that when it is scanned by another nfc device it will open a web page... to date I have had no success... I can write the URL but it is just read as a line of text.. I have looked through the android documentation mentioned in responses to this topic but have been unable to get this to work... Could anyone point me in the right direction please ?

Regards

Duncan
 

DavideV

Active Member
Licensed User
Longtime User
I really apreciate the help I have recieved on this topic... but I have yet another question... I am trying to write a URL to a tag so that when it is scanned by another nfc device it will open a web page... to date I have had no success... I can write the URL but it is just read as a line of text.. I have looked through the android documentation mentioned in responses to this topic but have been unable to get this to work... Could anyone point me in the right direction please ?

Regards

Duncan

Hi, you must set the correct payload,
if i'm not wrong these are payloads type for NDEF
0x00 = text
0x01 = http://www.
0x02 = https://www.
0x03 = http://

take a look at this lib, maybe you can reuse some code...
https://www.b4x.com/android/forum/threads/nfc-tagwriter-and-ibeacon-libraries-for-free.42137/
 

pixsys

Member
Licensed User
Longtime User
Hello,
I'm using this great lib to write an nfcv tag, calling transceive.

My question is, while queueing many different calls (writes at different offsets) will they always be executed in the calling order? or should i use flags in the _RunAsync methods and a timer(to periodically check those flags) to wait for one write completion before queuing the next?

Thanks alot
 
Last edited:

Peter Webb

Member
Licensed User
Hi, I have been playing with the excellent NFC library listed here. I can read Ndef tags with no issues. How can i modify this code to read the other NFC tag types available to Android? I have searched all over the net and can not find a B4A example of reading multiple NFC tag formats.

Can anyone assist me please?

Peter
 
Status
Not open for further replies.
Top