NFC 标签(用于 NfcA)扫描仅从第二次开始有效

NFC tag(for NfcA) scan works only from the second time

我编写了一个自定义插件来从 NfcA(i.e.non-ndef) 标签中读取数据块。它似乎工作正常,但只有在第二次扫描之后。我正在使用 Activity 意图导出 "NfcAdapter.EXTRA_TAG" 以便稍后使用它来读取值。我也在更新 onNewIntent() 中的意图。 OnNewIntent 在第二次扫描后被调用,之后我得到结果所有 time.But 在第一次扫描 onNewIntent 没有被调用,因此我最终使用 Activity 标签没有 "NfcAdapter.EXTRA_TAG",因此我得到空值。请在下面查看我的代码。

SE_NfcA.java(我的插件本机代码)

 @Override    
 public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {      
    String Result = "";
    String TypeOfTalking = "";                   
    if (action.contains("TalkToNFC")) 
    {
        JSONObject arg_object = args.getJSONObject(0);
        TypeOfTalking = arg_object.getString("type");           

        if(TypeOfTalking != "")
        {
          if (TypeOfTalking.contains("readBlock")) 
            {
                if(TypeOfTalking.contains("@"))
                {
                    try
                    {
                        String[] parts = TypeOfTalking.split("@");
                        int index = Integer.parseInt(parts[1]);
                        Result = Readblock(cordova.getActivity().getIntent(),(byte)index);
                        callbackContext.success(Result);
                    }
                    catch(Exception e)
                    {
                        callbackContext.error("Exception Reading "+ TypeOfTalking + "due to "+ e.toString());
                        return false;
                    }
                }               
            }                   
          else 
            {
                return false;
            }           
        }
        else 
            {
                return false;
            }       
    }
    else 
        {
            return false;
        }      
    return true;
}

@Override
public void onNewIntent(Intent intent) {    
ShowAlert("onNewIntent called");
Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
super.onNewIntent(intent);
getActivity().setIntent(intent);
savedTag = tagFromIntent;
savedIntent = intent;   
}

@Override
public void onPause(boolean multitasking) {
Log.d(TAG, "onPause " + getActivity().getIntent());
   super.onPause(multitasking);
    if (multitasking) {
        // nfc can't run in background       
        stopNfc();
    }
}

@Override
public void onResume(boolean multitasking) {
Log.d(TAG, "onResume " + getActivity().getIntent());
super.onResume(multitasking);
startNfc();
}

public String Readblock(Intent Intent,byte block) throws IOException{       
    byte[] response = new byte[]{};
    if(Intent != null)
    {
        Tag myTag = Intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        if(savedTag != null)
            myTag = savedTag;

        if(myTag != null)
        {           
            try{                
            Reader nTagReader = new Reader(myTag);                          
                nTagReader.close();
                nTagReader.connect();
                nTagReader.SectorSelect(Sector.Sector0);                    
                response = nTagReader.fast_read(block, block);
                nTagReader.close();             
                return ConvertH(response);                  
            }catch(Exception e){
                ShowAlert(e.toString());                    
            }
    }
        else
            ShowAlert("myTag is null.");            
    }       
    return null;
}

 private void createPendingIntent() {
        if (pendingIntent == null) {
            Activity activity = getActivity();
            Intent intent = new Intent(activity, activity.getClass());
            intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP| Intent.FLAG_ACTIVITY_CLEAR_TOP);
            pendingIntent = PendingIntent.getActivity(activity, 0, intent, 0);
        }
    }

 private void startNfc() {
      createPendingIntent(); // onResume can call startNfc before execute
        getActivity().runOnUiThread(new Runnable() {
            public void run() {
                NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(getActivity());
                if (nfcAdapter != null && !getActivity().isFinishing()) {
                    try {
                        nfcAdapter.enableForegroundDispatch(getActivity(), getPendingIntent(), getIntentFilters(), getTechLists());

                        if (p2pMessage != null) {
                            nfcAdapter.setNdefPushMessage(p2pMessage, getActivity());
                        }
                    } catch (IllegalStateException e) {
                        // issue 110 - user exits app with home button while nfc is initializing
                        Log.w(TAG, "Illegal State Exception starting NFC. Assuming application is terminating.");
                    }
                }
            }
        });
    }

    private void stopNfc() {
        Log.d(TAG, "stopNfc");
        getActivity().runOnUiThread(new Runnable() {
            public void run() {
                NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(getActivity());
                if (nfcAdapter != null) {
                    try {
                        nfcAdapter.disableForegroundDispatch(getActivity());
                    } catch (IllegalStateException e) {
                        // issue 125 - user exits app with back button while nfc
                        Log.w(TAG, "Illegal State Exception stopping NFC. Assuming application is terminating.");
                    }
                }
            }
        });
    }

    private Activity getActivity() {
        return this.cordova.getActivity();
    }

    private PendingIntent getPendingIntent() {
        return pendingIntent;
    }

    private IntentFilter[] getIntentFilters() {
        return intentFilters.toArray(new IntentFilter[intentFilters.size()]);
    }

    private String[][] getTechLists() {
        //noinspection ToArrayCallWithZeroLengthArrayArgument
        return techLists.toArray(new String[0][0]);
    }

}

我的 index.js 文件 nfc.addTagDiscoveredListener(

        function(nfcEvent){
          console.log(nfcEvent.tag.id);
            alert(nfcEvent.tag.id);
            window.echo("readBlock@88");//call to plugin
        },
        function() {
            alert("Listening for NFC tags.");
        },
        function() {
            alert("NFC activation failed.");
        }

    );

SE_NfcA.js(用于交互的插件接口 b/w index.js 和 SE_NfcA.java)

window.echo = function(natureOfTalk)
    {
        alert("Inside JS Interface, arg =" + natureOfTalk);
        cordova.exec(function(result){alert("Result is : "+result);},
                     function(error){alert("Some Error happened : "+ error);},
                     "SE_NfcA","TalkToNFC",[{"type": natureOfTalk}]);
    };

我想我搞砸了 Intents/Activity 生命周期,请帮忙。 TIA!

我找到了一个 tweak/hack 并让它工作。 在进行任何读取或写入调用之前,我进行了一次虚拟初始化调用。

window.echo("Initialize");
window.echo("readBlock@88");//call to plugin to read.

在插件的本机代码中,在收到 "Initialize" 令牌后,我调用了 startNFC()。

 else if(TypeOfTalking.equalsIgnoreCase("Initialize"))
       {
           startNfc();
       }