Simplest method for applying NFC trigger to basic timer application (Android) -
i have basic countdown app counts down 10 secs when button clicked. simplest method have timer start when contact made specific nfc tag? (ntag203)
i've read several nfc tutorials , 1 i've been able work has been simple tag reader. if wanted have specific nfc tag trigger simple timer app button would, how go doing so? best try read id or interpret plain text identifier?
thanks (using android studio)
nfc app main activity (code taken tutorial: http://shaikhhamadali.blogspot.com/2013/10/near-field-communication-nfc-android.html
package com.example.nfctest2.nfctest2app; import java.io.unsupportedencodingexception; import java.util.arrays; import android.app.activity; import android.app.pendingintent; import android.content.intent; import android.content.intentfilter; import android.content.intentfilter.malformedmimetypeexception; import android.nfc.ndefmessage; import android.nfc.ndefrecord; import android.nfc.nfcadapter; import android.nfc.tag; import android.nfc.tech.ndef; import android.os.asynctask; import android.os.bundle; import android.util.log; import android.widget.textview; import android.widget.toast; public class mainactivity extends activity { public static final string mimetype_text_plain = "text/plain"; public static final string tag = "nfctut"; private textview tv_readnfc; private nfcadapter nfcadapt; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); //initialize control tv_readnfc = (textview) findviewbyid(r.id.tv_readnfc); //initialise nfc adapter nfcadapt = nfcadapter.getdefaultadapter(this); //check nfc adapter initialized null when device doesn't support nfc if (nfcadapt == null) { // device deosn't support nfc toast.maketext(this, "your device doesn't support nfc.", toast.length_short).show(); finish(); return; } //check nfc adapter feature enabled if (!nfcadapt.isenabled()) { tv_readnfc.settext("nfc disabled."); } else { tv_readnfc.settext(r.string.attachnfctoread); } handleintent(getintent()); } @override protected void onresume() { super.onresume(); } @override protected void onpause() { //call before onpause, avoid illegalargumentexception. stopforegrounddispatch(this, nfcadapt); super.onpause(); } @override protected void onnewintent(intent intent) { handleintent(intent); } private void handleintent(intent intent) { //get action intent string action = intent.getaction(); //is action matches ndef_discovered if (nfcadapter.action_ndef_discovered.equals(action)) { //what mime type string type = intent.gettype(); //is text plain or not if (mimetype_text_plain.equals(type)) { //create tag instance , retrieve extended data intent tag tag = intent.getparcelableextra(nfcadapter.extra_tag); //execute background task new ndefreaderbgtask().execute(tag); } else { log.d(tag, "mime type not text/plain: " + type); } } //is action matches action_tech_discovered else if (nfcadapter.action_tech_discovered.equals(action)) { // in case still use tech discovered intent tag tag = intent.getparcelableextra(nfcadapter.extra_tag); //get available technologies string[] techlist = tag.gettechlist(); //get class name string searchedtech = ndef.class.getname(); (string tech : techlist) { //tag matched execute background task if (searchedtech.equals(tech)) { new ndefreaderbgtask().execute(tag); break; } } } } /** * @param act corresponding {@link activity} requesting foreground dispatch. * @param adp {@link nfcadapter} used foreground dispatch. */ public static void requestforegrounddispatch(final activity act, nfcadapter adp) { //create instance of intent final intent intent = new intent(act.getapplicationcontext(), act.getclass()); //set flags on top intent.setflags(intent.flag_activity_single_top); //crate instance of pending intent final pendingintent pendingintent = pendingintent.getactivity(act.getapplicationcontext(), 0, intent, 0); //create intent filters array intentfilter[] filters = new intentfilter[1]; //create 2d array of techlist string string[][] techlist = new string[][]{}; // note: same filter in our manifest. filters[0] = new intentfilter(); filters[0].addaction(nfcadapter.action_ndef_discovered); filters[0].addcategory(intent.category_default); try { //add data type filters[0].adddatatype(mimetype_text_plain); } catch (malformedmimetypeexception e) { //throw exception on different mime type throw new runtimeexception("check mime type."); } //enable foreground dispatch current activity adp.enableforegrounddispatch(act, pendingintent, filters, techlist); } public static void stopforegrounddispatch(final activity act, nfcadapter adp) { adp.disableforegrounddispatch(act); } private class ndefreaderbgtask extends asynctask<tag, void, string> { @override protected string doinbackground(tag... params) { tag tag = params[0]; ndef ndef = ndef.get(tag); if (ndef == null) { // when ndef not supported tag. return null; } //get ndefmessage read tag @ discovery time. ndefmessage ndefmessage = ndef.getcachedndefmessage(); //get ndef records inside ndef message. ndefrecord[] records = ndefmessage.getrecords(); (ndefrecord ndefrecord : records) { if (ndefrecord.gettnf() == ndefrecord.tnf_well_known && arrays.equals(ndefrecord.gettype(), ndefrecord.rtd_text)) { try { return readndefrecordtext(ndefrecord); } catch (unsupportedencodingexception e) { log.e(tag, "unsupported encoding", e); } } } return null; } private string readndefrecordtext(ndefrecord record) throws unsupportedencodingexception { // record pay load variable length byte[] payload = record.getpayload(); // text encoding string textencoding = ((payload[0] & 128) == 0) ? "utf-8" : "utf-16"; // language code int languagecodelength = payload[0] & 0063; // string languagecode = new string(payload, 1, languagecodelength, "us-ascii"); // e.g. "en" // text return new string(payload, languagecodelength + 1, payload.length - languagecodelength - 1, textencoding); } @override protected void onpostexecute(string result) { if (result != null) { tv_readnfc.settext("content in tag: " + result); } } } }
using foreground dispatch receive nfc event start.
identifying specific tag depends on need in context:
you match tag ids. easiest approach every tag exposes id used nfc device during tag enumeration , anti-collision. however, approach has limitations:
not tags expose static ids. tags generate fresh random id upon power-up. identifying such tag id therefore impossible.
depending on protocol, ids may have different lengths. e.g. iso 14443a (
nfca
) tag may have 4-byte, 7-byte or 10-byte uid. thus, have consider when creating database of valid tags.you can't auto-start app based on specific id.
you have record every allowed id in database , can't define large set of allowed tags.
you use specific ndef record on tag. in opinion prefered way go.
i refrain using text record type (or text/* mime type records) these types supposed used transport human-readable , (more importantly) human-interpreted text.
instead, suggest define own nfc forum external type name (specifications available free nfc forum) , create record using type name.
this allows auto-start (and your) app filtering particular type name.
you can start countdown based on either presence of ndef record particular type name, or
you can add specific data payload tags (e.g. custom identifier) allow tags have type name start countdown or distinguish between different tags carrying record type name.
for id matching scenario, suggest modify foreground dispatch activation (don't forget activate foreground dispatch in onresume()
):
public static void requestforegrounddispatch(final activity act, nfcadapter adp) { final intent pendingintent = pendingintent.getactivity(act, 0, new intent(act, act.getclass()).addflags(intent.flag_activity_single_top), 0); intentfilter[] filters = new intentfilter[] { new intentfilter(nfcadapter.action_tech_discovered) }; string[][] techlist = new string[][] { new string[] { nfca.class.getname() } }; adp.enableforegrounddispatch(act, pendingintent, filters, techlist); }
this match iso 14443 type tag (like ntag203).
then retrieve tag's id in handleintent method this:
private void handleintent(intent intent) { string action = intent.getaction(); if (nfcadapter.action_tech_discovered.equals(action)) { tag tag = intent.getparcelableextra(nfcadapter.extra_tag); byte[] id = tag.getid(); // id } }
Comments
Post a Comment