diff --git a/android/src/main/java/me/andisemler/nfc_in_flutter/NfcInFlutterPlugin.java b/android/src/main/java/me/andisemler/nfc_in_flutter/NfcInFlutterPlugin.java index 5505a7f..b72facf 100644 --- a/android/src/main/java/me/andisemler/nfc_in_flutter/NfcInFlutterPlugin.java +++ b/android/src/main/java/me/andisemler/nfc_in_flutter/NfcInFlutterPlugin.java @@ -8,6 +8,7 @@ import android.nfc.NdefRecord; import android.nfc.NfcAdapter; import android.nfc.Tag; +import android.nfc.tech.IsoDep; import android.nfc.tech.Ndef; import android.os.Bundle; import android.os.Handler; @@ -43,6 +44,7 @@ public class NfcInFlutterPlugin implements MethodCallHandler, private static final String LOG_TAG = "NfcInFlutterPlugin"; private final Activity activity; + private IsoDep iso_dep; private NfcAdapter adapter; private EventChannel.EventSink events; @@ -103,11 +105,87 @@ public void onMethodCall(MethodCall call, Result result) { } result.success(null); break; + case "startISODepReading": + Log.d("isodep", "start reading"); + startReadingISODep(result); + break; + case "connectISODep": + connectIsoDep(result); + break; + case "closeISODep": + closeIsoDep(result); + break; + case "setTimeOutIsoDep": + setTimeOutIsoDep(call, result); + break; + case "transceiveIsoDep": + transceiveIsoDep(call, result); + break; default: result.notImplemented(); } } + private void startReadingISODep( final Result result ) { + NfcAdapter adapter = NfcAdapter.getDefaultAdapter(activity); + if (adapter == null) return; + Bundle bundle = new Bundle(); + int DEFAULT_READER_FLAGS = NfcAdapter.FLAG_READER_NFC_A | NfcAdapter.FLAG_READER_NFC_B | NfcAdapter.FLAG_READER_NFC_F | NfcAdapter.FLAG_READER_NFC_V; + adapter.enableReaderMode(activity, new NfcAdapter.ReaderCallback() { + @Override + public void onTagDiscovered(Tag tag) { + Log.d("tag", tag.toString() ); + IsoDep new_iso_dep = IsoDep.get(tag); + if ( new_iso_dep == null ) return; + iso_dep = new_iso_dep; + eventSuccess(result, null); + Log.d("tag", "event success" ); + } + }, DEFAULT_READER_FLAGS, bundle); + } + + private void connectIsoDep( final Result result ) { + try { + iso_dep.connect(); + eventSuccess(result,null); + } catch (IOException e) { + eventError( result, e.getMessage(), e.getLocalizedMessage(), e.getStackTrace()); + } + } + + private void closeIsoDep( final Result result ) { + try { + iso_dep.close(); + eventSuccess(result,null); + } catch (IOException e) { + eventError( result, e.getMessage(), e.getLocalizedMessage(), e.getStackTrace()); + } + } + + private void setTimeOutIsoDep( final MethodCall call, final Result result ) { + if ( !call.hasArgument("timeout") ) { + eventError( result,"timeout must be provided", null, null); + return; + } + iso_dep.setTimeout( (int)call.argument("timeout") ); + eventSuccess( result, null); + } + + private void transceiveIsoDep(final MethodCall call, final Result result ) { + if ( !call.hasArgument("data") ) { + eventError(result,"To transceive data must be provided", null, null); + return; + } + final byte[] data = call.argument("data"); + try { + final byte[] response = iso_dep.transceive(data); + eventSuccess( result, response ); + } catch (IOException e) { + eventError( result, e.getMessage(), e.getLocalizedMessage(), e.getStackTrace() ); + } + + } + private Boolean nfcIsEnabled() { NfcAdapter adapter = NfcAdapter.getDefaultAdapter(activity); if (adapter == null) return false; @@ -258,4 +336,22 @@ public void run() { }; mainThread.post(runnable); } + + private void eventSuccess(final Result result, final Object parameter) { + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + result.success(parameter); + } + }); + } + + private void eventError( final Result result, final String code, final String message, final Object details) { + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + result.error(code, message, details); + } + }); + } } diff --git a/lib/src/api.dart b/lib/src/api.dart index 356fede..12e26e7 100644 --- a/lib/src/api.dart +++ b/lib/src/api.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:core'; +import 'dart:typed_data'; import 'package:flutter/services.dart'; @@ -130,6 +131,13 @@ class NFC { assert(supported is bool); return supported as bool; } + + static Future readNFCIsoDep() async => await _channel.invokeMethod("startISODepReading"); + static Future setTimeOutIsoDep( final int timeout ) async => await _channel.invokeMethod("setTimeOutIsoDep", { "timeout": timeout }); + static Future connectISODep() async => await _channel.invokeMethod("connectISODep"); + static Future closeISODep() async => await _channel.invokeMethod("closeISODep"); + static Future transceiveIsoDep( Uint8List data ) async => await _channel.invokeMethod("transceiveIsoDep", { "data": data } ); + } /// NFCReaderMode is an interface for different reading modes