chariotsolutions / phonegap-nfc

PhoneGap NFC Plugin
MIT License
706 stars 555 forks source link

Writing Ndef tag with sizable payload is not reliable on Android #368

Closed romansoft closed 4 years ago

romansoft commented 4 years ago

When writing a sizable (several hundred bytes) payload to Ndef tag, the phone acknowledges the operation with a callback:

nfc.write(
    record,
    function () {
        window.plugins.toast.showShortTop("Wrote data to device.");
        navigator.notification.beep(1);
        navigator.notification.vibrate(100);
        return true;
    },
    function (reason) {
        window.plugins.toast.showShortTop("There was a problem. Try again.");
        navigator.notification.vibrate(30);
        navigator.notification.beep(1);
        return false;
    });

However, the callback is generated before all data is physically written to the tag, not after, so if the user removes the phone from tag upon the success message, it may not be written completely.

The callback should be changed to happen after all the data is physically written to the tag, so the user does not remove the phone too quickly, corrupting the write operation.

Note, for small payloads, the current scheme works OK since the write latency is comparable to user's response time. This problem only affects larger payloads.

romansoft commented 4 years ago

I made a kludge that delays the notification for a few hundred milliseconds prompting a user to remove the phone (enough to allow the tag write to complete)

nfc.write(
    record,
    function () {
        // add some delay to allow for tag write to complete before the user is notified to remove the phone
        var stop = new Date().getTime();
        while(new Date().getTime() < stop + 350) { // 350 ms
         ;
        }
        window.plugins.toast.showShortTop("Wrote data to device.");
        navigator.notification.beep(1);
        navigator.notification.vibrate(100);
        return true;
    },
    function (reason) {
        window.plugins.toast.showShortTop("There was a problem. Try again.");
        navigator.notification.vibrate(30);
        navigator.notification.beep(1);
        return false;
    });

Unfortunately, there is another beep and vibration upon a tag write from within Android framework which still happens before write full completing. So, it only a partial solution, but better than before.

don commented 4 years ago

I don't have a good fix for this. Closing since it's an old issue.