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:

  1. 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.

  2. 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

Popular posts from this blog

javascript - RequestAnimationFrame not working when exiting fullscreen switching space on Safari -

Python ctypes access violation with const pointer arguments -