- Описание сервиса в файле aid_list.xml
- Androidmanifest.xml
- App.xaml.cs
- Card emulation:
- Github — acaliaro/xamarindemonfc: demo nfc with xamarin forms (only with android…)
- Header:
- Id length:
- Mainactivity ридера
- Ndef :
- Ndefmessage:
- Ndefrecord:
- Nfc data exchange format
- Nfc with xamarin.forms nothing happens
- Nfcadapter.actionndefdiscovered:
- Nfcadapter.actiontagdiscovered:
- Nfcadapter.actiontechdiscovered:
- Nfcadapter:
- Note:
- Payload length:
- Payload:
- Peer to peer communication:
- Read and write:
- Record id:
- Record type:
- Type length:
- Xamarin — near field communication
- Xamarin and nfc
- Xamarin.ios write nfc
- Запуск приложения эмулятора при обнаружении ридера
- Механизм отправки сообщений:
- Приложение «ридер»
- Приложение «эмулятор»
- Проверка состояния nfc-адаптера и переход в настройки nfc
- Ссылки на github
- Управление эмулятором
Описание сервиса в файле aid_list.xml
В папке xml надо создать файл aid_list.xml:
Androidmanifest.xml
В документации android написано, что для использования nfc в своём приложении и правильной с ним работы, надо объявить эти элементы в AndroidManifest.xml:
При этом, если ваше приложение может использовать nfc, но это не обязательная функция, то можете пропустить элемент uses-feature и проверять доступность nfc в процессе работы.
Это всё, что касается ридера.
App.xaml.cs
Такой же как в ридере метод для вывода сообщения:
public static async Task DisplayAlertAsync(string msg) => await Device.InvokeOnMainThreadAsync(async () => await Current.MainPage.DisplayAlert("message from service", msg, "ok"));Card emulation:
Physical cards are being replaced by NFC-enabled devices. For instance, instead of a card for opening your hotel room, you could use your smartphone for opening the door.
Github — acaliaro/xamarindemonfc: demo nfc with xamarin forms (only with android…)
Demo NFC with Xamarin Forms, for Android and iOS
Header:
The header record contains important information about the message. One of those is the Type Name Format (TNF). This field indicates the type of data in the payload (the actually transferred data). These are the possible values of the TNF field:
0 -> Empty
1 -> Well-known (text, uri, etc)
2 -> Multipurpose Internet Mail Extension (MIME)
3 -> Absolute Uniform Resource Identifier (URI)
4 -> External
5- > Unknown
6 -> Unchanged (when data in the payload field is too large, the data is chunked in multiple records)
7 ->
Id length:
Length of the ID field.
Mainactivity ридера
Здесь надо объявить поле ридера:
public CardReader cardReader;и два вспомогательных метода:
private void EnableReaderMode()
{ var nfc = NfcAdapter.GetDefaultAdapter(this); if (nfc != null) nfc.EnableReaderMode(this, cardReader, READER_FLAGS, null);
}
private void DisableReaderMode()
{ var nfc = NfcAdapter.GetDefaultAdapter(this); if (nfc != null) nfc.DisableReaderMode(this);
}в методе OnCreate() инициализируем ридер и включаем режим чтения:
protected override void OnCreate(Bundle savedInstanceState)
{ ... cardReader = new CardReader(); EnableReaderMode(); LoadApplication(new App());
}а также, включаем/выключаем режим чтения при сворачивании/открытии приложения:
protected override void OnPause()
{ base.OnPause(); DisableReaderMode();
}
protected override void OnResume()
{ base.OnResume(); EnableReaderMode();
}Ndef :
Provides access to NDEF content and operations on a Tag.
Ndefmessage:
This class represent the NFC Data Exchange format message what I explained in the previous chapter.
Ndefrecord:
As I explained in the previous section a message can have multiple records.
What I mention earlier is that there different tag types available. Xamarin supports a number of these type and can be found under the namespace Android.Nfc.Tech.
Nfc data exchange format
The NDEF format is standardized by the NFC forum. This message format can be used to read or write from a tag or when working with two active enabled NFC devices. The message contains multiple records:
Nfc with xamarin.forms nothing happens
For the first time, I want to implement NFC to cross platform Xamarin.Forms for projects WinPhone and Android.
I was testing on Android my app, but nothing really happens.
As a tool, I used Visa Pay Wave card which I tested in program reTag for Android, and it was successful scan.
I used solution from a GitHub from this link
I had 0 errors, also application «works», but when I add my Visa card to my phone on the back, I get nothing.
My first question is: Which protocol uses Visa card? (TAG_DISCOVERED,TECH_DISCOVERED or NDEF_DISCOVERED). i think that’s a reason for being my program in «idle» state.
My second question is: Do you know why I can’t get any event from program? (for start to just get UID number..)
Here is my AndroidManifest.xml file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="auto"> <uses-sdk android:minSdkVersion="15" /> <uses-permission android:name="android.permission.NFC" /> <application android:label="NFCTest002.Android"></application> <uses-feature android:name="android.hardware.nfc" android:required="true" /> <application> <activity android:name="MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/plain" /> </intent-filter> <intent-filter> <action android:name="android.nfc.action.TECH_DISCOVERED"/> </intent-filter> <meta-data android:name="android.nfc.action.TECH_DISCOVERED" android:resource="@xml/nfc" /> </activity> </application>
</manifest>My MainActivity.cs:
using Android.App;
using Android.Content;
using Android.Content.PM;
using Android.Nfc;
using Android.OS;
using Poz1.NFCForms.Abstract;
using Poz1.NFCForms.Droid;
using System;
namespace NFCTest002.Droid
{
[Activity(Label = "NFCTest002", Icon = "@drawable/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
[IntentFilter(new[] { NfcAdapter.ActionTechDiscovered })]
[MetaData(NfcAdapter.ActionTechDiscovered, Resource = "@xml/nfc")]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{ public NfcAdapter NFCdevice; public NfcForms x; protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); global::Xamarin.Forms.Forms.Init(this, bundle); NfcManager NfcManager = (NfcManager)Android.App.Application.Context.GetSystemService(Context.NfcService); NFCdevice = NfcManager.DefaultAdapter; Xamarin.Forms.DependencyService.Register<INfcForms, NfcForms>(); x = Xamarin.Forms.DependencyService.Get<INfcForms>() as NfcForms; LoadApplication(new NFCTest002.App()); } protected override void OnResume() { base.OnResume(); if (NFCdevice != null) { var intent = new Intent(this, GetType()).AddFlags(ActivityFlags.SingleTop); NFCdevice.EnableForegroundDispatch ( this, PendingIntent.GetActivity(this, 0, intent, 0), new[] { new IntentFilter(NfcAdapter.ActionTechDiscovered) }, new String[][] {new string[] { NFCTechs.Ndef, }, new string[] { NFCTechs.MifareClassic, }, } ); } } protected override void OnPause() { base.OnPause(); NFCdevice.DisableForegroundDispatch(this); } protected override void OnNewIntent(Intent intent) { base.OnNewIntent(intent); x.OnNewIntent(this, intent); }
}
}I’ve added to Resource folder and xml folder with nfc.xml file, if it’s needed I will post it.
Content Page is the same as it is on GitHub in the link that I provided.
Nfcadapter.actionndefdiscovered:
A tag with an NDEF payload is discovered.
Nfcadapter.actiontagdiscovered:
A tag is discovered.
Nfcadapter.actiontechdiscovered:
A tag is discovered and activities are registered for the specific technologies on the tag.
Nfcadapter:
This class represents the device’s NFC adapter. This is the main starting point for developing with NFC. It contains all operations you need for discovering tags. This class also contains some constants which I’ll explain later.
Note:
When you’re building an App you need to explicit configure that your app wants to use the device’s NFC adapter. You can do this by selecting the required permissions in the Android Manifest.
The NfcAdapter class contains three action constants we can use for discovering tags. Meaning our app will do something when the smartphone scan a tag.
Payload length:
The length of the payload field, again in the payload field the actual data is stored.
Payload:
Contains the actual data stored in bytes.
Peer to peer communication:
Two enabled NFC devices can communicate with each other. Think of two smartphones that are exchanging data.
Read and write:
An enabled NFC device can exchange data by using tags and smart posters. A tag can hold a small amount of data that can be read by a device. An enabled NFC device can also write data on a tag (Basically they are Target and Initiator). Basically, smart posters can hold multiple tags. Smart posters are widely used for marketing/advertisement purposes.
Record id:
ID of the record, mostly used for external applications to identify the message.
Record type:
The type of the payload data. This value corresponds to the TNF field in the header.
Type length:
The length of the payload type.
Xamarin — near field communication
This technology was officially accepted in 2003 by the International Standards Organization. NFC is based on standards. These standards are created by the NFC forum. NFC connects and exchange data based on existing Radio Frequency Identification (RFID) standards.
Xamarin and nfc
The Android.Nfc namespace provides functionality to work with NFC. Also there are different tag technologies. The NFC forum standardized five different tags, type 1, 2, 3, 4, 5. These tags are the most common ones and are being supported by most of the enabled NFC devices. There are also alternatives like MIFARE classic.
Xamarin.ios write nfc
The beauty of Xamarin.iOS is that everything you can do with the native Apple libraries, you can do in C#. So if something is possible using Swift using the native libraries, you will be able to do it using the C# version of that library, using CoreNFC in your case.
So your next step is just figuring out how to write that Swift/Obj-C code in C#.
Using the Apple docs, it’s clear that you have only certain types of tags you can write to using an iPhone. So let’s choose to go with the NFCISO7816Tag.
First you would have to create a class that implements INFCIso7816Tag. So I created NFCIso7816Tag that implements INFCIso7816Tag. I fill out everything appropriately. And after that, inside my code I create an instance of NFCIso7816Tag and also create an actionHandler delegate of type NFCIso7816SendCompletionHandler. So your code would look something like this:
var tag = new NFCMiFareTag();
tag.SendCommand(new NFCIso7816Apdu(...), actionHandler);Lastly, don’t forget to use the newer devices, since you can’t write to NFCs on the older devices!
Here’s a list of projects that use CoreNFC, it might give you a headstart on how to implement it yourself!
Edit May 2020:
I wrote an article that explains How to get started with NFC on iOS and Android apps using Xamarin Forms and also created this video. There’s an awesome nuget package for Xamarin forms called Plugin.NFC that also allows you to write Tags using iOS too
Запуск приложения эмулятора при обнаружении ридера
Если надо просто открыть приложение эмулятора, то в методе ProcessCommandApdu добавьте строку:
StartActivity(typeof(MainActivity));Если необходимо передать в приложение параметры, то так:
var activity = new Intent(this, typeof(MainActivity));
intent.PutExtra("MSG_DATA", "data for application");
this.StartActivity(activity);Прочитать переданные параметры можно в классе MainActivity в методе OnCreate:
...
LoadApplication(new App());
if (Intent.Extras != null)
{ var message = Intent.Extras.GetString("MSG_DATA"); await App.DisplayAlertAsync(message);
}Механизм отправки сообщений:
Сервис не имеет ссылок на MainActivity, которая в момент получения APDU команды может быть и вовсе не запущена. Поэтому отправляем сообщения из CardService в MainActivity с помощью BroadcastReceiver следующим образом:
Метод для отправки сообщения из CardService:
private void SendMessageToActivity(string msg)
{ Intent intent = new Intent("MSG_NAME"); intent.PutExtra("MSG_DATA", msg); SendBroadcast(intent);
}Получение сообщения:Создаём класс MessageReceiver:
Приложение «ридер»
Начнём с ридера, т.к. он проще.
Создаём в Visual Studio новый проект типа «Mobile App(Xamarin.Forms)» далее выбираем шаблон «Blank» и оставляем только галочку «Android» в разделе «Platforms».
В андроид-проекте надо сделать следующее:
И в кроссплатформенном проекте в файле App.xaml.cs:
Приложение «эмулятор»
Опять создаём в Visual Studio новый проект типа «Mobile App(Xamarin.Forms)» далее выбираем шаблон «Blank» и оставляем только галочку «Android» в разделе «Platforms».
В Android-проекте надо сделать следующее:
И в кроссплатформенном проекте в файле App.xaml.cs:
Проверка состояния nfc-адаптера и переход в настройки nfc
Этот раздел применим и к ридеру и к эмулятору.
Создадим в андроид-проекте NfcHelper и используем DependencyService для доступа к нему из кода страницы MainPage.
Ссылки на github
эмуляторридер
Управление эмулятором
Настройки буду хранить с помощью Xamarin.Essentials.
Сделаем так: при перезапуске приложения эмулятора будем обновлять настройку:
Xamarin.Essentials.Preferences.Set("key1", Guid.NewGuid().ToString());а в методе ProcessCommandApdu будем каждый раз заново брать это значение:
var messageToReader = $"Hello Reader! - {Xamarin.Essentials.Preferences.Get("key1", "key1 not found")}";теперь при каждом перезапуске(не сворачивании) приложения эмулятора видим новый guid, например:
Hello Reader! - 76324a99-b5c3-46bc-8678-5650dab0529d
Так же через настройки включаем/выключаем эмулятор:
Xamarin.Essentials.Preferences.Set("IsEnabled", false);а в начало метода ProcessCommandApdu добавляем:
var IsEnabled = Xamarin.Essentials.Preferences.Get("IsEnabled", false);
if (!IsEnabled) return UNKNOWN_CMD_SW; // 0x00, 0x00Это простой способ, но есть и другие.





