Skip to content

Latest commit

 

History

History
673 lines (412 loc) · 22.8 KB

README.md

File metadata and controls

673 lines (412 loc) · 22.8 KB

IoTize PhoneGap NFC iPhone XR / XS support

This is a fork from PhoneGap NFC Plugin 1.0.3

Ionic support

You can use this plugin with the ionic-native NFC provider:

npm i @ionic-native/nfc

Note: the iOS method beginNDEFSession is not referenced in @ionic-native/nfc. In order to call this method within an Ionic project, you need to declare it within your typescript file:

declare var nfc: Any;

nfc.beginNDEFSession(success, failure);

IoTize NFC Com Protocol

The current plugin comes with a protocol that allows to use NFC ISO15693 compatible devices to communicate with IoTize products.

see Communication protocol for more informations

Edit AndroidManifest using config.xml

Using cordova config-file node, you may edit AndroidManifest.xml file when adding the android platform. Copy the following snippet and add it inside the <platform name="android"> node of your project's config.xml file:

<config-file parent="/manifest/application/activity[@android:name='MainActivity']" target="app/src/main/AndroidManifest.xml" xmlns:android="http://schemas.android.com/apk/res/android">
    <intent-filter>
        <action android:name="android.nfc.action.NDEF_DISCOVERED" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="application/YOUR_APPLICATION_PACKAGE" />
    </intent-filter>
</config-file>

Replace YOUR_APPLICATION_PACKAGE according to your application and IoTize tap configuration.

IoTize Cordova NFC Plugin

The NFC plugin allows you to read and communicate with IoTize NFC Taps.

This plugin uses NDEF (NFC Data Exchange Format) and ISO15693 custom commands

Supported Platforms

Contents

Installing

Cordova

$ cordova plugin add @iotize/device-com-nfc.cordova

iOS Notes

Reading NFC NDEF tags is supported on iPhone 7 and iPhone 7 Plus running iOS 11. To enable your app to detect NFC tags, the plugin adds the Near Field Communication Tag Reading capability in your Xcode project. You must build your application with XCode 9+. See the Apple Documentation for more info.

Use nfc.addNdefListener to read NDEF NFC tags with iOS. Unfortunately, iOS also requires you to begin a session before scanning NFC tag. The JavaScript API contains two iOS specific function nfc.beginNDEFSession and nfc.invalidateNDEFSession

You must call nfc.beginNDEFSession before every scan.

iOS 13 Beta

With iOS 13, Apple opened its NFC API and allowed communication with ISO15693 tags.

Use nfc.connect to begin a NFC communication session in your iOS app. you may then use the nfc.transceive method to exchange, and then close the session with nfc.close

NFC

The nfc object provides access to the device's NFC sensor.

Methods

Tag Technology Functions

nfc.addNdefListener

Registers an event listener for any NDEF tag.

nfc.addNdefListener(callback, [onSuccess], [onFailure]);

Parameters

  • callback: The callback that is called when an NDEF tag is read.
  • onSuccess: (Optional) The callback that is called when the listener is added.
  • onFailure: (Optional) The callback that is called if there was an error.

Description

Function nfc.addNdefListener registers the callback for ndef events.

A ndef event is fired when a NDEF tag is read.

For BlackBerry 10, you must configure the type of tags your application will read with an invoke-target in config.xml.

On Android registered mimeTypeListeners takes precedence over this more generic NDEF listener.

On iOS you must call beginNDEFSession before scanning a NDEF tag.

Supported Platforms

  • Android
  • iOS

nfc.removeNdefListener

Removes the previously registered event listener for NDEF tags added via nfc.addNdefListener.

nfc.removeNdefListener(callback, [onSuccess], [onFailure]);

Removing listeners is not recommended. Instead, consider that your callback can ignore messages you no longer need.

Parameters

  • callback: The previously registered callback.
  • onSuccess: (Optional) The callback that is called when the listener is successfully removed.
  • onFailure: (Optional) The callback that is called if there was an error during removal.

Supported Platforms

  • Android
  • iOS

nfc.addTapDeviceListener

Registers an event listener for NFC tap

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

Related preference:

  • boolean EnableEncryptionWithNFC true to enable encryption when connecting to a new Tap.
  • boolean EnableNFCPairing true to enable NFC pairing when connecting to a new Tap
  • boolean EnableNFCTapDeviceDiscovery true to enable NFC Tap discovery in the native part of the plugin.
  • string NFCTapDeviceMimeType app mime type. Eg: application/com.iotize.apps.tapmanager
  • string NFCParingDoneToastMessage toast messsage displayed when NFC pairing has been done. Give an empty string to disable this message.

Supported Platforms

  • Android

nfc.addMimeTypeListener

Registers an event listener for NDEF tags matching a specified MIME type.

nfc.addMimeTypeListener(mimeType, callback, [onSuccess], [onFailure]);

Parameters

  • mimeType: The MIME type to filter for messages.
  • callback: The callback that is called when an NDEF tag matching the MIME type is read.
  • onSuccess: (Optional) The callback that is called when the listener is added.
  • onFailure: (Optional) The callback that is called if there was an error.

Description

Function nfc.addMimeTypeListener registers the callback for ndef-mime events.

A ndef-mime event occurs when a Ndef.TNF_MIME_MEDIA tag is read and matches the specified MIME type.

This function can be called multiple times to register different MIME types. You should use the same handler for all MIME messages.

nfc.addMimeTypeListener("text/json", *onNfc*, success, failure);
nfc.addMimeTypeListener("text/demo", *onNfc*, success, failure);

On Android, MIME types for filtering should always be lower case. (See IntentFilter.addDataType())

Supported Platforms

  • Android

nfc.removeMimeTypeListener

Removes the previously registered event listener added via nfc.addMimeTypeListener.

nfc.removeMimeTypeListener(mimeType, callback, [onSuccess], [onFailure]);

Removing listeners is not recommended. Instead, consider that your callback can ignore messages you no longer need.

Parameters

  • mimeType: The MIME type to filter for messages.
  • callback: The previously registered callback.
  • onSuccess: (Optional) The callback that is called when the listener is successfully removed.
  • onFailure: (Optional) The callback that is called if there was an error during removal.

Supported Platforms

  • Android

nfc.showSettings

Show the NFC settings on the device.

nfc.showSettings(success, failure);

Description

Function showSettings opens the NFC settings for the operating system.

Parameters

  • success: Success callback function [optional]
  • failure: Error callback function, invoked when error occurs. [optional]

Quick Example

nfc.showSettings();

Supported Platforms

  • Android

nfc.enabled

Check if NFC is available and enabled on this device.

nfc.enabled(onSuccess, onFailure);

Parameters

  • onSuccess: The callback that is called when NFC is enabled.
  • onFailure: The callback that is called when NFC is disabled or missing.

Description

Function nfc.enabled explicitly checks to see if the phone has NFC and if NFC is enabled. If everything is OK, the success callback is called. If there is a problem, the failure callback will be called with a reason code.

The reason will be NO_NFC if the device doesn't support NFC and NFC_DISABLED if the user has disabled NFC.

Note: that on Android the NFC status is checked before every API call NO_NFC or NFC_DISABLED can be returned in any failure function.

Supported Platforms

  • Android
  • iOS

nfc.beginNDEFSession

iOS requires you to begin a session before scanning a NFC tag.

nfc.beginNDEFSession(success, failure);

Description

Function beginNDEFSession starts the NFCNDEFReaderSession allowing iOS to scan NFC tags.

If the session is closed by the user, it will trigger the Error callback (if it exists)

Parameters

  • success: Success callback function called when the session begins [optional]
  • failure: Error callback function, invoked when error occurs. [optional]

Quick Example

nfc.beginNDEFSession();

Supported Platforms

  • iOS

nfc.invalidateSession

Invalidate the NFC NDEF session.

nfc.invalidateSession(success, failure);

Description

Function invalidateSession stops the NFCNDEFReaderSession returning control to your app.

Parameters

  • success: Success callback function called when the session in invalidated [optional]
  • failure: Error callback function, invoked when error occurs. [optional]

Quick Example

nfc.invalidateSession();

Supported Platforms

  • iOS

Tag Technology Functions

This plugin is built to communicate with IoTize tags. See the original plugin if you need a more complete use of the NFC

PhoneGap NFC Plugin 1.0.3

nfc.connect

Connect to the tag and enable I/O operations to the tag from this TagTechnology object.

//Android
nfc.connect(tech);

nfc.connect(tech, timeout);

//iOS
nfc.connect()

Description

Function connect enables I/O operations to the tag from this TagTechnology object. nfc.connect should be called after receiving a nfcEvent from the addNdefListener. Only one TagTechnology object can be connected to a Tag at a time.

See Android's TagTechnology.connect() for more info.

On iOS, connect starts a NFC Session, and is resolved when the device is connected to a Tag.

Parameters (Android only)

  • tech: The tag technology e.g. android.nfc.tech.IsoDep
  • timeout: The transceive(byte[]) timeout in milliseconds [optional]

Returns

  • Promise when the connection is successful

Quick Example

nfc.addTagDiscoveredListener(function(nfcEvent) {
    nfc.connect('android.nfc.tech.IsoDep', 500).then(
        () => console.log('connected to', nfc.bytesToHexString(nfcEvent.tag.id)),
        (error) => console.log('connection failed', error)
    );
})

Supported Platforms

  • Android
  • iOS 13 (beta)

nfc.transceive

Send raw command to the tag and receive the response.

nfc.transceive(data);

Description

Function transceive sends raw commands to the tag and receives the response. nfc.connect must be called before calling transceive. Data passed to transceive can be a hex string representation of bytes or an ArrayBuffer. The response is returned as an ArrayBuffer in the promise.

See Android's documentation IsoDep.transceive(), NfcV.transceive(), MifareUltralight.transceive() for more info.

Parameters

  • data: a string of hex data or an ArrayBuffer

Returns

  • Promise with the response data as an ArrayBuffer

Quick Example

// Promise style
nfc.transceive('90 5A 00 00 03 AA AA AA 00').then(
    response => console.log(util.arrayBufferToString(response)),
    error => console.log('Error selecting DESFire application')
)

// async await
const response = await nfc.transceive('90 5A 00 00 03 AA AA AA 00');
console.log('response =',util.arrayBufferToString(response));

Supported Platforms

  • Android
  • iOS 13 (beta)

nfc.close

Close TagTechnology connection.

nfc.close();

Description

Function close disabled I/O operations to the tag from this TagTechnology object, and releases resources.

See Android's TagTechnology.close() for more info.

Parameters

  • none

Returns

  • Promise when the connection is successfully closed

Quick Example

nfc.transceive().then(
    () => console.log('connection closed'),
    (error) => console.log('error closing connection', error);
)

Supported Platforms

  • Android
  • iOS 13 (beta)

NDEF

The ndef object provides NDEF constants, functions for creating NdefRecords, and functions for converting data. See android.nfc.NdefRecord for documentation about constants

NdefMessage

Represents an NDEF (NFC Data Exchange Format) data message that contains one or more NdefRecords. This plugin uses an array of NdefRecords to represent an NdefMessage.

NdefRecord

Represents a logical (unchunked) NDEF (NFC Data Exchange Format) record.

Properties

  • tnf: 3-bit TNF (Type Name Format) - use one of the TNF_* constants
  • type: byte array, containing zero to 255 bytes, must not be null
  • id: byte array, containing zero to 255 bytes, must not be null
  • payload: byte array, containing zero to (2 ** 32 - 1) bytes, must not be null

The ndef object has a function for creating NdefRecords

var type = "text/pg",
    id = [],
    payload = nfc.stringToBytes("Hello World"),
    record = ndef.record(ndef.TNF_MIME_MEDIA, type, id, payload);

There are also helper functions for some types of records

Create a URI record

var record = ndef.uriRecord("http://chariotsolutions.com");

Create a plain text record

var record = ndef.textRecord("Plain text message");

Create a mime type record

var mimeType = "text/pg",
    payload = "Hello Phongap",
    record = ndef.mimeMediaRecord(mimeType, nfc.stringToBytes(payload));

Create an Empty record

var record = ndef.emptyRecord();

Create an Android Application Record (AAR)

var record = ndef.androidApplicationRecord('com.example');

See ndef.record, ndef.textRecord, ndef.mimeMediaRecord, and ndef.uriRecord.

The Ndef object has functions to convert some data types to and from byte arrays.

See the phonegap-nfc.js source for more documentation.

Events

Events are fired when NFC tags are read. Listeners are added by registering callback functions with the nfc object. For example nfc.addNdefListener(myNfcListener, win, fail);

NfcEvent

Properties

  • type: event type
  • tag: Ndef tag

Types

  • ndef-mime
  • ndef

The tag contents are platform dependent.

id and techTypes may be included when scanning a tag on Android.

Assuming the following NDEF message is written to a tag, it will produce the following events when read.

var ndefMessage = [
    ndef.createMimeRecord('text/pg', 'Hello PhoneGap')
];

Sample Event on Android

{
    type: 'ndef',
    tag: {
        "isWritable": true,
        "id": [4, 96, 117, 74, -17, 34, -128],
        "techTypes": ["android.nfc.tech.IsoDep", "android.nfc.tech.NfcA", "android.nfc.tech.Ndef"],
        "type": "NFC Forum Type 4",
        "canMakeReadOnly": false,
        "maxSize": 2046,
        "ndefMessage": [{
            "id": [],
            "type": [116, 101, 120, 116, 47, 112, 103],
            "payload": [72, 101, 108, 108, 111, 32, 80, 104, 111, 110, 101, 71, 97, 112],
            "tnf": 2
        }]
    }
}

Sample Event on iOS

{
    type: 'ndef',
    tag: {
        "ndefMessage": [{
            "tnf": 2,
            "type": [116, 101, 120, 116, 47, 112, 103],
            "id": [],
            "payload": [72, 101, 108, 108, 111, 32, 80, 104, 111, 110, 101, 71, 97, 112]
        }]
    }
}

Getting Details about Events

The raw contents of the scanned tags are written to the log before the event is fired. Use adb logcat on Android

You can also log the tag contents in your event handlers. console.log(JSON.stringify(nfcEvent.tag)) Note that you want to stringify the tag not the event to avoid a circular reference.

Platform Differences

Multiple Listeners

Multiple listeners can be registered in JavaScript. e.g. addNdefListener, addTagDiscoveredListener, addMimeTypeListener.

On Android, only the most specific event will fire. If a Mime Media Tag is scanned, only the addMimeTypeListener callback is called and not the callback defined in addNdefListener. You can use the same event handler for multiple listeners.

On iOS, events are fired as NDEF ones. If the application has been launched with a NFC Tag, the scanned NDEF will be fired as soon as the addNdefListener has been called

Launching your Application when Scanning a Tag

Android

On Android, intents can be used to launch your application when a NFC tag is read. This is optional and configured in AndroidManifest.xml.

<intent-filter>
  <action android:name="android.nfc.action.NDEF_DISCOVERED" />
  <data android:mimeType="text/pg" />
  <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

Note: data android:mimeType="text/pg" should match the data type you specified in JavaScript

We have found it necessary to add android:noHistory="true" to the activity element so that scanning a tag launches the application after the user has pressed the home button.

See the Android documentation for more information about filtering for NFC intents.

iOS:

With the proper configuration, it is now possible to launch a phoneGap / cordova app by reading a NFC NDEF Tag.

When a tag is detected, a notification appears and asks you to open the linked app. It then opens the app (if it is not open yet) and gives the NDEFMessage delivered by the tag.

You don't have to start a session anymore (cf iOS notes), but you need to accept the notification in order to retrieve the tag's content.

This feature is available on iPhone XR / XS / XS Max. earlier devices do not support background tag reading.

You will need to turn on Associated Domains and Near Field Communication Tag Reading capabilities in your Xcode project, support universal links and add the website linked to the app as an Associated Domain with the following scheme:

applinks:www.example.com

Tag delivery is then handled by the plugin.

Check out the official documentation for more precise informations.

Testing

Tests require the Cordova Plugin Test Framework

Create a new project

git clone https://github.com/chariotsolutions/phonegap-nfc
cordova create nfc-test com.example.nfc.test NfcTest
cd nfc-test
cordova platform add android
cordova plugin add ../phonegap-nfc
cordova plugin add ../phonegap-nfc/tests
cordova plugin add https://github.com/apache/cordova-plugin-test-framework.git

Change the start page in config.xml

<content src="cdvtests/index.html" />

Run the app on your phone

cordova run

License

IoTize SAS

Copyright 2019 IoTize SAS

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Chariot Solutions

The MIT License

Copyright (c) 2011-2017 Chariot Solutions

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.