为NfcV标签创建自定义Cordova插件

Creating custom Cordova plugin for NfcV Tags

本文关键字:Cordova 插件 自定义 创建 NfcV 标签      更新时间:2023-09-26

我需要读取数据NfcV (ISO 15693)标签,我已经尝试了Phonegap-Nfc插件从战车解决方案,但似乎这个插件只能读取TagId和类型的NfcV标签,所以我决定我可以创建我自己的自定义插件,我首先发现了echo Hello World插件教程工作得很好,没有问题,所以我寻找Java NfcV阅读器,发现这个Java NfcV阅读器。

到目前为止,我所理解的是,我需要调用cordova。从CordovaPlugin扩展我的Java类,它是工作的。

我不懂Java,因为我是一个web开发人员,这对我来说有点困难。

这实际上看起来很好,但我试着用Hello World的方式来实现它,但没有按计划工作。

我现在有一个插件文件夹

Hello.java

    package org.apache.cordova.plugin;
    import org.apache.cordova.CallbackContext;
    import org.apache.cordova.CordovaPlugin;
    import org.json.JSONArray;
    import org.json.JSONException;

    /**
     * This class echoes a string called from JavaScript.
     */
    public class Hello extends CordovaPlugin
    {
        @Override
        public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
            if (action.equals("hello")) {
                String message = args.getString(0);
                this.hello(message, callbackContext);
                return true;
            }
            return false;
        }
        private void hello(String message, CallbackContext callbackContext) {
            if (message != null && message.length() > 0) {
                callbackContext.success(message);
            } else {
                callbackContext.error("Expected one non-empty string argument.");
            }
        }
    }

ReadNfcV.java从上面的链接

    package org.apache.cordova.plugin;
    import org.apache.cordova.CallbackContext;
    import org.apache.cordova.CordovaPlugin;
    import org.json.JSONArray;
    import org.json.JSONException;
    import java.io.IOException;
    import java.nio.ByteBuffer;
    import java.util.HashMap;
    import org.apache.http.util.ByteArrayBuffer;
    import android.nfc.Tag;
    import android.nfc.TagLostException;
    import android.nfc.tech.NfcV;
    import android.nfc.tech.TagTechnology;
    //import android.os.Parcelable;
    import android.util.Log;
    /**
        * @author uhahn
        *
        */
    public class ReadNfcV extends CordovaPlugin implements TagTechnology {
            protected NfcV mynfcv;
    //      protected Tag mytag; // can be retrieved through mynfcv
    
            private final String TAG=this.getClass().getName();
            protected final int maxtries=3;
    
            protected boolean isTainted=true; // Tag info already read?
            protected byte[] mysysinfo=null;        // NfcV SystemInformation - or generated
            protected byte[] myuserdata=null;       // buffer user content
            protected boolean[] blocktainted;       // true when block is to be uploaded to tag
            protected byte[] blocklocked;           // 0 means writable
    
            protected byte afi=0;
            public byte nBlocks=0;
            public byte blocksize=0;
            public byte[] Id;
            public byte[] UID; // becomes valid when a real tag is contacted
            public byte DSFID = -1;
            public int maxtrans=0; // tag dependent max transceive length
            public byte lastErrorFlags=-1; // re-set by each transceive
            public byte lastErrorCode=-1; // re-set by each transceive
            public byte manuByte=0;
    
            public static final byte BYTE_IDSTART=(byte)0xe0;
            public static final byte MANU_TAGSYS=0x04;
            public static final HashMap<Byte,String> manuMap = new HashMap<Byte, String>();
    
            static{
                    manuMap.put(MANU_TAGSYS, "TagSys");
            }
    
            /**
             * read new NfcV Tag from NFC device
             */
            public ReadNfcV(Tag t) {
                    UID = t.getId(); // sysinfo holds the UID in lsb order -  Id will be filled lateron from sysinfo!
    //              Log.d(TAG,"getId: "+toHex(t.getId()));
                    mynfcv=NfcV.get(t);
                    try {
                            mynfcv.connect();
                            mysysinfo=getSystemInformation(); 
                            // explore Nfcv properties..
                            //initfields(); // done by getSys..
                            maxtrans=mynfcv.getMaxTransceiveLength();
                            DSFID=mynfcv.getDsfId();
                            Log.d(TAG,nBlocks + " x " + blocksize + " bytes");
                            blocklocked=new byte[nBlocks]; // init the lock shadow
                            getMultiSecStatus(0, nBlocks);  // and fill from tag
                    
                            blocktainted=new boolean[nBlocks];
                            taintblock(0,nBlocks);
                    
    //                      Log.d(TAG,"maxtrans "+maxtrans);
                            // init space for userdata ?
                            myuserdata= new byte[nBlocks*blocksize]; 
                    } catch (IOException e) {
                            // TODO Auto-generated catch block
                            lastErrorFlags=-1;
                            Log.d(TAG, "MyNfcV failed: "+e.getMessage());
                            e.printStackTrace();
                    }
            }
    
            /**
             * recreate NfcV Tag from log
             * @param sysinfo: the logged system info only
             */
            public ReadNfcV(String sysinfo){
                    int startat=0;
                    sysinfo.toLowerCase(); // ignore case
                    if(sysinfo.startsWith("0x")){ // lets believe in HEX
                            startat=2;
                    }
                    mysysinfo=hexStringToByteArray(sysinfo.substring(startat));
                    initfields();
                    // init space for userdata TODO limit size?
                    //myuserdata= new byte[nBlocks*blocksize]; 
                    isTainted=false; 
    // TODO fake Tag?               mytag = Tag.CREATOR.createFromParcel(???);
            }
            /**
             * recreate NfcV Tag from log
             * @param sysinfo: the logged system info
             * @param userdata: the logged userdata
             */
            public ReadNfcV(String sysinfo, String userdata){
                    this(sysinfo);
                    // TODO fake userdata
                    int startat=0;
                    userdata.toLowerCase(); // ignore case
                    if(userdata.startsWith("0x")){ // lets believe in HEX
                            startat=2;
                    }
                    myuserdata=hexStringToByteArray(userdata.substring(startat));
            }
    
            /**
             * parse system information byte array into attributes
             * with respect to the flags found
             * DSFID
             * AFI
             * memsize values (block count and length)
             */
            private void initfields(){
                    byte[] read=mysysinfo;
                    if((null!=read)&&(12<read.length)&&(0==read[0])){// no error
                            char flags=(char)read[1]; //s.charAt(1);
                            //      String s=new String(read);
                            //s.substring(2, 9).compareTo(Id.toString())  // the same?
                            //set the Id from mysysinfo
                            int pos=2;
                            boolean forwardId=false; // the Id field is in lsb order
                            if(BYTE_IDSTART==read[pos]){
                                    forwardId=true;
                                    manuByte=read[pos+1];
                            }else if(BYTE_IDSTART==read[pos+7]){
                                    manuByte=read[pos+6];
                                    forwardId=false;
                            }else
                                    Log.e(TAG,"Id start byte not found where expected");
                            if(null==Id){ // dont overwrite, if given
                                    Id=new byte[8];
                                    for(int i=0;i<8;i++) 
                                            // TODO decide if Id to be reversed (Zebra needs msb order, that is Id[7] changes between tags)
                                            Id[i]=(forwardId? read[pos+i] : read[pos + 7 - i]); //reverse?!
                                    Log.d(TAG,"Id from sysinfo (reversed): "+toHex(Id));
                            }
                    
                            pos=10; // start after flags, Infoflags and Id TODO: change if transceive should eat up the error byte 
                            if(0<(flags&0x1)){ // DSFID valid
                                    pos++; // already implemented 
                            }
                            if(0<(flags&0x2)){ // AFI valid
                                    afi=(byte)read[pos++];//s.charAt(pos++);
                            }
                            if(0<(flags&0x4)){ // memsize valid
                                    nBlocks=(byte)(read[pos++]+1);//(s.charAt(pos++)+1);
                                    blocksize=(byte)(read[pos++]+1); //((s.charAt(pos++)&0x1f)+1);
                            }       
                    }
            }
    
            /**
             * @return the stored afi byte
             */
            public byte getAFI(){
                    if(isTainted){ // system info not read yet
                            getSystemInformation(); // fill in the fields
                    }
                    return afi;
            }
    
            public byte getDsfId(){
    //              return mynfcv.getDsfId(); // avoid re-reading
                    return DSFID;
            }
    
            public int getblocksize(){
                    return (int)blocksize;
            }
    
            public int getnBlocks(){
                    return (int)nBlocks;
            }
    
            public byte[] getSystemInformation(){
                    if(isTainted){ // dont reread 
                            mysysinfo=transceive((byte)0x2b);
                            isTainted=false; // remember: we have read it and found it valid
                            if(0==lastErrorFlags){// no error
                                    isTainted=false; // remember: we have read it and found it valid
                                    initfields(); // analyze 
                            }}
                    return mysysinfo;
            }
    
            /**
             * overload method transceive
             * @return resulting array (or error?)
             */
            protected byte[] transceive(byte cmd){
                    return transceive(cmd, -1, -1, null);
            }
            protected byte[] transceive(byte cmd, int m){
                    return transceive(cmd, m, -1, null);
            }
    
            protected byte[] transceive(byte cmd, int m ,int n){
                    return transceive(cmd, m, n, null);
            }
    
            /**
             * prepare and run the command according to NfcV specification
             * @param cmd command byte
             * @param m command length
             * @param n 
             * @param in input data
             * @return
             */
            protected byte[] transceive(byte cmd,int m, int n, byte[] in){
                            byte[] command;
                            byte[] res="transceive failed message".getBytes();
            
                    ByteArrayBuffer bab = new ByteArrayBuffer(128);
                    // flags: bit x=adressed, 
                    bab.append(0x00);
                    bab.append(cmd); // cmd byte
                    // 8 byte UID - or unaddressed
            //      bab.append(mytag.getId(), 0, 8);
                    // block Nr
                    if(-1!=m)bab.append(m);
                    if(-1!=n)bab.append(n);
                    if(null!=in)bab.append(in, 0, in.length);
            
                    command=bab.toByteArray();
                    Log.d(TAG,"transceive cmd: "+toHex(command));
    //              Log.d(TAG,"transceive cmd length: "+command.length);
            
                    // TODO background!
                    try {
                            if(!mynfcv.isConnected()) return res;
                            for(int t=maxtries;t>0;t++){ // retry reading
                                    res=mynfcv.transceive(command);
                                    if(0==res[0]) break;
                            }
                    } 
                    catch (TagLostException e){ //TODO roll back user action
                            Log.e(TAG, "Tag lost "+e.getMessage());
                            try {
                                    mynfcv.close();
                            } catch (IOException e1) {
                                    e1.printStackTrace();
                            }
                            return e.getMessage().getBytes();               
                    }
                    catch (IOException e) {
                            Log.d(TAG, "transceive IOEx: "+e.getMessage()+toHex(res));
            //              e.printStackTrace();
                            return e.getMessage().getBytes();
                    }
                    finally{
                            Log.d(TAG,"getResponseFlags: "+mynfcv.getResponseFlags()); 
                            lastErrorFlags=res[0];
                            Log.d(TAG,"Flagbyte: "+String.format("%2x", lastErrorFlags));
                            if(0!=lastErrorFlags){
                                    lastErrorCode=res[1];
                                    Log.d(TAG,"ErrorCodebyte: "+String.format("%2x", lastErrorCode));
                            }
                    }
                    if(0==mynfcv.getResponseFlags())
                            return (res);
                    else
    //                      return new String("response Flags not 0").getBytes();
                            return res;
            }
    
            public void taintblock(int i, int n){
                    for(int j=0;j<n;j++)
                            setblocktaint(j,true);
            }
            public void taintblock(int i){
                    setblocktaint(i,true);
            }
    
            protected void setblocktaint(int i, boolean b){
                    blocktainted[i]=b;
            }
    
    
            /* (non-Javadoc)
             * @see android.nfc.tech.TagTechnology#getTag()
             * 
             */
            @Override
            public Tag getTag() {
                    // TODO Auto-generated method stub
                    //return mytag;
                    return mynfcv.getTag();
            }
    
            /* (non-Javadoc)
             * @see android.nfc.tech.TagTechnology#close()
             */
            @Override
            public void close() throws IOException {
                    try {
                            mynfcv.close();
                    } catch (IOException e) {
                            // TODO Auto-generated catch block
                            Log.d(TAG, "close failed: "+e.getMessage());
                            e.printStackTrace();
                    }
            }
            /* (non-Javadoc)
             * @see android.nfc.tech.TagTechnology#connect()
             */
            @Override
            public void connect() throws IOException {
                    try {
                            mynfcv.connect();
                    } catch (IOException e) {
                            lastErrorFlags=-1; // TODO discriminate error states
                            Log.d(TAG,"connect failed: "+e.getMessage());
                            e.printStackTrace();
                    }
            }
            /* (non-Javadoc)
             * @see android.nfc.tech.TagTechnology#isConnected()
             */
            @Override
            public boolean isConnected() {
                    // TODO Auto-generated method stub
    //              mynfcv.getDsfId();
                    return mynfcv.isConnected(); // better?
            }
            public byte[] readSingleBlock(int i){
                    byte[] read=transceive((byte)0x20,i);
            
                    setblocktaint(i,false); // remember we read this block
                    if(0!=lastErrorFlags)return read; // TODO not so ignorant..
            
                    byte[] res=new byte[read.length-1]; // drop the (0) flag byte TODO: in transceive?
                    for (int l = 0; l < read.length-1; l++) {
                            res[l]=read[l+1];
                            myuserdata[i*blocksize+l]=res[l]; // sort block into our buffer
                    }
            
                    return res;
            
            }
            /**
             * 
             * @param i starting block number
             * @param j block count
             * @return block content concatenated 
             */
            public byte[] readMultipleBlocks(int i,int j){
                    if(0==blocksize){
                            Log.e(TAG,"readMult w/o initfields?");
                            getSystemInformation(); // system info was not read yet
                    }
                    byte[] read = transceive((byte)0x23,i,j);
                    if(0!=read[0])return read; // error flag set: TODO  left as exercise..
                    byte[] res=new byte[read.length-1]; // drop the (0) flag byte
                    for (int l = 0; l < read.length-1; l++) {
                            res[l]=read[l+1];
                            myuserdata[i*blocksize+l]=res[l]; // sort block into our buffer
                    }
            
                    if(res.length<j*blocksize) return read; // da fehlt was
                    for (int k = i; k < j; k++) { // all blocks we read
                            setblocktaint(k, false); // untaint blocks we read
    // @TODO reverting block order should be done on demand - or under user control (done again in DDMData)
    //              reverse(res,k*blocksize,blocksize); // swap string positions
                    }
                    return res;
            }
    
            public byte[] getMultiSecStatus(int i,int n){
                    byte[] read = transceive((byte)0x2c,i,n-1);
                    Log.d(TAG,"secstatus "+toHex(read));
                    if(0!=read[0])return read;
                    int startat=1; // TODO transceive will skip the error field soon
            
                    for(int j=0;j<nBlocks;j++)
                            blocklocked[j]=read[startat+i+j];
                    return read;
            }
    
    
            /**
             * move anywhere to utils
             * @param s
             * @return
             */
    
        public static String toHex(byte[] in){
            String text=String.format("0x");
            for (byte  element : in) {
                            text=text.concat(String.format("%02x", element));
                    }
            return text;
        }
    
            public static byte[] hexStringToByteArray(String s) {
                int len = s.length();
                byte[] data = new byte[len / 2];
                for (int i = 0; i < len; i += 2) {
                    data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                                         + Character.digit(s.charAt(i+1), 16));
                }
                return data;
            }
    }
我的hello.js文件
        var hello = {
        world: function(str, callback) {
            cordova.exec(callback, function(err) {
                callback('Nothing to hello.');
            }, "Hello", "hello", [str]);
        }
    }
    var ReadNfcV = {
        read: function (str, callback) {
            cordova.exec(callback, function (err) {
                callback('Nothing to hello.');
            }, "Hello", "hello", [str]);
        }
    }
    module.exports = hello;
    module.exports = ReadNfcV;

和my plugin.xml

  <?xml version="1.0" encoding="UTF-8"?>
  <plugin xmlns="http://cordova.apache.org/ns/plugins/1.0"
          id="org.apache.cordova.plugin"
          version="0.1.0">

      <js-module src="hello.js" name="hello">
          <clobbers target="hello" />
      </js-module>
      <!-- Android -->
      <platform name="android">
          <source-file src="Hello.java" target-dir="src/org/apache/cordova/plugin" />
          <source-file src="ReadNfcV.java" target-dir="src/org/apache/cordova/plugin" />
          <config-file target="res/xml/config.xml" parent="/*">
              <feature name="Hello" >
                  <param name="android-package" value="org.apache.cordova.plugin.Hello"/>
              </feature>
          </config-file>
      </platform>
  </plugin>

我能够部署应用程序,所以我可以测试一点,我的问题是,我真的不明白我如何能调用ReadNfc类从ReadNfcV.java文件从我的应用程序内通过javascript。我只是做了同样的教程,但现在的hello。世界函数不再是一个函数了,所以我想我在hello.js文件中做错了。如果有人能帮助并解释我如何通过javascript调用我的java类,然后将java类的结果返回给我的javascript,我将非常感激。我找了2天已经存在的插件,但没有找到任何关于这个主题,但phonegap-nfc插件。

亲切问候Christopher

更新集合

我将tech.NfcV添加到导入列表

import android.nfc.tech.NfcV;

按建议修改execute函数

@Override
public boolean execute(String action, JSONArray data, CallbackContext callbackContext) throws JSONException {
    Log.d(TAG, "execute " + action);
    if (!getNfcStatus().equals(STATUS_NFC_OK)) {
        callbackContext.error(getNfcStatus());
        return true; // short circuit
    }
    createPendingIntent();

    if (action.equals(REGISTER_DEFAULT_TAG)) {
        addTechList(new String[]{NfcV.class.getName()});  //changed this form Mifare to NfcV
        registerDefaultTag(callbackContext);

    } else if (action.equalsIgnoreCase(INIT)) {
        init(callbackContext);
    } else {
        // invalid action
        return false;
    }
    return true;
}

问题似乎是,我得到无效的动作返回的时刻,所以有些东西是错误的在这里

我将registerDefault函数更改为

private void registerDefaultTag(CallbackContext callbackContext) {
addTechFilter();
callbackContext.success();
}

我将Parse Message函数更改为

void parseMessage() {
    cordova.getThreadPool().execute(new Runnable() {
        @Override
        public void run() {
            Log.d(TAG, "parseMessage " + getIntent());
            Intent intent = getIntent();
            String action = intent.getAction();
            Log.d(TAG, "action " + action);
            if (action == null) {
                return;
            }
            if (action.equals(NfcAdapter.ACTION_TECH_DISCOVERED) || action.equals(NfcAdapter.ACTION_TAG_DISCOVERED)){
             Tag tagFromIntent  = (Tag)intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
             NfcV mfc = NfcV.get(tagFromIntent);
             fireTagEvent(tag);
            }
            /*if (action.equals(NfcAdapter.ACTION_NDEF_DISCOVERED)) {
                Ndef ndef = Ndef.get(tag);
                fireNdefEvent(NDEF_MIME, ndef, messages);
            } else if (action.equals(NfcAdapter.ACTION_TECH_DISCOVERED)) {
                for (String tagTech : tag.getTechList()) {
                    Log.d(TAG, tagTech);
                    if (tagTech.equals(NdefFormatable.class.getName())) {
                        fireNdefFormatableEvent(tag);
                    } else if (tagTech.equals(Ndef.class.getName())) { //
                        Ndef ndef = Ndef.get(tag);
                        fireNdefEvent(NDEF, ndef, messages);
                    }
                }
            }
            if (action.equals(NfcAdapter.ACTION_TAG_DISCOVERED)) {
                fireTagEvent(tag);
            }*/
            setIntent(new Intent());
        }
    });
}

所以目前我得到错误无效的动作,只要我点击开始监听和调用Javascript中的Taglisteners,我使用所有4个不同的监听器,看看是否有任何工作。似乎我需要编写一个新的fireEvent函数特定于NfcV,因为现有的不工作

更新2

我已经设法编译插件和部署应用程序,但没有发生任何事情,我没有得到一个标签对象返回

解析消息函数

void parseMessage() {
    cordova.getThreadPool().execute(new Runnable() {
        @Override
        public void run() {
            Log.d(TAG, "parseMessage " + getIntent());
            Intent intent = getIntent();
            String action = intent.getAction();
            Log.d(TAG, "action " + action);
            if (action == null) {
                return;
            }
        if (action.equals(NfcAdapter.ACTION_TECH_DISCOVERED) || action.equals(NfcAdapter.ACTION_TAG_DISCOVERED)){
            Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
                    if(tag != null){
                      byte[] id = tag.getId();
                      // set up read command buffer
                      byte blockNo = 0; // block address
                      byte[] readCmd = new byte[3 + id.length];
                      readCmd[0] = 0x20; // set "address" flag (only send command to this tag)
                      readCmd[1] = 0x20; // ISO 15693 Single Block Read command byte
                      
                      System.arraycopy(id, 0, readCmd, 2, id.length); // copy ID
                      readCmd[2 + id.length] = blockNo; // 1 byte payload: block address
                      NfcV tech = NfcV.get(tag);
                      if (tech != null) {
                        // send read command
                        try {
                          tech.connect();
                          byte[] data = tech.transceive(readCmd); 
                          fireTagEvent(data);
                        } catch (IOException e) {
                          e.printStackTrace();
                        } finally {
                          try {
                            tech.close();
                          } catch (IOException e) {
                            e.printStackTrace();
                          }
                        }
                      }
                    }
            setIntent(new Intent());
        }
    
    }
 });
}
我fireTagEvent

private void fireTagEvent(byte[] data) {
    String s2 = new String(data);
    String command = MessageFormat.format(javaScriptEventTemplate, TAG_DEFAULT, s2);
    Log.v(TAG, s2);
    this.webView.sendJavascript(s2);
}

execute函数

@Override
public boolean execute(String action, JSONArray data, CallbackContext callbackContext) throws JSONException {
    Log.d(TAG, "execute " + action);
    if (!getNfcStatus().equals(STATUS_NFC_OK)) {
        callbackContext.error(getNfcStatus());
        return true; // short circuit
    }
    createPendingIntent();

    if (action.equals(REGISTER_DEFAULT_TAG)) {
        addTechList(new String[]{NfcV.class.getName()});
        registerDefaultTag(callbackContext);

    } else if (action.equalsIgnoreCase(INIT)) {
        init(callbackContext);
    } else {
        // invalid action
        return false;
    }
    return true;
}

这就是应用程序启动"addTagDiscoveredListener"是注册的,但我没有得到任何对象返回,所以nfcv标签没有读取,或者我只是没有得到任何返回不确定…

我使用车夫解决方案插件作为开始构建我自己的nfc阅读插件。我想如果你不从头开始,会节省很多时间。

你可以删除很多东西,因为原来的插件只处理NDEF标签,但是删除行比重新发明轮子要快得多。

我脑子里有点老了,所以我不确定我能解释对所有的事情…我的需要是在Mifare经典标签中读取信息,但也许你可以适应你的需要…所以,如果你看一下NfcPlugin.java,在执行函数中,我只保留了REGISTER_DEFAULT_TAG和INIT动作的代码。

更新了REGISTER_DEFAULT_TAG中的代码,以注册侦听mifare classic标记。并修改了registerDefaultTag函数来调用addTechFilter而不是addTagFilter。

这就留给我们public boolean execute(String action, JSONArray data, CallbackContext, CallbackContext)抛出JSONException {

    Log.d(TAG, "execute " + action);
    if (!getNfcStatus().equals(STATUS_NFC_OK)) {
        callbackContext.error(getNfcStatus());
        return true; // short circuit
    }
    createPendingIntent();

    if (action.equals(REGISTER_DEFAULT_TAG)) {
        addTechList(new String[]{MifareClassic.class.getName()});
        registerDefaultTag(callbackContext);

    } else if (action.equalsIgnoreCase(INIT)) {
        init(callbackContext);
    } else {
        // invalid action
        return false;
    }
    return true;
}
private void registerDefaultTag(CallbackContext callbackContext) {
    addTechFilter();
    callbackContext.success();
}

现在你需要理解的是,一旦你从js中调用了init函数,每次设备看到nfc标签时,插件的parseMessage函数都会被调用。

在parseMessage函数中我有一个test

if (action.equals(NfcAdapter.ACTION_TECH_DISCOVERED) || action.equals(NfcAdapter.ACTION_TAG_DISCOVERED))

里面有处理标签的所有代码

在该代码中,

可以从intent中的标签获取信息,使用如下所示:

            Tag tagFromIntent  = (Tag)intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
            MifareClassic mfc = MifareClassic.get(tagFromIntent);

然后根据你的处理,你可以调用fireerrovent或fire…事件,使用webView.sendJavascript函数将数据返回给javascript。

我没有时间详细说明js部分。

不确定它是否会帮助你,或者它是否是你想要的方式(不知道你正在使用的标签是如何工作的)。如果它对你有帮助,如果你需要更多的细节,请告诉我。

好了,我终于让它工作了

在Phonegap-nfc.js中,我为NFCV标签添加了一个事件监听器

addNfcVListener: function (callback, win, fail) {
        document.addEventListener("nfcv", callback, false);
        cordova.exec(win, fail, "NfcPlugin", "registerNfcV", []);
    },

匹配的Execute函数如下所示

@Override
    public boolean execute(String action, JSONArray data, CallbackContext callbackContext) throws JSONException {
        Log.d(TAG, "execute " + action);
        if (!getNfcStatus().equals(STATUS_NFC_OK)) {
            callbackContext.error(getNfcStatus());
            return true; // short circuit
        }
        createPendingIntent();

         if (action.equalsIgnoreCase(REGISTER_NFCV)) {
          registerNfcV(callbackContext);
        }else {
            // invalid action
            return false;
        }
        return true;
    }

这里是标签被添加到技术列表的地方

private void registerNfcV(CallbackContext callbackContext) {
      addTechList(new String[]{NfcV.class.getName()});
      callbackContext.success();
  }

这里Tag被解析并触发一个事件

void parseMessage() {
        cordova.getThreadPool().execute(new Runnable() {
            @Override
            public void run() {
                Log.d(TAG, "parseMessage " + getIntent());
                Intent intent = getIntent();
                String action = intent.getAction();

                Log.d(TAG, "action " + action);
                if (action == null) {
                    return;
                }

                if (action.equals(NfcAdapter.ACTION_TECH_DISCOVERED) || action.equals(NfcAdapter.ACTION_TAG_DISCOVERED)){
                     NfcvData ma;
                     Tag tagFromIntent  = (Tag)intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
                     Parcelable[] messages = intent.getParcelableArrayExtra((NfcAdapter.EXTRA_NDEF_MESSAGES));
                     NfcV mfc = NfcV.get(tagFromIntent);
                     Tag tag = mfc.getTag();
                     fireNfcVReadEvent(NFCV, mfc, messages);
                }
                setIntent(new Intent());
            }
        });
    }

则此事件称为

private void fireNfcVReadEvent(String type, NfcV nfcv, Parcelable[] messages) {
        JSONObject jsonObject = buildNfcVReadJSON(nfcv, messages);
        String tag = jsonObject.toString();
        String command = MessageFormat.format(javaScriptEventTemplate, type, tag);
        Log.v(TAG, command);
        this.webView.sendJavascript(command);
    }

它将Taginformation发送回我的Javascript

看起来您没有在回调中发送任何数据,只是cordova SUCCESS。callbackContext.success (returndatahere);支持的数据类型请参见cordova插件规范。