diff --git a/README.md b/README.md index 1e522466..1ac3792f 100644 --- a/README.md +++ b/README.md @@ -452,7 +452,6 @@ Function `nfc.share` writes an NdefMessage via peer-to-peer. This should appear ### Supported Platforms -- Android - Windows - BlackBerry 7 - BlackBerry 10 @@ -481,7 +480,6 @@ Function `nfc.unshare` stops sharing data via peer-to-peer. ### Supported Platforms -- Android - Windows - BlackBerry 7 - BlackBerry 10 diff --git a/plugin.xml b/plugin.xml index a2d42aa2..d89d1af4 100644 --- a/plugin.xml +++ b/plugin.xml @@ -123,13 +123,13 @@ NDEF - TAG + TAG NDEF - TAG + TAG diff --git a/src/android/src/com/chariotsolutions/nfc/plugin/NfcPlugin.java b/src/android/src/com/chariotsolutions/nfc/plugin/NfcPlugin.java index 3c82776b..01b16056 100644 --- a/src/android/src/com/chariotsolutions/nfc/plugin/NfcPlugin.java +++ b/src/android/src/com/chariotsolutions/nfc/plugin/NfcPlugin.java @@ -32,12 +32,13 @@ import android.nfc.tech.Ndef; import android.nfc.tech.NdefFormatable; import android.nfc.tech.TagTechnology; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Parcelable; import android.util.Log; -public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCompleteCallback { +public class NfcPlugin extends CordovaPlugin { private static final String REGISTER_MIME_TYPE = "registerMimeType"; private static final String REMOVE_MIME_TYPE = "removeMimeType"; private static final String REGISTER_NDEF = "registerNdef"; @@ -48,10 +49,6 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom private static final String WRITE_TAG = "writeTag"; private static final String MAKE_READ_ONLY = "makeReadOnly"; private static final String ERASE_TAG = "eraseTag"; - private static final String SHARE_TAG = "shareTag"; - private static final String UNSHARE_TAG = "unshareTag"; - private static final String HANDOVER = "handover"; // Android Beam - private static final String STOP_HANDOVER = "stopHandover"; private static final String ENABLED = "enabled"; private static final String INIT = "init"; private static final String SHOW_SETTINGS = "showSettings"; @@ -82,15 +79,12 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom private final List intentFilters = new ArrayList<>(); private final ArrayList techLists = new ArrayList<>(); - private NdefMessage p2pMessage = null; private PendingIntent pendingIntent = null; private Intent savedIntent = null; private CallbackContext readerModeCallback; private CallbackContext channelCallback; - private CallbackContext shareTagCallback; - private CallbackContext handoverCallback; private PostponedPluginResult postponedPluginResult = null; @@ -190,18 +184,6 @@ public boolean execute(String action, JSONArray data, CallbackContext callbackCo } else if (action.equalsIgnoreCase(ERASE_TAG)) { eraseTag(callbackContext); - } else if (action.equalsIgnoreCase(SHARE_TAG)) { - shareTag(data, callbackContext); - - } else if (action.equalsIgnoreCase(UNSHARE_TAG)) { - unshareTag(callbackContext); - - } else if (action.equalsIgnoreCase(HANDOVER)) { - handover(data, callbackContext); - - } else if (action.equalsIgnoreCase(STOP_HANDOVER)) { - stopHandover(callbackContext); - } else if (action.equalsIgnoreCase(INIT)) { init(callbackContext); } else if (action.equalsIgnoreCase(ENABLED)) { @@ -323,13 +305,6 @@ private void removeNdef(CallbackContext callbackContext) { callbackContext.success(); } - private void unshareTag(CallbackContext callbackContext) { - p2pMessage = null; - stopNdefPush(); - shareTagCallback = null; - callbackContext.success(); - } - private void init(CallbackContext callbackContext) { Log.d(TAG, "Enabling plugin " + getIntent()); @@ -340,6 +315,59 @@ private void init(CallbackContext callbackContext) { callbackContext.success(); } + private void parseLaunchIntent(final CallbackContext callbackContext) { + final Intent intent = NfcActivity.getLaunchIntent(); + if (intent != null) { + Log.d(TAG, "parseLaunchIntent " + intent); + String action = intent.getAction(); + Log.d(TAG, "action " + action); + final String data = intent.getDataString(); + Log.d(TAG, "data " + data); + + try { + Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); + Parcelable[] messages = intent.getParcelableArrayExtra((NfcAdapter.EXTRA_NDEF_MESSAGES)); + + if (action.equals(NfcAdapter.ACTION_NDEF_DISCOVERED)) { + Ndef ndef = Ndef.get(tag); + callbackContext.success(buildNdefJSON(ndef, messages)); + } else if (action.equals(NfcAdapter.ACTION_TECH_DISCOVERED)) { + Ndef ndef = null; + for (String tagTech : tag.getTechList()) { + Log.d(TAG, tagTech); + if (tagTech.equals(Ndef.class.getName())) { // + ndef = Ndef.get(tag); + } + } + if (ndef != null) { + callbackContext.success(buildNdefJSON(ndef, messages)); + } else { + callbackContext.success(Util.tagToJSON(tag)); + } + } else if (action.equals(NfcAdapter.ACTION_TAG_DISCOVERED)) { + callbackContext.success(Util.tagToJSON(tag)); + } else { + if (data != null) { + callbackContext.success(data); + } else { + callbackContext.error("NO_INTENT"); + } + } + } catch (Exception exception) { + Log.e(TAG, "failed to parse tag from launch intent", exception); + if (data != null) { + // Fallback to returning the URL obtained from the intent + callbackContext.success(data); + } else { + callbackContext.error("NO_INTENT"); + } + } + } else { + Log.d(TAG, "parseLaunchIntent: NO_INTENT"); + callbackContext.error("NO_INTENT"); + } + } + private void removeMimeType(JSONArray data, CallbackContext callbackContext) throws JSONException { String mimeType = data.getString(0); removeIntentFilter(mimeType); @@ -472,35 +500,6 @@ private void makeReadOnly(final CallbackContext callbackContext) { }); } - private void shareTag(JSONArray data, CallbackContext callbackContext) throws JSONException { - NdefRecord[] records = Util.jsonToNdefRecords(data.getString(0)); - this.p2pMessage = new NdefMessage(records); - - startNdefPush(callbackContext); - } - - // setBeamPushUris - // Every Uri you provide must have either scheme 'file' or scheme 'content'. - // Note that this takes priority over setNdefPush - // - // See http://developer.android.com/reference/android/nfc/NfcAdapter.html#setBeamPushUris(android.net.Uri[],%20android.app.Activity) - private void handover(JSONArray data, CallbackContext callbackContext) throws JSONException { - - Uri[] uri = new Uri[data.length()]; - - for (int i = 0; i < data.length(); i++) { - uri[i] = Uri.parse(data.getString(i)); - } - - startNdefBeam(callbackContext, uri); - } - - private void stopHandover(CallbackContext callbackContext) { - stopNdefBeam(); - handoverCallback = null; - callbackContext.success(); - } - private void showSettings(CallbackContext callbackContext) { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) { Intent intent = new Intent(android.provider.Settings.ACTION_NFC_SETTINGS); @@ -517,7 +516,13 @@ private void createPendingIntent() { 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, PendingIntent.FLAG_IMMUTABLE); + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) { + intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); + pendingIntent = PendingIntent.getActivity(activity, 0, intent, PendingIntent.FLAG_MUTABLE); + } else { + intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); + pendingIntent = PendingIntent.getActivity(activity, 0, intent, 0); // PendingIntent.FLAG_IMMUTABLE instead of 0? + } } } @@ -579,10 +584,6 @@ private void startNfc() { if (intentFilters.length > 0 || techLists.length > 0) { nfcAdapter.enableForegroundDispatch(getActivity(), getPendingIntent(), intentFilters, techLists); } - - 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."); @@ -609,77 +610,6 @@ private void stopNfc() { }); } - private void startNdefBeam(final CallbackContext callbackContext, final Uri[] uris) { - getActivity().runOnUiThread(() -> { - - NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(getActivity()); - - if (nfcAdapter == null) { - callbackContext.error(STATUS_NO_NFC); - } else if (!nfcAdapter.isNdefPushEnabled()) { - callbackContext.error(STATUS_NDEF_PUSH_DISABLED); - } else { - nfcAdapter.setOnNdefPushCompleteCallback(NfcPlugin.this, getActivity()); - try { - nfcAdapter.setBeamPushUris(uris, getActivity()); - - PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT); - result.setKeepCallback(true); - handoverCallback = callbackContext; - callbackContext.sendPluginResult(result); - - } catch (IllegalArgumentException e) { - callbackContext.error(e.getMessage()); - } - } - }); - } - - private void startNdefPush(final CallbackContext callbackContext) { - getActivity().runOnUiThread(() -> { - - NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(getActivity()); - - if (nfcAdapter == null) { - callbackContext.error(STATUS_NO_NFC); - } else if (!nfcAdapter.isNdefPushEnabled()) { - callbackContext.error(STATUS_NDEF_PUSH_DISABLED); - } else { - nfcAdapter.setNdefPushMessage(p2pMessage, getActivity()); - nfcAdapter.setOnNdefPushCompleteCallback(NfcPlugin.this, getActivity()); - - PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT); - result.setKeepCallback(true); - shareTagCallback = callbackContext; - callbackContext.sendPluginResult(result); - } - }); - } - - private void stopNdefPush() { - getActivity().runOnUiThread(() -> { - - NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(getActivity()); - - if (nfcAdapter != null) { - nfcAdapter.setNdefPushMessage(null, getActivity()); - } - - }); - } - - private void stopNdefBeam() { - getActivity().runOnUiThread(() -> { - - NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(getActivity()); - - if (nfcAdapter != null) { - nfcAdapter.setBeamPushUris(null, getActivity()); - } - - }); - } - private void addToTechList(String[] techs) { techLists.add(techs); } @@ -874,22 +804,6 @@ private void setIntent(Intent intent) { getActivity().setIntent(intent); } - @Override - public void onNdefPushComplete(NfcEvent event) { - - // handover (beam) take precedence over share tag (ndef push) - if (handoverCallback != null) { - PluginResult result = new PluginResult(PluginResult.Status.OK, "Beamed Message to Peer"); - result.setKeepCallback(true); - handoverCallback.sendPluginResult(result); - } else if (shareTagCallback != null) { - PluginResult result = new PluginResult(PluginResult.Status.OK, "Shared Message with Peer"); - result.setKeepCallback(true); - shareTagCallback.sendPluginResult(result); - } - - } - /** * Enable I/O operations to the tag from this TagTechnology object. * * diff --git a/src/ios/NfcPlugin.m b/src/ios/NfcPlugin.m index 33ade225..80df838f 100644 --- a/src/ios/NfcPlugin.m +++ b/src/ios/NfcPlugin.m @@ -215,13 +215,13 @@ - (void)writeTag:(CDVInvokedUrlCommand*)command API_AVAILABLE(ios(13.0)){ if (self.shouldUseTagReaderSession) { NSLog(@"Using NFCTagReaderSession"); - self.nfcSession = [[NFCTagReaderSession new] + self.nfcSession = [[NFCTagReaderSession alloc] initWithPollingOption:(NFCPollingISO14443 | NFCPollingISO15693) delegate:self queue:dispatch_get_main_queue()]; } else { NSLog(@"Using NFCTagReaderSession"); - self.nfcSession = [[NFCNDEFReaderSession new]initWithDelegate:self queue:nil invalidateAfterFirstRead:FALSE]; + self.nfcSession = [[NFCNDEFReaderSession alloc]initWithDelegate:self queue:nil invalidateAfterFirstRead:FALSE]; } } @@ -400,12 +400,12 @@ - (void)startScanSession:(CDVInvokedUrlCommand*)command { if (self.shouldUseTagReaderSession) { NSLog(@"Using NFCTagReaderSession"); - self.nfcSession = [[NFCTagReaderSession new] + self.nfcSession = [[NFCTagReaderSession alloc] initWithPollingOption:(NFCPollingISO14443 | NFCPollingISO15693) delegate:self queue:dispatch_get_main_queue()]; } else { NSLog(@"Using NFCNDEFReaderSession"); - self.nfcSession = [[NFCNDEFReaderSession new]initWithDelegate:self queue:nil invalidateAfterFirstRead:TRUE]; + self.nfcSession = [[NFCNDEFReaderSession alloc]initWithDelegate:self queue:nil invalidateAfterFirstRead:TRUE]; } sessionCallbackId = [command.callbackId copy]; self.nfcSession.alertMessage = @"Hold near NFC tag to scan."; @@ -413,7 +413,7 @@ - (void)startScanSession:(CDVInvokedUrlCommand*)command { } else if (@available(iOS 11.0, *)) { NSLog(@"iOS < 13, using NFCNDEFReaderSession"); - self.nfcSession = [[NFCNDEFReaderSession new]initWithDelegate:self queue:nil invalidateAfterFirstRead:TRUE]; + self.nfcSession = [[NFCNDEFReaderSession alloc]initWithDelegate:self queue:nil invalidateAfterFirstRead:TRUE]; sessionCallbackId = [command.callbackId copy]; self.nfcSession.alertMessage = @"Hold near NFC tag to scan."; [self.nfcSession beginSession];