NFC-адаптер Firemonkey для Android

Я новичок в Firemonkey и Android, и я не знаю, есть ли у меня неправильный подход. Я хочу, чтобы приложение работало и считывало NFC-тег.

Есть ли способ использовать NFC Reader на устройствах Android с firemonkey?

С частью NFCAdapter от FMXExpress (http://www.fmxexpress.com/full-android-sdk-interface-files-in-object-pascal-for-firemonkey/) я могу определить, есть ли на устройстве считыватель NFC и включен ли он. Но чтобы использовать все функции, мне пришлось вручную определить все интерфейсы и решить все циклические ссылки. Я не думаю, что это может привести к правильному решению.

Я столкнулся с решением создать свой собственный JavaClass для связи с адаптером nfc, как это описано в этом сообщении в блоге: http://blong.com/Articles/DelphiXE5AndroidActivityResult/ActivityResult.htm#Building


person deterministicFail    schedule 09.07.2014    source источник
comment
Если вы все еще застряли на этом, @deterministicFail, я написал, как читать и записывать теги NFC в приложениях Delphi для Android для XE5, XE6 и XE7. Пост со ссылками на все три статьи можно найти здесь: blog.blong.com/2014/09/delphi-and-nfc-on-android.html Наслаждайтесь!   -  person blong    schedule 10.09.2014


Ответы (1)


Да! Вы придерживаетесь правильного подхода.

Чтобы заставить Delphi и FireMonkey работать, вы можете использовать следующий template, так как это правильный способ достичь того, что вы задумали:

Интерфейс:

/ JNI NFC import demo
// Note - REQUIRES - PROJECT OPTIONS - USES PERMISSIONS - NFC

interface

uses
  Androidapi.JNIBridge,
  Androidapi.JNI.JavaTypes,
  Androidapi.JNI.GraphicsContentViewText,
  FMX.Helpers.Android,
  SysUtils,
  Classes;

type

Адаптер NFC:

  /////////////////////////// NfcAdapter /////////////////////////////////
  JNfcManager = interface;
  JNfcAdapter = interface;

  JNfcAdapterClass = interface(JObjectClass)
  ['{634258AC-7931-4E38-97E6-48DBF688A288}']
    {Property methods}
    function _ACTION_TAG_DISCOVERED: JString; cdecl;
    function _EXTRA_ID: JString; cdecl;
    function _EXTRA_NDEF_MESSAGES: JString; cdecl;
    function _EXTRA_TAG: JString; cdecl;
    {Properties}
    property ACTION_TAG_DISCOVERED: JString read _ACTION_TAG_DISCOVERED;
    property EXTRA_ID: JString read _EXTRA_ID;
    property EXTRA_NDEF_MESSAGES: JString read _EXTRA_NDEF_MESSAGES;
    property EXTRA_TAG: JString read _EXTRA_TAG;
  end;

  [JavaSignature('android/nfc/NfcAdapter')]
  JNfcAdapter = interface(JObject)
  ['{364D8F3F-23AE-4C28-A261-E30C0893B24C}']
    //Return true if this NFC Adapter has any features enabled
    function isEnabled: Boolean; cdecl;
  end;

  TJNfcAdapter = class(TJavaGenericImport<JNfcAdapterClass, JNfcAdapter>) end;

NfcManager:

  /////////////////////////// NfcManager /////////////////////////////////

  JNfcManagerClass = interface(JObjectClass)
  ['{812481E1-F491-47D2-AC1F-4C5AB509532B}']
  end;

  [JavaSignature('android/nfc/NfcManager')]
  JNfcManager = interface(JObject)
  ['{04B707EC-966A-4E4F-85DC-F003B7C9ACE3}']
    {Methods}
    function getDefaultAdapter: JNfcAdapter; cdecl;
  end;

  TJNfcManager = class(TJavaGenericImport<JNfcManagerClass, JNfcManager>) end;

function HasNfc: Boolean;
function IsNfcEnabled: Boolean;

implementation

function GetNfcManager: JNfcManager;
var
  ConnectivityServiceNative: JObject;
begin
  ConnectivityServiceNative := SharedActivityContext.getSystemService(TJContext.JavaClass.NFC_SERVICE);
  if not Assigned(ConnectivityServiceNative) then
    raise Exception.Create('Could not locate Nfc Service');
  Result := TJNfcManager.Wrap((ConnectivityServiceNative as ILocalObject).GetObjectID);
  if not Assigned(Result) then
    raise Exception.Create('Could not access Nfc Manager');
end;

function HasNfc: Boolean;
var
  NfcManager: JNfcManager;
  NfcAdapter: JNfcAdapter;
begin
  NfcManager := GetNfcManager;
  NfcAdapter := NfcManager.getDefaultAdapter;
  Result := Assigned(NfcAdapter);
end;

function IsNfcEnabled: Boolean;
var
  NfcManager: JNfcManager;
  NfcAdapter: JNfcAdapter;
begin
  NfcManager := GetNfcManager;
  NfcAdapter := NfcManager.getDefaultAdapter;
  Result := Assigned(NfcAdapter)and NfcAdapter.isEnabled;
end;

end.

{code}

usage
Memo1.Lines.Add('Nfc Enabled: '+BoolToStr(IsNfcEnabled, True));

Если вы поэкспериментируете с этим примером кода, я уверен, что он сработает!

Я полагаю, вы вынуждены использовать лучшее из всего, например, использовать API, который является полностью кроссплатформенным и мультиплатформенным, что позволит вам иметь точно такой же код, работающий на Android и iOS без каких-либо изменений внешнего и внутреннего интерфейса вашего приложения. Да, это правда, что в настоящее время разрабатываются некоторые инструменты, предназначенные для решения реальных многоплатформенных встроенных разработка, которая, возможно, будет полностью интегрирована в ближайшем будущем. К сожалению, реальность такова, что на нынешних этапах разработки мобильных платформ вы можете использовать такие мультиплатформенные инструменты только в том случае, если вы реализуете более простые приложения, которые не будут зависеть от более конкретных ресурсов, таких как NFC, Geofencing и т. д. Конечно, если вы не находитесь в производственной среде , то, в конце концов, у вас может быть все время, чтобы играть и заниматься хакерством для развлечения. Но предположим, что это не так, тогда сосредоточьтесь на сборе вещей для быстрой работы, поскольку сроки доставки обычно сжаты.

Тем не менее, в качестве альтернативы, самый быстрый и кратчайший способ установить связь с помощью NFC-тегов — это просто сделать это с помощью ресурса Android NFC API, который был представлен начиная с уровня API 9 — Android Gingerbread.

введите здесь описание изображения

Передача NFC может происходить между двумя устройствами с поддержкой NFC или между устройством и «меткой» NFC. Теги могут варьироваться от пассивных тегов, которые передают URL-адрес при сканировании, до сложных систем, используемых в платежных решениях NFC, таких как Google Кошелек.

введите здесь описание изображения

Чтобы читать, писать или транслировать сообщения NFC, вашему приложению требуется разрешение манифеста NFC:

<uses-permission android:name=”android.permission.NFC” />

Когда устройство Android используется для сканирования метки NFC, система будет декодировать входящую полезную нагрузку, используя собственную систему отправки меток, которая анализирует метку, классифицирует данные и использует Intent для запуска приложения для получения данных.

Вот код снимка, показывающий, как зарегистрировать действие, которое будет отвечать только на теги NFC:

<activity android:name=”.BlogViewer”>
    <intent-filter>
        <action android:name=”android.nfc.action.NDEF_DISCOVERED”/>
        <category android:name=”android.intent.category.DEFAULT”/>
        <data android:scheme=”http”android:host=”blog.example.com”/>
    </intent-filter>
</activity>

Дополнение NfcAdapter.EXTRA_TAG включает необработанный объект Tag, который представляет отсканированный тег. Дополнение NfcAdapter.EXTRA_TNDEF_MESSAGES содержит массив сообщений NDEF:

String action = getIntent().getAction();

if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
    Parcelable[] messages =
    intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
    for (int i = 0; i < messages.length; i++) {
        NdefMessage message = (NdefMessage)messages[i];
        NdefRecord[] records = message.getRecords();
        for (int j = 0; j < records.length; j++) {
            NdefRecord record = records[j];
            // TODO Process the individual records.
        }
    }
}

введите здесь описание изображения

Потенциал и возможности приложений NFC огромны, а спрос для такой технологии имеет тенденцию к значительному росту:

введите здесь описание изображения

Если вы можете использовать свой смартфон в качестве способа оплаты, то оплата таких вещей, как общественный транспорт и парковочные счетчики, может быть такой же простой, как считывание телефона. Вы даже можете нажать на газетный терминал во время ежедневных поездок на работу, чтобы загрузить последний выпуск на свое устройство.

person Avanz    schedule 26.07.2014
comment
Спасибо за ваш подробный ответ. К сожалению, я привязан к delphi и firemonkey. - person deterministicFail; 28.07.2014
comment
Спасибо за ваши усилия. Эти интерфейсы - это то, что я имел в виду в своем вопросе, и это единственный пример Delphi в сети. Основываясь на своих исследованиях, я пришел к выводу, что единственный правильный способ на данный момент - это реализовать собственный JavaClass и использовать его из Firemonkey. - person deterministicFail; 28.07.2014