Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/remove android beam #508

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 0 additions & 54 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,6 @@ Writing NFC tags on iOS uses the same [nfc.write](#nfcwrite) function as other p
- [nfc.share](#nfcshare)
- [nfc.unshare](#nfcunshare)
- [nfc.erase](#nfcerase)
- [nfc.handover](#nfchandover)
- [nfc.stopHandover](#nfcstophandover)
- [nfc.enabled](#nfcenabled)
- [nfc.showSettings](#nfcshowsettings)
- [~~nfc.beginSession~~](#nfcbeginsession)
Expand Down Expand Up @@ -452,7 +450,6 @@ Function `nfc.share` writes an NdefMessage via peer-to-peer. This should appear

### Supported Platforms

- Android
- Windows
- BlackBerry 7
- BlackBerry 10
Expand Down Expand Up @@ -481,7 +478,6 @@ Function `nfc.unshare` stops sharing data via peer-to-peer.

### Supported Platforms

- Android
- Windows
- BlackBerry 7
- BlackBerry 10
Expand All @@ -508,56 +504,6 @@ This method *must* be called from within an NDEF Event Handler.
- Android
- BlackBerry 7

## nfc.handover

Send a file to another device via NFC handover.

var uri = "content://media/external/audio/media/175";
nfc.handover(uri, [onSuccess], [onFailure]);


var uris = [
"content://media/external/audio/media/175",
"content://media/external/audio/media/176",
"content://media/external/audio/media/348"
];
nfc.handover(uris, [onSuccess], [onFailure]);


### Parameters

- __uri__: A URI as a String, or an *array* of URIs.
- __onSuccess__: (Optional) The callback that is called when the message is pushed.
- __onFailure__: (Optional) The callback that is called if there was an error.

### Description

Function `nfc.handover` shares files to a NFC peer using handover. Files are sent by specifying a file:// or context:// URI or a list of URIs. The file transfer is initiated with NFC but the transfer is completed with over Bluetooth or WiFi which is handled by a NFC handover request. The Android code is responsible for building the handover NFC Message.

This is Android only, but it should be possible to add implementations for other platforms.

### Supported Platforms

- Android

## nfc.stopHandover

Stop sharing NDEF data via NFC handover.

nfc.stopHandover([onSuccess], [onFailure]);

### Parameters

- __onSuccess__: (Optional) The callback that is called when sharing stops.
- __onFailure__: (Optional) The callback that is called if there was an error.

### Description

Function `nfc.stopHandover` stops sharing data via peer-to-peer.

### Supported Platforms

- Android

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please delete one more line here.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to add this empty build.gradle?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this empty build.gradle

## nfc.showSettings

Expand Down
Empty file added build.gradle
Empty file.
150 changes: 1 addition & 149 deletions src/android/src/com/chariotsolutions/nfc/plugin/NfcPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,10 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter.MalformedMimeTypeException;
import android.net.Uri;
import android.nfc.FormatException;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.NfcEvent;
import android.nfc.Tag;
import android.nfc.TagLostException;
import android.nfc.tech.Ndef;
Expand All @@ -35,7 +33,7 @@
import android.os.Parcelable;
import android.util.Log;

public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCompleteCallback {
public class NfcPlugin extends CordovaPlugin {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, any info on why removing this implements NfcAdapter.OnNdefPushCompleteCallback can be done, or is necessary, or else?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing implements NfcAdapter.OnNdefPushCompleteCallback corresponds with Android Beam's phase-out in API 29 and its complete removal in API 34 for Android 14. This update keeps our plugin aligned with the latest Android standards and free from deprecated code.

Copy link
Author

@souleymane-diallo souleymane-diallo Jul 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This interface implements NfcAdapter.OnNdefPushCompleteCallback https://developer.android.com/reference/android/nfc/NfcAdapter.OnNdefPushCompleteCallback which includes the method @Override public void onNdefPushComplete(NfcEvent event). If we remove this interface, we must also remove the associated @Override. Since our goal is related to Android Beam, which is no longer supported, we no longer need to implement this interface or the @Override.

private static final String REGISTER_MIME_TYPE = "registerMimeType";
private static final String REMOVE_MIME_TYPE = "removeMimeType";
private static final String REGISTER_NDEF = "registerNdef";
Expand All @@ -46,10 +44,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";
Expand All @@ -74,21 +68,17 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
private static final String STATUS_NFC_OK = "NFC_OK";
private static final String STATUS_NO_NFC = "NO_NFC";
private static final String STATUS_NFC_DISABLED = "NFC_DISABLED";
private static final String STATUS_NDEF_PUSH_DISABLED = "NDEF_PUSH_DISABLED";

private static final String TAG = "NfcPlugin";
private final List<IntentFilter> intentFilters = new ArrayList<>();
private final ArrayList<String[]> 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;

@Override
public boolean execute(String action, JSONArray data, CallbackContext callbackContext) throws JSONException {
Expand Down Expand Up @@ -155,18 +145,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);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK to remove handover/stopHandover because directly related to Beam, as visible in the code here.
But why removing share/unshare? It seems to be related to "NdefPush"/"Push" ; is that part of Android Beam too?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The removal of shareTag and unshareTag actions is due to their dependence on the NDEF push feature, which is primarily facilitated through Android Beam. Since Android Beam and related functionalities have been deprecated and removed in newer Android APIs, maintaining these actions would lead to future compatibility issues and potential security risks. This ensures our plugin stays updated with supported Android NFC capabilities.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Android Beam https://developer.android.com/develop/connectivity/nfc/nfc#p2p a feature that utilized NFC for file sharing, is no longer supporte. Although it still exists in the SDK, it is not functional; the code does not compile and links to the documentation are non-existent.
Development guides once referred to "Beam file," https://developer.android.com/training/beam-files but this documentation has been removed and redirects to 'file sharing'. Specific links to Android Beam https://developer.android.com/reference/android/nfc/NfcAdapter as well as any dedicated documentation and its specific methods are no longer available.


} else if (action.equalsIgnoreCase(HANDOVER)) {
handover(data, callbackContext);

} else if (action.equalsIgnoreCase(STOP_HANDOVER)) {
stopHandover(callbackContext);

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

Expand Down Expand Up @@ -289,13 +267,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());

Expand Down Expand Up @@ -438,35 +409,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);
Expand Down Expand Up @@ -546,9 +488,6 @@ private void startNfc() {
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.");
Expand All @@ -575,77 +514,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);
}
Expand Down Expand Up @@ -835,22 +703,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.
* *
Expand Down
12 changes: 0 additions & 12 deletions www/phonegap-nfc.js
Original file line number Diff line number Diff line change
Expand Up @@ -461,18 +461,6 @@ var nfc = {
cordova.exec(win, fail, "NfcPlugin", "unshareTag", []);
},

handover: function (uris, win, fail) {
// if we get a single URI, wrap it in an array
if (!Array.isArray(uris)) {
uris = [ uris ];
}
cordova.exec(win, fail, "NfcPlugin", "handover", uris);
},

stopHandover: function (win, fail) {
cordova.exec(win, fail, "NfcPlugin", "stopHandover", []);
},

erase: function (win, fail) {
cordova.exec(win, fail, "NfcPlugin", "eraseTag", [[]]);
},
Expand Down