Android Tutorial NFC - Reading and Writing

Discussion in 'Tutorials & Examples' started by Erel, Mar 9, 2016.

Thread Status:
Not open for further replies.
  1. Erel

    Erel Administrator Staff Member Licensed User

    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.

    Code:
    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:
    Code:
    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):
    Code:
    Private Sub ReadNdef
       TagTech.RunAsync(
    "ReadNdef""getNdefMessage"Null0)
    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.

    Versions:

    - This example is compatible with Android 4.1+ (API 16). The minimum version if you don't use NFC.CreateMimeRecord is Android 4.0 (API 14).
    - NFC v2.0+: https://www.b4x.com/android/forum/threads/updates-to-internal-libraries.59340/#post-408085
    - ViewsEx 1.11+: https://www.b4x.com/android/forum/threads/updates-to-internal-libraries.59340/#content
    - B4A v5.80+ (you can use older versions by creating a new layout without the custom views, the minimum version is v5.00).
     

    Attached Files:

    Last edited: Mar 17, 2016
    Procesor, calsdn, cimperia and 15 others like this.
  2. Roll Casey

    Roll Casey Member Licensed User

    Thank you, I am trying your example and it says "missing library reference for Tag Tech?"
     
  3. Roll Casey

    Roll Casey Member Licensed User

    Please disregard, I followed the link above and have the correct libraries now.
     
    DonManfred likes this.
  4. Duncan williamson

    Duncan williamson Member Licensed User

    Hi Erel
    I realised that the account I logged in from was my origional account which I had befor I renewed my licence.... So hopefully this account shows me as a licenced user.
    My question is how do I read the tag UID using this new version of NFC

    Regards

    Duncan
     
  5. Erel

    Erel Administrator Staff Member Licensed User

    You can use this code to get the id:
    Code:
    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
     
  6. Duncan williamson

    Duncan williamson Member Licensed User

    Thanks Erel , very much apreciated
     
  7. GaNdAlF89

    GaNdAlF89 Active Member Licensed User

    Hi, I tried this example, adjusting code and layout for B4A v2.71. But when I try to read a tag, the row
    Code:
    TagTech.Initialize("TagTech","android.nfc.tech.Ndef",si)
    generate this
    Code:
    ** Activity (main) Resume **

    main_activity_resume (B4A line: 
    61)
    TagTech.Initialize(
    "TagTech","android.nfc.tech.Ndef" ,si)
    java.lang.NoSuchMethodError: No static method getExtraTags(Ljava/lang/Object;)Ljava/util/HashMap; 
    in class Lanywheresoftware/b4a/AbsObjectWrapper; or its super classes (declaration of 'anywheresoftware.b4a.AbsObjectWrapper' appears in /data/app/b4a.example-1/base.apk)
       at anywheresoftware.b4a.objects.NFC$TagTechnologyWrapper.Initialize(NFC.java:273)
       at b4a.example.main._activity_resume(main.java:
    319)
       at java.lang.reflect.Method.invoke(Native Method)
       at java.lang.reflect.Method.invoke(Method.java:
    372)
       at anywheresoftware.b4a.BA.raiseEvent2(BA.java:
    169)
       at anywheresoftware.b4a.BA.raiseEvent(BA.java:
    153)
       at b4a.example.main$ResumeMessage.run(main.java:
    221)
       at android.os.Handler.handleCallback(Handler.java:
    739)
       at android.os.Handler.dispatchMessage(Handler.java:
    95)
       at android.os.Looper.loop(Looper.java:
    155)
       at android.app.ActivityThread.main(ActivityThread.java:
    5696)
       at java.lang.reflect.Method.invoke(Native Method)
       at java.lang.reflect.Method.invoke(Method.java:
    372)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:
    1028)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:
    823)
    What is the problem?
     
  8. DonManfred

    DonManfred Expert Licensed User

    I guess your old B4A version.
     
  9. GaNdAlF89

    GaNdAlF89 Active Member Licensed User

    Why it depends on B4A version?
     
  10. DonManfred

    DonManfred Expert Licensed User

    because the lib is using
    And i GUESS the AbsObjectWrapper has changed since B4A 2 to B4A 5.8
     
  11. GaNdAlF89

    GaNdAlF89 Active Member Licensed User

    Thanks for reply. In the first post, I read
    Code:
    "- B4A v5.80+ (you can use older versions by creating a new layout without the custom views)."
    but I created a new layout....what version I have to use?
     
  12. DonManfred

    DonManfred Expert Licensed User

    I don´t know.
    I´m just guessing it can be the B4A Version. @Erel needs to answer this question.

    Maybe i´m guessing wrong and the problem is somewhere else.
     
  13. Erel

    Erel Administrator Staff Member Licensed User

    This library requires B4A v5.0+. I've added this requirement to the first post.
     
    lemonisdead and DonManfred like this.
  14. Duncan williamson

    Duncan williamson Member Licensed User

    I have come across a strange issue that i cant explain or get around... if i use the demo program supplied above i can write to the tag and read it with no issues.. if i use other tag reading apps i find that the first letter of record 0 is not read. eg if i write with the example "hello world!" then when i read it with other tag reading apps i get "ello world!"
    if I write to the tag with other apps and read with the example i find it appends "en" to the start of the record so a tag writen with "hello" will read as "enhello".
    any and all work arounds would be apreciated:)
     
  15. GaNdAlF89

    GaNdAlF89 Active Member Licensed User

    Thanks.
    Sorry but with the "you can use older versions by creating a new layout without the custom views" I understood that version also older than 5.0 would work...
    I will send you a mail for new license.
     
  16. Erel

    Erel Administrator Staff Member Licensed User

    There are all kinds of protocols for NDEF payloads: http://nfcpy.readthedocs.org/en/latest/topics/ndef.html
    You can add the language code with:
    Code:
    Dim s As String = Chr(2) & "en" & originalMessage
    'now write s instead of the original messsage
    When you read the message, use GetAsTextType instead of GetPayload.
     
  17. Cableguy

    Cableguy Expert Licensed User

    Am I correct in assuming that with this lib we can emulate a NFC device? Like use the phone as a NFC tag, not a reader.
     
  18. DonManfred

    DonManfred Expert Licensed User

    I dont think so.
     
  19. Cableguy

    Cableguy Expert Licensed User

    I ask because on first post...
     
  20. DonManfred

    DonManfred Expert Licensed User

    Maybe you are right... I don´t know.
     
Thread Status:
Not open for further replies.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice