Android Question NFC - Read EMV Cards?

hasexxl1988

Active Member
Licensed User
Longtime User
Hello,

Is it possible to read data from an EMV credit card via NFC for an Automated PayPal (API) Payment System?

I found information about NFC in the community. However, nothing in connection with credit cards


I found the following Lib. However, I can not integrate that easily because there is no B4A. https://github.com/devnied/EMV-NFC-Paycard-Enrollment
 
Last edited:

hasexxl1988

Active Member
Licensed User
Longtime User
Thanks for Infos.

Thats not working. I have tryed fully weekend >.<

Log says Only:

*** 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 **
** Activity (main) Pause, UserClosed = false **
*** 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 **
** Service (starter) Destroy (ignored)**
 
Upvote 0

hasexxl1988

Active Member
Licensed User
Longtime User
Where is the code that tries to read the data?

I only get the techs out, more unfortunately not .... I have never worked with NFC code and therefore do not know how the individual values can be read, or how I can read a list of all available records of the card.

This is the Code:

B4X:
#Region  Project Attributes
    #ApplicationLabel: Advanced NFC
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: portrait
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
    Private prevIntent As Intent
End Sub

Sub Globals
    Private nfc As NFC
    Private TagTech As TagTechnology
 
    Private rdbRead As RadioButton
    Private ListView1 As ListView
    Private rdbWrite As RadioButton
    Private flTxt1 As FloatLabeledEditText
    Private flTxt2 As FloatLabeledEditText
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("1")
    ListView1.SingleLineLayout.Label.TextSize = 15
    flTxt2.EditText.ForceDoneButton = True
End Sub

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("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.IsoDep") > -1 Then
            TagTech.Initialize("TagTech", "android.nfc.tech.IsoDep" , si)
            'Connect to the tag
            TagTech.Connect
        Else
            ToastMessageShow("Tag does not support IsoDep.", True)
        End If
    End If
End Sub

Private Sub TagTech_Connected (Success As Boolean)
    Log($"Connected: ${Success}"$)
    If Success = False Then
        ToastMessageShow("Error connecting to tag", True)
        Log(LastException)
    Else
        ReadNdef
    End If
End Sub

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


Sub Activity_Pause (UserClosed As Boolean)
    nfc.DisableForegroundDispatch
End Sub

Debug LOG (Unfiltered):

B4X:
** Activity (main) Resume **
Relayout returned: old=[0,0][720,1280] new=[0,0][720,1280] result=0x1 surface={valid=true 3503185920} changed=false
 in onLayout changed 
** Activity (main) Pause, UserClosed = false **
** Activity (main) Resume **
Techs: [android.nfc.tech.IsoDep, android.nfc.tech.NfcA]
Class anywheresoftware.b4a.B4AThreadPool failed lock verification and will run slower.
Connected: true
java.lang.RuntimeException: Method: getNdefMessage not found in: android.nfc.tech.IsoDep
    at anywheresoftware.b4j.object.JavaObject$MethodCache.getMethod(JavaObject.java:366)
    at anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:119)
    at anywheresoftware.b4a.objects.NFC$TagTechnologyWrapper$2.call(NFC.java:298)
    at anywheresoftware.b4a.objects.NFC$TagTechnologyWrapper$2.call(NFC.java:1)
    at anywheresoftware.b4a.BA$3.run(BA.java:461)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:457)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
    at java.lang.Thread.run(Thread.java:764)
Do partial code cache collection, code=30KB, data=29KB
After code cache collection, code=29KB, data=28KB
Increasing code cache capacity to 128KB
setView = android.widget.LinearLayout{4b81d2 V.E...... ......I. 0,0-0,0 #1020535 android:id/toast_layout_root} TM=true MM=false
Text: Donn in android.widget.Toast$TN@c2072a3
Reading completed. Success=false, Flag=0
dispatchAttachedToWindow
sf_framedrop debug : 0x4f4c, game : false, logging : 0
Relayout returned: old=[0,0][0,0] new=[220,1048][500,1152] result=0x7 surface={valid=true 3503187968} changed=true
MSG_RESIZED_REPORT: frame=Rect(220, 1048 - 500, 1152) ci=Rect(0, 0 - 0, 0) vi=Rect(0, 0 - 0, 0) or=1
dispatchDetachedFromWindow
channel 'ac0c9b2 Toast (client)' ~ Disposing input event receiver.
channel 'ac0c9b2 Toast (client)' ~NativeInputEventReceiver.
setView = android.widget.LinearLayout{73d95ff V.E...... ......I. 0,0-0,0 #1020535 android:id/toast_layout_root} TM=true MM=false
Text: Sead in android.widget.Toast$TN@b26bfcc
dispatchAttachedToWindow
sf_framedrop debug : 0x4f4c, game : false, logging : 0
Relayout returned: old=[0,0][0,0] new=[58,1021][662,1152] result=0x7 surface={valid=true 3503187968} changed=true
MSG_RESIZED_REPORT: frame=Rect(58, 1021 - 662, 1152) ci=Rect(0, 0 - 0, 0) vi=Rect(0, 0 - 0, 0) or=1
dispatchDetachedFromWindow
channel 'c53dd0a Toast (client)' ~ Disposing input event receiver.
channel 'c53dd0a Toast (client)' ~NativeInputEventReceiver.

Result is null. I do not get the ToastMessage from 'ToastMessageShow ("No records found.", False)' and Success is False by all cards
 
Last edited:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Upvote 0

hasexxl1988

Active Member
Licensed User
Longtime User
Don't use Toast messages for debugging. Use Log.
Reading nfc tags that are not formatted as NDEF tags is more complicated. You will need to implement the low level protocol.
The code here demonstrates it: https://www.b4x.com/android/forum/threads/cannot-read-and-write-to-nfc-card.84363/#post-534798

Java implementation which you should post based on the code from that link: https://stackoverflow.com/a/16853868/971547

Okay thanks,

i have tryed. Not working. Success is false and Result is null.

How do I know which byte parameters have to be read out?

Full LOG:
java.lang.RuntimeException: Method: transceive not found in: android.nfc.tech.NdefFormatable

B4X:
Relayout returned: old=[0,0][720,1280] new=[0,0][720,1280] result=0x1 surface={valid=false 0} changed=false
sf_framedrop debug : 0x4f4c, game : false, logging : 0
Relayout returned: old=[0,0][720,1280] new=[0,0][720,1280] result=0x7 surface={valid=true 3663955968} changed=true
EGLint new_window_surface(egl_winsys_display *, void *, EGLSurface, EGLConfig, egl_winsys_surface **, egl_color_buffer_format *, EGLBoolean) returns 0x3000,  [720x1280]-format:1
eglCreateWindowSurface = 0xdfcf48e0
** Activity (main) Resume **
MSG_WINDOW_FOCUS_CHANGED 1
Starting input: tba=android.view.inputmethod.EditorInfo@d1a4eaa nm : b4a.example ic=com.android.internal.widget.EditableInputConnection@9a77a9b
startInputInner - mService.startInputOrWindowGainedFocus
SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
** Activity (main) Pause, UserClosed = false **
** Activity (main) Resume **
Techs: [android.nfc.tech.IsoDep, android.nfc.tech.NfcA]
setView = android.widget.LinearLayout{9f92577 V.E...... ......I. 0,0-0,0} TM=true MM=false
Text: Uag  in android.widget.Toast$TN@98965e4
dispatchAttachedToWindow
sf_framedrop debug : 0x4f4c, game : false, logging : 0
Relayout returned: old=[0,0][0,0] new=[67,1064][653,1152] result=0x7 surface={valid=true 3448905728} changed=true
MSG_RESIZED_REPORT: frame=Rect(67, 1064 - 653, 1152) ci=Rect(0, 0 - 0, 0) vi=Rect(0, 0 - 0, 0) or=1
dispatchDetachedFromWindow
channel '9fc4284 Toast (client)' ~ Disposing input event receiver.
channel '9fc4284 Toast (client)' ~NativeInputEventReceiver.
 
Last edited:
Upvote 0

hasexxl1988

Active Member
Licensed User
Longtime User
1. I don't see the error in these logs.
2. Where is the updated code?

B4X:
#Region  Project Attributes
    #ApplicationLabel: Advanced NFC
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: portrait
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
    Private prevIntent As Intent
End Sub

Sub Globals
    Private nfc As NFC
    Private TagTech As TagTechnology
    
    Private rdbRead As RadioButton
    Private ListView1 As ListView
    Private flTxt2 As FloatLabeledEditText
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("1")
    ListView1.SingleLineLayout.Label.TextSize = 15
    flTxt2.EditText.ForceDoneButton = True
End Sub

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("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.IsoDep") > -1 Then
            TagTech.Initialize("TagTech", "android.nfc.tech.IsoDep" , si)
            'Connect to the tag
            TagTech.Connect
        Else
            ToastMessageShow("Tag does not support IsoDep.", True)
        End If
    End If
End Sub

Private Sub TagTech_Connected (Success As Boolean)
    Log($"Connected: ${Success}"$)
    If Success = False Then
        ToastMessageShow("Error connecting to tag", True)
        Log(LastException)
    Else
        ReadNdef
    End If
End Sub

Private Sub ReadNdef
    TagTech.RunAsync("ReadNdef", "transceive", Array(Array As Byte(0xA2, 0x03, 0xE1, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x10, 0x06)), 0)
    Wait For TT_RunAsync (Flag As Int, Success As Boolean, Result As Object)
    Log(Success)
    TagTech.Close
    
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


Sub Activity_Pause (UserClosed As Boolean)
    nfc.DisableForegroundDispatch
End Sub
 
Upvote 0

hasexxl1988

Active Member
Licensed User
Longtime User
B4X:
#Region  Project Attributes
    #ApplicationLabel: Advanced NFC
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: portrait
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
    Private prevIntent As Intent
End Sub

Sub Globals
    Private nfc As NFC
    Private TagTech As TagTechnology
   
    Private rdbRead As RadioButton
    Private ListView1 As ListView
    Private flTxt2 As FloatLabeledEditText
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("1")
    ListView1.SingleLineLayout.Label.TextSize = 15
    flTxt2.EditText.ForceDoneButton = True
End Sub

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("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.IsoDep") > -1 Then
            TagTech.Initialize("TagTech", "android.nfc.tech.IsoDep" , si)
            'Connect to the tag
            TagTech.Connect
        Else
            ToastMessageShow("Tag does not support IsoDep.", True)
        End If
    End If
End Sub

Private Sub TagTech_Connected (Success As Boolean)
    Log($"Connected: ${Success}"$)
    If Success = False Then
        ToastMessageShow("Error connecting to tag", True)
        Log(LastException)
    Else
        ReadNdef
    End If
End Sub

Private Sub ReadNdef
    TagTech.RunAsync("ReadNdef", "transceive", Array(Array As Byte(0xA2, 0x03, 0xE1, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x10, 0x06)), 0)
    Wait For TT_RunAsync (Flag As Int, Success As Boolean, Result As Object)
    Log(Success)
    TagTech.Close
   
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


Sub Activity_Pause (UserClosed As Boolean)
    nfc.DisableForegroundDispatch
End Sub

how can I read the string value from the NFC tag? >.<
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Upvote 0
Top