Android Question Application and Activity launch by NFC

adrianstanescu85

Active Member
Licensed User
Longtime User
Hello all,

I started using NFC tags for my application.
All the NFC tags I'm using have a text content, so no URI.

Since my phone may have more than a single application that handles NFCs, I'd like my own application to handle NFCs only if... let's say the text content starts with "ABCTag". How can I do this?

And also, my application has several activities. Let's say Activity1, Activity2, Activity3. What I'd really need is if the NFC tag text is "ABCTag1" then that should start Activity1, if "NFCTag2" then Activity2 and so on.

Any help on this please?

So far I've updated my manifest file and it reads all NFCs no matter what, but I'm still having problems with this kind of filtering.

Thank you!
Adrian
 

DonManfred

Expert
Licensed User
Longtime User
I think it would work with a broadcastreciever and specialized Intentfilters

But I can not help out there. I have no plan what you have to do for this filters in B4A.

PS: If you find out how to do: please share the solution to us :)
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
You don't need to use the BroadcastReceiver library to handle intent filters. You should use static filters as explained in the NFC tutorial.

However it is not possible to filter based on the text content. Do you have control on the tags values? If yes then you can set any scheme you like and filter based on this scheme (see the tutorial).
 
Upvote 0

adrianstanescu85

Active Member
Licensed User
Longtime User
I tried implementing static filters in the first place and did not succeed, this is why I asked... I do have control over the tags values, so here is what I wrote on my Manifest:

B4X:
AddActivityText(main, <intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <data android:mimeType="text/plain" />
    <data android:scheme="HOME_" />
</intent-filter>)

What I wanted was to handle the NFC tags that have a text value that starts with HOME_, however this doesn't work. What am I doing wrong?

Thank you!
 
Upvote 0

adrianstanescu85

Active Member
Licensed User
Longtime User
I removed the mimetype and set the scheme. I does not work. Can you post a little code by what you mean? Also, what should the actual tag contain? Text (formatted according to scheme) Uri (since the writing app doesn't allow something like home://)?
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
It should be a Uri. If you cannot use home:// then use http:// and filter based on the url as in this example:
B4X:
AddActivityText(main, <intent-filter>
 <action android:name="android.nfc.action.NDEF_DISCOVERED" />
 <category android:name="android.intent.category.DEFAULT" />
 <data android:scheme="http"
 android:host="www.b4x.com" />
</intent-filter>)
You can add data after the url: ...com?your data here
 
Upvote 0

adrianstanescu85

Active Member
Licensed User
Longtime User
Great, got it! It seems that the actual text that I'm interested in passing comes right after www.whatever.abc (abc must be 3 letters, i.e. not abcde) plus a character (either "/" or "?" or anything else).

My application has a start activity from which if the user chooses, some other activities start.

If I'm on the Activity2 let's say (I went there from the start activity) and I scan a tag according to the format above, the activity that reads it is the start activity (which is where I set the read NFC process). I want to be able to scan a tag both in the start activity AND in the Activity2 (where let's say I want a label to print the tag text).

How can I do that, so that when I scan another tag, this reading be done exclusively in Activity2? Should I add another kind of filter to the manifest? What's the best way to do it?

Thank you!
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
You can try to add a dynamic intent filter with the BroadcastReceiver. I don't think that adding another static filter will work (though it worth a test).

Another option is to handle it inside your app. If Activity2 was just paused when the intent arrives to start activity then you should call StartActivity(Activity2).
 
Upvote 0

adrianstanescu85

Active Member
Licensed User
Longtime User
Thank you for the suggestion, I just tried it! I added a second static filter and replaced the "main" specification (which was my main activity name) with "secondactivity" (which is my second activity name) and also modified the according scheme in the URI. That worked.

The great NFC problem here is that the read even is raised in the RESUME sub, which actually runs that RESUME activity, so for instance if during Create I'm showing Panel1, Panel2 and Panel3 and in the mean time I've hidden those to show Panel4 and Panel5, if I do scan the NFC tag the RESUME sub fires and recalls Create, which shuts down Panel4 and Panel5 and relists Panel1, Panel2 and Panel3. This is very inconvenient!

The easiest way would be to get the actual NFC read without a RESUME launch. How can I do that??

Thank you!
 
Upvote 0

adrianstanescu85

Active Member
Licensed User
Longtime User
Actually I did find a solution and also a bug I guess.

First, if anyone is interested in the solution for getting certain NFC tag contents to different activities without launching the main activity each time the NFC is read, here it is: create a separate activity for reading NFC tags, let's say that will be called NFCActivity; then, in the manifest editor replace "AddActivityText(main, <intent-filter>" with "AddActivityText(nfcactivity, <intent-filter>" so that activity will take care or reading; be sure that on the Create sub for NFCActivity not to load a layout, so nothing will come up; in the NFCActivity Resume sub go ahead and do the reading - you should store the NFC uri/text in a global variable, so that is available through other activities i.e. where you need it. That's it!

Second, the bug: I have to say declaring two static filters for NFC works. Let's say I write the following in the manifest editor:

B4X:
AddActivityText(main, <intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <data android:scheme="http"
android:host="www.mysite.com" />
</intent-filter>)
AddActivityText(nfc, <intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <data android:scheme="http"
android:host="www.yoursite.com" />
</intent-filter>)

By doing so, each NFC tag that has the URI set to http://www.mysite.com/ will send the info to Main activity, and then the contents. For instance, if the URI on the NFC tag is http://www.mysite.com/MyOwnNFCtag then the Main activity would receive "MyOwnNFCtag". That's fine. Here's the problem: if you have a second NFC tag that says http://www.yoursite.com/MyOwnNFCtag then that would be read by the NFC activity (according to the manifest editor), but the text being received will be "m/MyOwnNFCtag" instead of "MyOwnNFCtag". That is because www.mysite.com, which is first declared in the manifest editor, is two characters shorter than www.yoursite.com, which is declared second. So when cutting to the actual text being transferred to the activity, only the length of the first URI matters. That's the bug.

Hope it helps!

Adrian
 
Upvote 0
Top