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: 728
Last edited:

BluSky76

Member
Licensed User
Longtime User
Hello Erel,

you can format with a NFC v2.00 card without using external programs or libraries as RSNFCTagWriter.

Thanks
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
You can the android.nfc.tech.NdefFormatable tech to format the tag: https://developer.android.com/reference/android/nfc/tech/NdefFormatable.html

Try to connect to the tag with:
B4X:
TagTech.Initialize("TagTech", "android.nfc.tech.NdefFormatable" , si)
TagTech.Connect
Dim RecordsJO As JavaObject
RecordsJO.InitializeArray("android.nfc.NdefRecord",Array(nfc.CreateUriRecord("https://www.b4x.com"))
Dim message As JavaObject
message.InitializeNewInstance("android.nfc.NdefMessage", Array(RecordsJO))
TagTech.RunAsync("Format", "format", Array(message), 0)
End Sub

Private Sub Format_RunAsync (Flag As Int, Success As Boolean, Result As Object)
   Log($"Writing completed. Success=${Success}, Flag=${Flag}"$)
End Sub
 

boon2

Member
Licensed User
Longtime User
Private TagTech As TagTechnology

where is lib > tagtechnology
b4a version.3.8
thx
 

MCU01

Member
Licensed User
Longtime User
Hi, I'm trying to combine this NFC code with the TabStripViewPager explained here.

My NFC program works great. The problem is that when I add the tabs with TabStripViewPager, my NFC communication stops working. My NFC program works great with TabHosts, but it doesn't like the TabStripViewPager. Am I missing something here? I'm just a beginner, so go easy on me.... :)

Update: Never mind, I found what I was doing wrong. I was calling the first tab, tab# 1 instead of calling it tab# 0 in the following line of code, If tbsMain.CurrentPage = 1 Then
 
Last edited:

Cnrez

Member
Licensed User
Longtime User
hi all,
i want to read and write to mifare desfire 4k card
it support tech :
Techs: [android.nfc.tech.IsoDep, android.nfc.tech.NfcA, android.nfc.tech.NdefFormatable]

i want to use android.nfc.tech.NdefFormatable
i modified the sample project, but it didn't work,
here is the log :

B4X:
Logger connected to:  CipherLab CipherLab RS30
--------- beginning of /dev/log/system
--------- beginning of /dev/log/main
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
** Activity (main) Resume **
Techs: [android.nfc.tech.IsoDep, android.nfc.tech.NfcA, android.nfc.tech.NdefFormatable]
Connected: true
Reading completed. Success=false, Flag=0
** Activity (main) Pause, UserClosed = false **
** Activity (main) Resume **
Techs: [android.nfc.tech.IsoDep, android.nfc.tech.NfcA, android.nfc.tech.NdefFormatable]
Connected: true
Reading completed. Success=false, Flag=0

please help.
regards

here is my project
 

Attachments

  • advanced_NFC_ndefformatable.zip
    9 KB · Views: 571

Wolli013

Well-Known Member
Licensed User
Longtime User
Hi Erel

Thanks for it!
How can I make one day NFC only readably and according to demand again recordably?
 

MCU01

Member
Licensed User
Longtime User
Hi,

I've been using this code for a while to read NFC tags and it works great. I have an electronic design where I'm using an NXP chip with an antenna tuned properly. Sometimes the phone recognizes the tag and sometimes I get the message "Tag does not support Ndef." from the following code.

B4X:
    '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
        Dim techs As List = nfc.GetTechList(si)
        Log($"Techs: ${techs}"$)
        'in this case we are only accessing Ndef tags.
        If techs.IndexOf("android.nfc.tech.Ndef") > -1 Then
            TagTech.Initialize("TagTech", "android.nfc.tech.Ndef" , si)
            'Connect to the tag
            TagTech.Connect
        Else
            ToastMessageShow("Tag does not support Ndef.", True)  'CHECK WHY THIS MESSAGE SOMETIMES COMES UP....
        End If
    End If

The tags work find with other readers. Just in case that you want to take a look at the datasheet of this tag here is the datasheet,

https://www.mouser.com/datasheet/2/302/NT3H2111_2211-1127378.pdf

Below is a screenshot of the tag read using a different program. It shows that the tag is NdefFormatable instead of being Ndef enabled.

upload_2018-6-30_1-42-53.png


Any help is greatly appreciated. Please, let me know if I need to start a new thread instead of posting here.

Thank you,

Robert
 
Last edited:
Status
Not open for further replies.
Top