Android Question NFC within a service

Rainer@B4A

Member
Licensed User
Longtime User
Is it possible to use the NFC library within a service ?
In my app a service is running, even if the app is paused (sleep mode), to read the GPS coordinates.
In the similar way I want to receive an event, if a NFC tag is detected, to read the Tag ID.
 
Last edited:

drgottjr

Expert
Licensed User
Longtime User
this doesn't answer your question, but you don't need a
running service to read an nfc tag. your app simply needs to
register itself with the os as a reader of nfc tags (with an intent
filter). when your android device is held in proximity to an nfc
tag or card, the os consults a list of apps which are meant to handle
reading of the tag.

depending on how many apps you have installed which can read
an nfc tag, and depending on the type of tag (eg, ndef), your app
- whether active, sleeping or simply off - will handle the reading.

some devices (mine, for example) come with a built-in nfc reader
app. assuming the nfc tag is of the ndef type, most typical tags
are automatically read without the need for other apps. of course,
that was a surprise and rather disappointing to me since i wanted
my app to be the reader.

i tell the os to use my app when an nfc tag is discovered, and my
app bypasses the built-in app. it doesn't matter the state of my app
at the time. it simply handles the reading.

in general, only ndef tags are recognized without a dedicated app.
my app also reads contactless smartcards, so a built-in app or one
using the nfc library would not be able to handle the reading.

so, even if your app handles some very specific type of nfc tag, it
doesn't have to be running as a service all day. you simply tell the
os your app is the one to go to in the event an nfc tag of the type
your app handles is discovered. when that occurs, your app is
summoned (as if it was already waiting in the background). even
if you wanted to reinvent the wheel and handle all ndef tags (like the
built-in app), you can bypass the built-in app with an intent filter.

if your device does not come with a built-in app, there still is no
need to run the service. if your app is registered as an nfc reader,
it will be called when a tag is discovered. whether it is able to
read the tag is a different story.

to test if your device has a built-in reader, turn nfc on in device
settings and hold the device near some nfc tag.

i don't even have to think about whether my app is running or
may have been killed or some service gone bad. when an nfc
tag is discovered, it's called by the os.
 
Upvote 0

Rainer@B4A

Member
Licensed User
Longtime User
Dear drgottjr,
thank you very much for your excellent description.

I understand what you explained, but I need to handle the read process in the background while the phone is in sleep mode. This is necessary because the phone should stay in a pocket. There it must be in sleep mode to prevent unwanted touch events.

My app is for golfers and I want to add a feature to record where (GPS coordinates) a shot is made from and with which club (Tag ID). For this the phone should stay sleeping in the pocket.

The GPS process is already solved. I also can read the club tag with my own app, as well with build-in nfc reader app, but only as a running activity.

Any idea ?
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Any idea ?
What about reading thet TAG once before a couse begins. It must be done in a visible activity (COURSE Login for example).
RECORD and remember it until course ends.
You can use the recorded tag inside the service to save it together with GPS infos. No need to get the tag again from NFC.
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
@DonManfred's suggestion is an excellent example of occam's razor.
but i think both he and i may have a different understanding of what you mean
by "club". or perhaps it's just me. i don't play the sport, so a golf club has 2
meanings for me.

I also can read the club tag with my own app, as well with build-in nfc reader app, but only as a running activity.

my excellent explanation may not have been excellent enough,
as i appear to have failed to make my point: your app need not be running in
order for the os to call it to read nfc tags.

when i put my phone in do-not-disturb mode (which, i guess,
is what you mean by sleeping) and pass near an nfc tag, my app - which was
not running - reads the tag. if i walk around with the phone "sleeping", and
pretending to be golfing, every time i come near a tag, the read is recorded.

full disclosure:
in fact i don't use the nfc library to read nfc tags. it is not required. almost no
coding is required to read a tag. it's all already done by the os and passed right
to the app. writing to a nfc tag is a different story.

so, in that context, i cannot tell you if you can modify the background tracking
example to handle nfc tags. i therefore withdraw with apologies. i simply wanted
to draw your attention to an alternate way of looking at the situation.
i would add, however, that if you've seen one background service, you've probably seen
most of them.
 
Upvote 0

Rainer@B4A

Member
Licensed User
Longtime User
thanks guys,
for those who don't play golf:
A golf club is the tool with which you hit the golf ball, like a racket in tennis. On a round of golf over 18 holes, as an amateur, you hit the ball about 90 times and it takes 3-4 hours to do so. A golfer carries about 10 different clubs with him, which are optimized for different distances and situations. Each club will have its own ID-Tag.

With my app I want to record the geo position and the used club for every shot without touching the phone. Simply by holding the club with its NFC_Tag to the phone in the trouser pocket before each shot. And because of the phone is in the pocket it must be swiched in a mode in which no touch event can happen.
 
Last edited:
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
and a golf club is an facility which provides a location (course) to play golf. you can join the club or not (ie, simply pay a day fee to use the facility).
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
NOT FOR ME! i need a moving ball to hit

even though i am no longer involved in this thread, i was
intrigued by your wish to run a background service for nfc, similar to
(and in conjunction with) gps background tracking.

i may not have all of this 100%, but i think i'm pretty close:
the main problem with an nfc background service is that nfc discovery
is triggered by an intent from the os's nfc software. such an intent is sent
to an activity. to reach your service, the app would have to turn around and
forward it to the service start. in theory, no biggie. but i think if a user forgets
to run your app before putting the phone to sleep, there could be a problem.
also if the app were killed at some point (the long-running service would never
be informed if a mashie or niblick were being used since such information has
to come from a running app via an intent).

technically, it is possible to discover tags without an intent, but not with
the nfc library. there is a method which takes a proactive stance to tag
discovery and uses a callback instead of an intent. i use it to stop the stupid
noise the device makes when a tag is discovered. (but do not disturb avoids
that.)
 
Upvote 0

wes58

Active Member
Licensed User
Longtime User
What I have in my project written many times ago:
In the Manifest:
B4X:
AddActivityText(nfcGet,
    <intent-filter>
        <action android:name="android.nfc.action.TAG_DISCOVERED"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
    <intent-filter>
        <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="*/*" />
    </intent-filter>)
In my project I add another activity called nfcGet
B4X:
#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: false
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Dim LastIntent As Intent

End Sub

Sub Globals
    Dim nfc_Tag As NFC
End Sub

Sub Activity_Create(FirstTime As Boolean)

End Sub

Sub Activity_Resume
    If Activity.GetStartingIntent = LastIntent Then Return
    
    If nfc_Tag.IsNdefIntent(Activity.GetStartingIntent) Then
        Dim records As List
        Dim r As NdefRecord
        records = nfc_Tag.GetNdefRecords(Activity.GetStartingIntent)
        r = records.Get(0)
        CallSubDelayed2(Starter, "ReadNFCtag", r.GetAsTextType)
        Log("nfc " & r.GetAsTextType)
    End If
    LastIntent = Activity.GetStartingIntent
    Activity.Finish
End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub
And process the tag in Starter or any other service.
This works for me.
Note, this was written many years ago so there were no B4XPages!
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…