Android NFC в Embarcadero XE5

Попытка заставить NFC работать на Android в Embarcadero XE5. Началось со следующего: https://forums.embarcadero.com/thread.jspa?threadID=97574 которые, похоже, работают. Теперь хотелось бы зарегистрировать обратный вызов для NFC Intent

Java-подход:

1. Register current activity as a listener
...
2. Receive Intent
@Override
protected void onNewIntent(Intent intent) {
    if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
        NdefMessage[] msgs = NfcUtils.getNdefMessages(intent);
    }
}

Источник: http://www.jessechen.net/blog/how-to-nfc-on-the-android-platform/

Delphi подход (как я и предполагал):

1. Define methods available in Java interface

Источник: https://forums.embarcadero.com/thread.jspa?messageID=634212

Question:
How do I register a listener for NFC intent messages and 
how do I eventually get messages?

Мое предположение было бы назвать метод enableForegroundDispatch. Определите это как:

procedure enableForegroundDispatch; cddcl;

чтобы вызвать его из Android API

Но так как я никогда раньше этого не делал, я не знаю, как продолжить

Ответы

Ответ 1

Изменить: Кажется, я пропустил тег, и OP не запрашивает Java-код. Оставляя это в любом случае для дальнейшего использования

Ваша догадка правильная, хотя можно определить намерения, которые вы хотите прослушать в AndroidManifest.xml, отправка переднего плана действительно помещает ваше приложение в front, что дает вам возможность capture all запустил NFC.

Способ, описанный в docs, дает вам ключ.

Я предполагаю, что вы знакомы с жизненным циклом деятельности Android, Intent Dispatching и т.д.


Структура

Используя следующую структуру, у вас будет 4 поля:

private PendingIntent pendingIntent;
private IntentFilter[] mIntentFilters;
private String[][] mTechLists;
private NfcAdapter mNfcAdapter;

В onCreate вы получите:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
    pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);

    mIntentFilters = new IntentFilter[]{new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED)};
    mTechLists = new String[][]{new String[]{Ndef.class.getName()},
                new String[]{NdefFormatable.class.getName()}};
}

Этот делает, фактически не разрешает отправку переднего плана, это всего лишь подготовка. Приложение получит технологии Ndef и NdefFormatable Почему мы подписываемся на ACTION_NDEF_DISCOVERED?

Порядок, в котором Android пытается обработать намерение, таков:

  • ACTION_NDEF_DISCOVERED
  • ACTION_TECH_DISCOVERED
  • ACTION_TAG_DISCOVERED

Итак, мы уверены, что наше приложение первое, на что можно обратить внимание Android.


Включить FGD

Поместите следующую строку кода в метод onResume:

if (mNfcAdapter != null) {
        mNfcAdapter.enableForegroundDispatch(this, pendingIntent, mIntentFilters, mTechLists);
    }

Почему это в onResume? Как указано в документах: enableForegroundDispatch() must be called from the main thread and only when the activity is in the foreground (calling in onResume() guarantees this)

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