Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
48 changes: 17 additions & 31 deletions android/src/main/java/community/revteltech/nfc/HceService.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,11 @@ private void prepareNdefData() {

Log.d(TAG, "Preparing NDEF with " + staticSimpleUrls.size() + " URLs: " + staticSimpleUrls);

List<NdefRecord> allRecords = new ArrayList<>();
for (String url : staticSimpleUrls) {
if (url != null && !url.isEmpty()) {
List<NdefRecord> records = createUriRecords(url);
allRecords.addAll(records);
}
}
// Manual NDEF URI record creation for better cross-device compatibility(had issue with ndefRecord.createUri)
byte[] uriBytes = simpleUrl.getBytes(StandardCharsets.UTF_8);
byte[] payload = new byte[uriBytes.length + 1];
payload[0] = 0x00; // No URI prefix identifier - full URI
System.arraycopy(uriBytes, 0, payload, 1, uriBytes.length);

if (allRecords.isEmpty()) {
Log.d(TAG, "No valid URLs found, clearing NDEF data");
Expand Down Expand Up @@ -186,47 +184,37 @@ public int onStartCommand(Intent intent, int flags, int startId) {
if (vcf != null && !vcf.isEmpty()) {
contactVcf = vcf;
staticContactVcf = vcf;
staticSimpleUrls.clear();
isServiceActive = true; // Activate service when setting content
simpleUrl = null;
staticSimpleUrl = null;
prepareNdefData();
} else {fear:
} else {
// Explicit clear VCF
Log.d(TAG, "Clearing VCF content");
contactVcf = null;
staticContactVcf = null;
currentNdefData = null;
// Don't deactivate if URL content might still exist
if (staticSimpleUrls.isEmpty()) {
isServiceActive = false;
}
}
} else if (hasUrlExtra) {
if (url != null && !url.isEmpty()) {
// Add URL to the list (accumulate)
if (!staticSimpleUrls.contains(url)) {
staticSimpleUrls.add(url);
}
simpleUrl = url;
staticSimpleUrl = url;
contactVcf = null;
staticContactVcf = null;
isServiceActive = true; // Activate service when setting content
prepareNdefData();
Log.d(TAG, "Added URL to collection. Total URLs: " + staticSimpleUrls.size());
} else {
// Explicit clear URLs
// Explicit clear URL
Log.d(TAG, "Clearing URL content");
staticSimpleUrls.clear();
simpleUrl = null;
staticSimpleUrl = null;
currentNdefData = null;
// Don't deactivate if VCF content might still exist
if (staticContactVcf == null) {
isServiceActive = false;
}
}
} else if (hasUrlExtra && hasVcfExtra && url == null && vcf == null) {
// Both are explicitly null - clear all content and deactivate
Log.d(TAG, "Clearing all content and deactivating service");
contactVcf = null;
staticContactVcf = null;
staticSimpleUrls.clear();
simpleUrl = null;
staticSimpleUrl = null;
currentNdefData = null;
isServiceActive = false;
}
Expand All @@ -244,11 +232,9 @@ public byte[] processCommandApdu(byte[] commandApdu, Bundle extras) {
Log.d(TAG, "Processing APDU: " + ApduUtil.bytesToHex(commandApdu));

// Check if HCE is actually active and has content
if (!isServiceActive || (staticSimpleUrls.isEmpty() && staticContactVcf == null)) {
if (!isServiceActive || (staticSimpleUrl == null && staticContactVcf == null)) {
Log.d(TAG, "HCE service inactive or no content, rejecting all commands");
byte[] response = ApduUtil.A_FILE_NOT_FOUND;
Log.d(TAG, "Response APDU: " + ApduUtil.bytesToHex(response));
return response;
return ApduUtil.A_FILE_NOT_FOUND;
}

// Handle SELECT NDEF application
Expand Down
19 changes: 11 additions & 8 deletions android/src/main/java/community/revteltech/nfc/NfcManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -1536,12 +1536,10 @@ public void stopHCE(Callback callback) {
serviceIntent.putExtra(HceService.EXTRA_CONTACT_VCF, (String) null);
context.startService(serviceIntent);

// Re-enable NFC reading after a delay to avoid immediate interference
// Re-enable NFC reading if it was previously enabled
if (isForegroundEnabled && isResumed) {
new android.os.Handler(android.os.Looper.getMainLooper()).postDelayed(() -> {
Log.d(LOG_TAG, "Auto re-enabling NFC reading after HCE stop");
enableDisableForegroundDispatch(true);
}, 3000); // 3 second delay to ensure devices are separated
Log.d(LOG_TAG, "Re-enabling NFC reading after HCE stop");
enableDisableForegroundDispatch(true);
}

Log.d(LOG_TAG, "HCE Service content cleared and deactivated");
Expand All @@ -1563,7 +1561,7 @@ public void setSimpleUrl(String url, Callback callback) {

// Disable NFC reading to prevent interference when sharing via HCE
if (isForegroundEnabled) {
Log.d(LOG_TAG, "Temporarily disabling NFC reading for HCE sharing");
Log.d(LOG_TAG, "Temporarily disabling NFC reading for HCE URL sharing");
enableDisableForegroundDispatch(false);
}

Expand Down Expand Up @@ -1592,7 +1590,13 @@ public void clearContent(Callback callback) {
serviceIntent.putExtra(HceService.EXTRA_CONTACT_VCF, (String) null);
context.startService(serviceIntent);

Log.d(LOG_TAG, "HCE content cleared (all URLs and VCF)");
// Re-enable NFC reading if it was previously enabled
if (isForegroundEnabled && isResumed) {
Log.d(LOG_TAG, "Re-enabling NFC reading after clearing content");
enableDisableForegroundDispatch(true);
}

Log.d(LOG_TAG, "HCE content cleared");
callback.invoke(null, true);
} catch (Exception e) {
Log.e(LOG_TAG, "Error clearing content: " + e.getMessage(), e);
Expand All @@ -1610,7 +1614,6 @@ public void setVCard(String vcf, Callback callback) {

// Disable NFC reading to prevent interference when sharing via HCE
if (isForegroundEnabled) {
Log.d(LOG_TAG, "Temporarily disabling NFC reading for HCE sharing");
enableDisableForegroundDispatch(false);
}

Expand Down