Skip to content

Commit

Permalink
Merge pull request #2 from InfosoftSystems/develop
Browse files Browse the repository at this point in the history
fix: launch app with NFC when in background
  • Loading branch information
dwettstein authored Jul 30, 2024
2 parents 1e741fb + 382f37f commit 6bcde10
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 35 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "phonegap-nfc",
"version": "1.2.0",
"version": "1.2.1",
"description": "Near Field Communication (NFC) Plugin. Read and write NDEF messages to NFC tags and share NDEF messages with peers.",
"cordova": {
"id": "phonegap-nfc",
Expand Down Expand Up @@ -33,4 +33,4 @@
"url": "https://github.com/chariotsolutions/phonegap-nfc/issues"
},
"homepage": "https://github.com/chariotsolutions/phonegap-nfc#readme"
}
}
88 changes: 58 additions & 30 deletions src/android/src/com/chariotsolutions/nfc/plugin/NfcPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

Expand Down Expand Up @@ -33,6 +34,7 @@
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;

Expand All @@ -50,7 +52,6 @@ public class NfcPlugin extends CordovaPlugin {
private static final String ENABLED = "enabled";
private static final String INIT = "init";
private static final String SHOW_SETTINGS = "showSettings";
private static final String PARSE_LAUNCH_INTENT = "parseLaunchIntent";

private static final String NDEF = "ndef";
private static final String NDEF_MIME = "ndef-mime";
Expand Down Expand Up @@ -85,10 +86,27 @@ public class NfcPlugin extends CordovaPlugin {
private CallbackContext readerModeCallback;
private CallbackContext channelCallback;

private PostponedPluginResult postponedPluginResult = null;

class PostponedPluginResult {
private Date moment;
private PluginResult pluginResult;

PostponedPluginResult(Date moment, PluginResult pluginResult) {
this.moment = moment;
this.pluginResult = pluginResult;
}

boolean isValid() {
return this.moment.after(new Date(new Date().getTime() - 30000));
}
}

@Override
public boolean execute(String action, JSONArray data, CallbackContext callbackContext) throws JSONException {

Log.d(TAG, "execute " + action);
// Log.d(TAG, "execute postponedPluginResult.toString() " + postponedPluginResult.toString());

// showSettings can be called if NFC is disabled
// might want to skip this if NO_NFC
Expand All @@ -98,8 +116,24 @@ public boolean execute(String action, JSONArray data, CallbackContext callbackCo
}

// the channel is set up when the plugin starts
if (action.equalsIgnoreCase(CHANNEL)) {
// if (action.equalsIgnoreCase(CHANNEL)) {
if (action.equalsIgnoreCase(READER_MODE)) {
channelCallback = callbackContext;

if (postponedPluginResult != null) {
Log.i(TAG, "Postponed plugin result available");

if (postponedPluginResult.isValid()) {
Log.i(TAG, "Postponed plugin result is valid, resending it now");

channelCallback.sendPluginResult(postponedPluginResult.pluginResult);
} else {
Log.i(TAG, "Postponed plugin result not valid anymore, so ignoring it");
}

postponedPluginResult = null;
}

return true; // short circuit
}

Expand Down Expand Up @@ -152,10 +186,6 @@ public boolean execute(String action, JSONArray data, CallbackContext callbackCo

} else if (action.equalsIgnoreCase(INIT)) {
init(callbackContext);

} else if (action.equalsIgnoreCase(PARSE_LAUNCH_INTENT)) {
parseLaunchIntent(callbackContext);

} else if (action.equalsIgnoreCase(ENABLED)) {
// status is checked before every call
// if code made it here, NFC is enabled
Expand Down Expand Up @@ -183,12 +213,6 @@ public boolean execute(String action, JSONArray data, CallbackContext callbackCo
return true;
}

@Override
protected void pluginInitialize() {
super.pluginInitialize();
NfcActivity.onPluginInitialize();
}

private String getNfcStatus() {
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(getActivity());
if (nfcAdapter == null) {
Expand Down Expand Up @@ -233,12 +257,11 @@ public void onTagDiscovered(Tag tag) {
Ndef ndef = Ndef.get(tag);
json = Util.ndefToJSON(ndef);
} else {
json = Util.tagToJSON(tag);
json = Util.tagToJSON(tag, null);
}

Intent tagIntent = new Intent();
tagIntent.putExtra(NfcAdapter.EXTRA_TAG, tag);
savedIntent = tagIntent;
setIntent(tagIntent);

PluginResult result = new PluginResult(PluginResult.Status.OK, json);
Expand Down Expand Up @@ -319,10 +342,10 @@ private void parseLaunchIntent(final CallbackContext callbackContext) {
if (ndef != null) {
callbackContext.success(buildNdefJSON(ndef, messages));
} else {
callbackContext.success(Util.tagToJSON(tag));
callbackContext.success(Util.tagToJSON(tag, messages));
}
} else if (action.equals(NfcAdapter.ACTION_TAG_DISCOVERED)) {
callbackContext.success(Util.tagToJSON(tag));
callbackContext.success(Util.tagToJSON(tag, messages));
} else {
if (data != null) {
callbackContext.success(data);
Expand Down Expand Up @@ -368,7 +391,7 @@ private void registerMimeType(JSONArray data, CallbackContext callbackContext) t
private void eraseTag(CallbackContext callbackContext) {
Tag tag = savedIntent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
NdefRecord[] records = {
new NdefRecord(NdefRecord.TNF_EMPTY, new byte[0], new byte[0], new byte[0])
new NdefRecord(NdefRecord.TNF_EMPTY, new byte[0], new byte[0], new byte[0])
};
writeNdefMessage(new NdefMessage(records), tag, callbackContext);
}
Expand All @@ -394,7 +417,7 @@ private void writeNdefMessage(final NdefMessage message, final Tag tag, final Ca
int size = message.toByteArray().length;
if (ndef.getMaxSize() < size) {
callbackContext.error("Tag capacity is " + ndef.getMaxSize() +
" bytes, message is " + size + " bytes.");
" bytes, message is " + size + " bytes.");
} else {
ndef.writeNdefMessage(message);
callbackContext.success();
Expand Down Expand Up @@ -661,7 +684,7 @@ private void parseMessage() {
}

if (action.equals(NfcAdapter.ACTION_TAG_DISCOVERED)) {
fireTagEvent(tag);
fireTagEvent(tag, messages);
}

setIntent(new Intent());
Expand All @@ -673,12 +696,17 @@ private void sendEvent(String type, JSONObject tag) {

try {
JSONObject event = new JSONObject();
event.put("type", type); // TAG_DEFAULT, NDEF, NDEF_MIME, NDEF_FORMATABLE
event.put("tag", tag); // JSON representing the NFC tag and NDEF messages
event.put("type", type); // TAG_DEFAULT, NDEF, NDEF_MIME, NDEF_FORMATABLE
event.put("tag", tag); // JSON representing the NFC tag and NDEF messages

PluginResult result = new PluginResult(PluginResult.Status.OK, event);
result.setKeepCallback(true);
channelCallback.sendPluginResult(result);

if (channelCallback != null) {
channelCallback.sendPluginResult(result);
} else {
postponedPluginResult = new PostponedPluginResult(new Date(), result);
}
} catch (JSONException e) {
Log.e(TAG, "Error sending NFC event through the channel", e);
}
Expand All @@ -691,11 +719,11 @@ private void fireNdefEvent(String type, Ndef ndef, Parcelable[] messages) {
}

private void fireNdefFormatableEvent(Tag tag) {
sendEvent(NDEF_FORMATABLE, Util.tagToJSON(tag));
sendEvent(NDEF_FORMATABLE, Util.tagToJSON(tag, null));
}

private void fireTagEvent(Tag tag) {
sendEvent(TAG_DEFAULT, Util.tagToJSON(tag));
private void fireTagEvent(Tag tag, Parcelable[] messages) {
sendEvent(TAG_DEFAULT, Util.tagToJSON(tag, messages));
}

private JSONObject buildNdefJSON(Ndef ndef, Parcelable[] messages) {
Expand Down Expand Up @@ -780,8 +808,8 @@ private void setIntent(Intent intent) {
* Enable I/O operations to the tag from this TagTechnology object.
* *
*
* @param tech TagTechnology class name e.g. 'android.nfc.tech.IsoDep' or 'android.nfc.tech.NfcV'
* @param timeout tag timeout
* @param tech TagTechnology class name e.g. 'android.nfc.tech.IsoDep' or 'android.nfc.tech.NfcV'
* @param timeout tag timeout
* @param callbackContext Cordova callback context
*/
private void connect(final String tech, final int timeout, final CallbackContext callbackContext) {
Expand Down Expand Up @@ -813,9 +841,9 @@ private void connect(final String tech, final int timeout, final CallbackContext
try {
Method maxTransceiveLengthMethod = tagTechnologyClass.getMethod("getMaxTransceiveLength");
resultObject.put("maxTransceiveLength", maxTransceiveLengthMethod.invoke(tagTechnology));
} catch(NoSuchMethodException e) {
} catch (NoSuchMethodException e) {
// Some technologies do not support this, so just ignore.
} catch(JSONException e) {
} catch (JSONException e) {
Log.e(TAG, "Error serializing JSON", e);
}
}
Expand Down Expand Up @@ -895,7 +923,7 @@ private void close(CallbackContext callbackContext) {
/**
* Send raw commands to the tag and receive the response.
*
* @param data byte[] command to be passed to the tag
* @param data byte[] command to be passed to the tag
* @param callbackContext Cordova callback context
*/
private void transceive(final byte[] data, final CallbackContext callbackContext) {
Expand Down
11 changes: 8 additions & 3 deletions src/android/src/com/chariotsolutions/nfc/plugin/Util.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.chariotsolutions.nfc.plugin;

import android.os.Parcelable;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.Tag;
Expand Down Expand Up @@ -38,9 +39,9 @@ static JSONObject ndefToJSON(Ndef ndef) {
// mTag.getTagService(); of the Ndef object sometimes returns null
// see http://issues.mroland.at/index.php?do=details&task_id=47
try {
json.put("canMakeReadOnly", ndef.canMakeReadOnly());
json.put("canMakeReadOnly", ndef.canMakeReadOnly());
} catch (NullPointerException e) {
json.put("canMakeReadOnly", JSONObject.NULL);
json.put("canMakeReadOnly", JSONObject.NULL);
}
} catch (JSONException e) {
Log.e(TAG, "Failed to convert ndef into json: " + ndef.toString(), e);
Expand All @@ -49,13 +50,17 @@ static JSONObject ndefToJSON(Ndef ndef) {
return json;
}

static JSONObject tagToJSON(Tag tag) {
static JSONObject tagToJSON(Tag tag, Parcelable[] messages) {
JSONObject json = new JSONObject();

if (tag != null) {
try {
json.put("id", byteArrayToJSON(tag.getId()));
json.put("techTypes", new JSONArray(Arrays.asList(tag.getTechList())));

if (messages != null && messages.length > 0) {
json.put("ndefMessage", messageToJSON((NdefMessage)messages[0]));
}
} catch (JSONException e) {
Log.e(TAG, "Failed to convert tag into json: " + tag.toString(), e);
}
Expand Down

0 comments on commit 6bcde10

Please sign in to comment.