I was wondering if there is any way to save a string of text (URL) to an NFC tag, let us say MIFARE or NTAG203, that can be read by other devices (smartphones) without the need of any special tag reading application.
I have tested several applications, e.g. Trigger for Android, and noticed that if the device reading the tag does not have the required application to read the data/instructions off the tag it still opens a URL that sends you to the Play Store to download that application.
So there must be a way to save some data readable by all/some NFC enabled phones. Simply put I want to create an applcation for Android that will write data to NFC tags and the data can be read/opened/executed by a random NFC enabled phone.
So is it possible to prepare an NFC tag that triggers some action on the reading device without requiring a specific application? What type of data could I write on an NFC tag with my app to achieve this?
First of all, in general, I agree with CommonsWare point of view that it's always a "special" app that handles NFC events. However, when looking into Android, I would consider the various platform apps from AOSP as part of the Android system. Even though not all of them may be available on all devices.
Looking into Andrid 4.4+, the following data types are handled by such system apps:
Browser: URIs with schemes "http:" and "https:".
Contacts and Dialer: MIME types "text/vcard" and "text/x-vcard" for importing contacts.
E-mail: URIs with scheme "mailto:"
In addition, if no other app handles a certain tag, NFC devices should(?) have the Tag app, that tries to handle various types (upon user confirmation):
URIs with scheme "tel" will cause an ACTION_CALL intent to call the given number.
URIs with schemes "sms"/"smsto" will cause an ACTION_SENDTO intent to start editing an SMS message.
Other URIs should(?) be forwarded in ACTION_VIEW intents.
MIME type records with type "text/x-vcard" (if not already handled) should be forwarded in ACTION_VIEW intents.
The text message of Text RTD records (not text/* MIME types!) should be displayed in the Tag app. Unfortunately many stupid(!) NFC apps register for Text records, thus you will normally not get to the Tag app.
MIME type records with type image/* (if image type is supported by Android) should be displayed in the Tag app.
Some records are handled by the NFC service itself (this should always be available on Android):
Android Application records (NFC Forum external type with type name "urn:nfc:ext:android.com:pkg") cause an ACTION_VIEW intent with the URI "market://details?id={PACKAGE_NAME}" to be sent.
NFC Forum external types with type name "urn:nfc:nokia.com:bt" are parsed for Bluetooth connection handover.
NDEF messages starting with a Handover Select RTD record and containing a MIME type record of type "application/vnd.bluetooth.ep.oob" are parsed for Bluetooth connection handover.
Everything with NFC involves an application for responding to the tag. Whether that is a "special tag reading application" depends on your own personal definition of "special tag reading application".
For example, some Web browsers will support NDEF-formatted tags with the payload being a URL. But that's a browser thing, not an OS thing. For example, the AOSP browser app has the manifest entry to respond to NDEF-formatted tags with URLs beginning with http or https. By my definition of "special tag reading application", the AOSP browser is a "special tag reading application". While hopefully all NFC-capable devices will ship with a Web browser that supports NDEF-formatted tags, that's not guaranteed.
If your "some data" is anything else, whether or not there is an app that is set up to respond to that sort of data. After URLs, the next-most-common tag payload is identified via a MIME type, just like you use with Web apps, and so if there is an app installed that supports NDEF and is set up to respond to your MIME type, it will pick up your data. This is no different than having your Web server serve up content under some MIME type -- an app needs to be installed that honors http/https URLs (or files downloaded by a browser) and that MIME type.
if the device reading the tag does not have the required application to read the data/instructions off the tag it still opens a URL that sends you to the Play Store to download that application
An AAR (Android Application Record) was added to the NDEF message written to the NDEF-formatted tag. That is the only NDEF item that can be thought of as being handled by the platform itself, and that's only for devices that support the Play Store (and apps that are distributed via the Play Store).
Related
I have an android device with this app installed on it. Then have a second device that I have factory-reset. Both are NFC enabled. And I am trying to provision the second device with a device owner application. I want to understand how this works. I am under the impression that when I bump the two devices together, something should happen. However, nothing happens. Both devices are on and I believe that I am bumping them in the right places. I have not worked with NFC before.
On the NFCProvisioning app provided by Google, that I linked above, I can see that the wifi ssid, and password are set in the ndef message. However, the url to the deviceowner app is not set anywhere. How will the device being provisioned know how to download the apk?
Also what about this nfcprovisioning.txt? Please, can someone who has done this before help me out. Many thanks!
So Now I have more time I can give a full answer.
So some background on Android and NFC first.
The Android OS has some built in parsing and handling of some types of data on NFC cards, it will handle cards with NDEF messages on them.
When an NFC card is presented the OS will attempt to read and understand the card. If there is no App running that has expressed and interest in NFC NDEF messages it will handle some types of NDEF messages in certain was.
E.g. If the NDEF message contains record with the Mime Type saying "Web Address" the OS will launch a web browser (or ask the user which web browser to open the URL in)
An NDEF message can also contain an "Android Application Reference" or AAR record, this specifies a package name that should handle the data on the card. If that application is not installed it will open up google play to install it.
(https://developer.android.com/guide/topics/connectivity/nfc/nfc.html#aar)
Details on Mime Types and AAR at https://developer.android.com/guide/topics/connectivity/nfc/nfc.html#create-records
This is all done by they OS creating an Intent from the NDEF data and passing it to applications.
So more specific to NFCProvisioning creates an NDEF message of a special Mime Type "application/com.android.managedprovisioning" that Android Understands is about Device Provisioning and that to use a package name that is was given or "com.example.android.deviceowner" or "com.example.android.deviceowner/.DeviceOwnerReceiver" if non given.
The package name could be one found on the play store but it also has a option to specify a URL to download the management app package from.
There is other data included in the NDEF message to Like Wifi details, time zone etc will will be passed on the the Device provisioning app.
Details of what can be passed is at https://developer.android.com/reference/android/app/admin/DevicePolicyManager#MIME_TYPE_PROVISIONING_NFC I believe
The problem you might be suffering is that the method used for the Provisioner device uses to send the data is NfcAdapter#setNdefPushMessage http://developer.android.com/reference/android/nfc/NfcAdapter.html#setNdefPushMessage(android.nfc.NdefMessage,%20android.app.Activity,%20android.app.Activity...) which has been deprecated in API level 29/ Android 10 (and no longer works)
see the issues raised on this https://github.com/android/enterprise-samples/issues/27
I have not used this process before, but looking at the code the "nfcprovisioning.txt" is just a text file you can load in that stores the values of the key=value pairs instead of having to type them in to the App every time.
e.g. it would have lines like for that the data you want to provision
EXTRA_PROVISIONING_WIFI_SSID=someWifiSSid
I am looking for a way to create a NFC-tag that shares the wifi credentials of my network without my guests having to have any special NFC apps on their phone (other than whats coming with the phone).
I have been looking at apps and services like NFC Tag Writer, WifiTap, NFC Task Launcher and NFCLabels.com, but it seems to me like it I would need to have the apps on the guest mobile as well to be able to use it, but I am not able to test it as I only have one NFC-enabled phone available. (Yes, I know, twisting my brains for nothing, but heck, weird behaviour is nothing new...)
My closest clue is that WifiTap states that:
The app processes URIs in the format of wifi://[network ssid]/[wep|wpa|open]/[network key]
If this is actually universal this would mean that I could do what I what I want to, but I have not found any confirmation on this. So, how could what I want be done and am I on the right track with the clue from WifiTap?
As Alex wrote in a comment, you can now (since Lollipop) write a tag containing Wi-Fi credentials directly from the Android Wi-Fi settings: long-tap a network → Write to NFC tag.
It seems to be an NDEF-formatted tag with the application/vnd.wfa.wsc MIME type and a "WPS NFC" token.
The relevant source code can be found in platform/packages/apps/Settings/src/com/android/settings/wifi/WriteWifiConfigToNfcDialog.java.
There is an official standard for this kind of situation: NFC Forum Connection Handover Technical Specification. However, this is currently not supported by Android. I don't think there is currently any way to transfer WiFi credentials using NFC without the help of a dedicated app.
One way of going about this is to create (or find) an app in the Google Play Store that has the following properties:
Intent filter for ACTION_NDEF_DISCOVERED and as URI the URL of the app in the Play Store.
Intent filter for ACTION_NDEF_DISCOVERED and as type some proprietary type (e.g. a MIME type)
Then you can create tags with an NDEF message containing the following NDEF records:
SmartPoster record with Play Store URI and some descriptive text (e.g. name of the app)
Record of proprietary type containing the WiFi credentials
Android Application Record for the app
The 3rd record will make sure that the proper app will always be started or the device user will be redirected to the Play Store to install it. This works only on ICS, however, but the 1st record (combined with the 1st intent filter) serves the same purpose on Gingerbread.
I've created an app which actually writes networks to tag in a standardized way - the problem is that Android does not currently recognize the handover records and automagically add them. And maybe that is all right - after all there is more to adding a network than just adding a network; you might for example verify the composer of the tag contents and so on.
Also, if you'd like to write more than one network to a tag, there might simply not be enough space to do it in the right (using standardized records) way.
I may have the wrong end of the stick but with the app nfc tools downloaded form the play store you can write a wifi network onto a tag that when scanned with defult android 5.0.2. On a nexus 7 2013 opens a message box asking confirmation formthe wifi connection, although this has always failed bar o
A URI of the form WIFI:T:WPA;S:SSID;P:PASSPHRASE;; will set WiFi if encoded to a QR code and scanned; but when encoded to an NFC tag it is unrecognized as a URI. This suggests to me that the NFC API is deficient in Android.
So here is my basic motivation for my question obfuscated a little:
I want to track a users loyalty to a particular store. Each store would have a NFC sticker on the register. On purchase the user would use an app on their phone (NFC available of course) and the sticker would send back some code that designates the store.
Now here is my question, one, can I send a simple code back to my application that is then, for example, added to some database? This link, near the bottom, provides a description of 'Content Options' none of which I want. Also, the NFC-Forum specifications don't tell me much (or I'm just not looking in the right place).
Also, how do I actually put this tag/code onto one of these stickers? If I do it myself can I make them read-only?
you can put arbitrary information on the NFC tag - there is no limitation what you can upload and in which format. Think about NFC tags like if they were normal data storage places like e.g. hardrive or CD - to those you can save to them files with arbitrarty format holding the arbitrary content. Same with NFC tags.
Anyway there is recommended NFC Forum standard for the content format called NDEF (NFC Forum Data Exchange Format is a lightweight binary message format designed to
encapsulate one or more application-defined payloads into a single message construct.)
Also for specific data (links, Phone number, calendar event, etc.) there is another recommended NFC Forum standard called RTD (Record Type Definition specifies the format and rules for building standard record types used by NFC Forum application definitions and third parties that are based on the NDEF data format).
So in fact you can use arbitrary data format or NDEF, for the data itself you can follow RTD recommendations or not... It is up to you.
For tag writing you can buy some existing software and USB NFC reader/writer or you can program your own software - this is more difficult, since you must know HW characteristic of tag you would like to use.
All tags allow permanent data locking.
Regards,
STeN
www.mautilus.com, petr.mazanec#mautilus.com
For Android devices, you would create a tag with an so-called Android Application Record (AAR). The AAR contains the package name of your application, and, using a technology called Beam, Android automatically launches your application. You are then free to access the other records contained within the NDEF message, which then probably would contain the id of the shop somehow, and contact your site.
I have tried AAR already and it works, also I have created an NFC Eclipse plugin which would get you up and running in no time, if you have an Android phone and some tag, of course ;-)
I've been able to successfully write URL and text data to RFID tags, these are recognized by the Android Tags app, but I have been unable to get the Tags app to recognize vcard data. Where I would assume it would give me the option to add contact after scanning I only see the MIME type text/x-vcard.
Can anyone confirm whether or not the Tags app will recognize vcard data?
Thanks,
Chris
Yes, the tags app should be able to recognize v-card data.
I've used the NXP TagWriter app to write a vcard to a Mifare Classic card, then read it in via the Tags app. It showed up as a contact type and allowed me to import the contact into the contacts system.
I've also had success in using the Tags app to read vcard data off of a demo NFC-enabled business card.
Did you try the recommended Android app from NXP? You can find the applications at google play: https://play.google.com/store/apps/developer?id=NXP+Semiconductors
The TagWriter app lets you write urls, contact, text or sms. If you do so with a brand new mifare tag the app will show a message before confirmation that the tag needs to be formatted for NDEF first.
This routine worked fine for me with a new tag. A Nexus 7 tablet showed the contact card when the tag was presented afterwards.
I also tried the same routine with a tag that was previously formatted as an NDEF tag but that failed. Each time I tried it turned up as an empty NDEF tag. I used the NFC TagInfo app (see link on top) for checking the contents of that tag and it turns out that only one sector (sector 1, counting from 0) is written with the vcard information. Resulting in an incomplete tag. Because the tag is already NFC formatted the tagWriter app doesn't propose to format the tag. My guess is that it's badly formatted, not to the full 1K size size.
Make sure to enable full scan at scan level using the preferences of the taginfo app.
I still haven't quite got this "Intent" thing down when it comes to the details. What I'd like to do is to receive an intent when a certain email attachment is opened. The attachment will be a file that is actually an SQLite database with a structure specific to my app, and with a file extension that is also specific to my app.
What I've noticed in experimenting with this is that, when I send the file attachment from my PC (using Thunderbird), it is coded with a MIME type of "application/octet-stream". When I try to open this on my Android phone (using K-9 mail), it tells me that there is no app for "application/octet-stream".
So what do I do in my app to be recognized as a servicing app for this particular type of attachment, especially since I expect it's not a good idea to try to open anything with this MIME type.
So what do I do in my app to be recognized as a servicing app for this particular type of attachment, especially since I expect it's not a good idea to try to open anything with this MIME type.
You don't.
Inventing new documents as email attachments doesn't work well pretty much anywhere. Android is just a notch worse in this regard.
You cannot realistically set up an ACTION_VIEW <intent-filter> by MIME type, because your MIME type is too general. You cannot set up an ACTION_VIEW <intent-filter> by file extension, because there is no file extension on email attachments as is processed by the AOSP email app, and perhaps other email clients as well.
I encourage you to abandon email attachments as a delivery vector for your files, and find some other solution where you can have a customized MIME type (e.g., download the files from a Web server, with the emails containing a link to the files). Then, an ACTION_VIEW <intent-filter> by MIME type can work OK.