Не удается вызвать метод NFC onNewIntent()

Я пытаюсь прочитать идентификатор карты Mifare Classic 1k, используя диспетчеризацию переднего плана. Как я вижу из своих журналов, я могу включить диспетчеризацию переднего плана, но не могу вызвать метод onNewIntent(). Мы ценим любые предложения.

MainActivity.java

...
@Override
   protected void onResume() {
      setupForegroundDispatch(this, mAdapter);
      super.onResume();
} 

public static void setupForegroundDispatch(final Activity activity, NfcAdapter adapter) {
    final Intent intent = new Intent(activity.getApplicationContext(), activity.getClass());
    intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
    System.out.println("Setup FGD.");  // i can see this output.

    final PendingIntent pendingIntent = PendingIntent.getActivity(activity.getApplicationContext(), 0, intent, 0);

    IntentFilter[] filters = new IntentFilter[1];
    String[][] techList = new String[][]{};

    // Notice that this is the same filter as in our manifest.
    filters[0] = new IntentFilter();
    filters[0].addAction(NfcAdapter.ACTION_NDEF_DISCOVERED);
    filters[0].addCategory(Intent.CATEGORY_DEFAULT);
    try {
        filters[0].addDataType(MIME_TEXT_PLAIN);
    } catch (MalformedMimeTypeException e) {
        throw new RuntimeException("Check your mime type.");
    }

    adapter.enableForegroundDispatch(activity, pendingIntent, filters, techList);
    System.out.println("Enabled FGD.");  // and this one.
}

protected void onNewIntent(Intent intent) { 
    System.out.println("Intent."); but i cannot see this one,
    handleIntent(intent);
}

private void handleIntent(Intent intent) {      
    System.out.println("Handle.");  // and this one.
    String action = intent.getAction();
    if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
        System.out.println("NDEF discovered.");
         ....

Манифест Android

....
 <activity
        android:name=".MainActivity"
        android:label="@string/app_name" >

        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>

        <intent-filter>
            <action android:name="android.nfc.action.TECH_DISCOVERED" />
            <action android:name="android.nfc.action.NDEF_DISCOVERED" />
            <action android:name="android.nfc.action.TAG_DISCOVERED" />
         </intent-filter>

        <meta-data
                android:name="android.nfc.action.TECH_DISCOVERED"
                android:resource="@xml/nfc_tech_filter" />
    </activity>
....

person Ceyhan ILERI    schedule 22.06.2014    source источник
comment
Содержит ли ваш тег сообщение NDEF с текстовой записью (или запись типа MIME с типом MIME text/plain) в качестве первой записи?   -  person Michael Roland    schedule 23.06.2014
comment
На самом деле, когда я добавляю действие ACTION_TECH_DISCOVERED после ACTION_NDECF_DISCOVERED в свой NfcAdapter, все решается как по волшебству. Но спасибо и за ваше решение.   -  person Ceyhan ILERI    schedule 23.06.2014
comment
На самом деле это не решило как волшебство, но на самом деле ответило на мой вопрос: значит, ваш тег не содержит такой записи NDEF, и вам нужен более общий способ обнаружения тега (с помощью его технологии тегов, а не его содержимого).   -  person Michael Roland    schedule 24.06.2014


Ответы (1)


Если вы хотите иметь возможность обнаруживать каждый тег MIFARE Classic (а не только те, которые содержат текстовую запись (или запись типа MIME с типом MIME text/plain), вам следует адаптировать отправку переднего плана для обнаружения конкретной технологии тегов, а не определенный тип записи NDEF:

public static void setupForegroundDispatch(final Activity activity, NfcAdapter adapter) {
    final Intent pendingIntent = PendingIntent.getActivity(activity, 0, new Intent(activity, activity.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);

    IntentFilter[] filters = new IntentFilter[] { new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED) };
    String[][] techList = new String[][] { new String[] { MifareClassic.class.getName() } };

    adapter.enableForegroundDispatch(activity, pendingIntent, filters, techList);
}

Если вы также хотите получить UID тегов MIFARE Classic на устройствах с набором микросхем Broadcom NFC (эти устройства не могут определить MIFARE Classic как MIFARE Classic из-за проблем с лицензированием проприетарной технологии NXP), вы можете вместо этого отфильтровать все теги NfcA (MIFARE Classic будет определяться как NfcA на всех устройствах, поэтому вам не нужно фильтровать и NfcA, и MifareClassic):

    String[][] techList = new String[][] { new String[] { NfcA.class.getName() } };

Наконец, фильтр намерений в вашем манифесте не соответствует фильтру намерений в вашем коде! Эквивалентный фильтр намерений вашей диспетчеризации переднего плана будет:

<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_tech_filter" />

С nfc_tech_filter.xml, содержащим:

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <tech-list>
        <tech>android.nfc.tech.MifareClassic</tech>
    </tech-list>
</resources>

Или (в случае совпадения для NfcA):

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <tech-list>
        <tech>android.nfc.tech.NfcA</tech>
    </tech-list>
</resources>
person Michael Roland    schedule 24.06.2014