Lectura de varias etiquetas NFC en Android. IsoDep-tag no leerá mientras la pantalla está desbloqueada

He estado intentando crear una aplicación que pueda leer dos tipos diferentes de etiquetas NFC. Se supone que es HCE-IsoDep, emulado en un Nexus 5, y uno es un Ndef-tag. He encontrado un problema leve sin embargo:

Puedo leer ambos tipos de etiquetas, pero no de la manera que quiero hacerlo. La etiqueta de Ndef no es ningún problema en absoluto. Es cuando trato de leer la etiqueta HCE que encuentro mi problema. Sólo puedo leer la etiqueta cuando el teléfono está encendido, que emular la etiqueta en está bloqueado (la pantalla, pero el bloqueo está encendido). Cada vez que desbloqueo la pantalla ya no va a interactuar, y por lo que puedo entender intenta transmitir en su lugar.

Si intento hacerlo sin el onNewIntent y simplemente ir directamente a un onTagDiscovered , funciona tanto cuando el dispositivo HCE está bloqueado y desbloqueado, pero luego no puedo leer la etiqueta Ndef. En logcat recibo el mensaje: NfcService LLCP Activation Message cuando leo la etiqueta HCE cuando está desbloqueado.

Cuando estoy bloqueado, recibo el mensaje: NativeNfcTag Connect to a tag with a different handle (y antes de eso obtengo: audio_hw_primary select_devices: out_snd_device(2: speaker) in_snd_device(0: ) )

Mi código se ve así:

Principal:

 public class NfcReader extends Activity implements OnMessageReceived { private static String TAG = NfcReader.class.getSimpleName(); private Button sendButton; private ProgressBar callProgress; private NfcAdapter nfcAdapter; private PendingIntent pIntent; private IntentFilter[] writeTagFilters; private String[][] mTechLists; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView dateView = (TextView) findViewById(R.id.dateTextView); nfcAdapter = NfcAdapter.getDefaultAdapter(this); pIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED); writeTagFilters = new IntentFilter[] { tagDetected }; mTechLists = new String[][] {new String[] { Ndef.class.getName(), IsoDep.class.getName() }}; } @Override protected void onPause() { super.onPause(); disableForegroundMode(); } @Override protected void onResume() { super.onResume(); enableForegroundMode(); } public void enableForegroundMode() { Log.d(TAG, "onResume"); nfcAdapter.enableForegroundDispatch(this, pIntent, writeTagFilters, mTechLists); } public void disableForegroundMode() { Log.d(TAG, "onPause"); nfcAdapter.disableForegroundDispatch(this); } @Override public void onNewIntent(Intent intent) { Log.d(TAG, "onNewIntent"); if(NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())){ Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); Ndef nDef = Ndef.get(tag); if (nDef != null) { onNdefDiscovered(tag); } else { onTagDiscovered(tag); } } } public void onNdefDiscovered(Tag tag) { Log.d(TAG, "Ndef found"); new ReadTag().execute(tag); } public void onTagDiscovered(Tag tag) { Log.d(TAG, "HCEfound"); IsoDep isoDep = IsoDep.get(tag); IsoDepTransceiver transceiver = new IsoDepTransceiver(isoDep, this); transceiver.run(); } @Override public void onMessage(final byte[] message) { runOnUiThread(new Runnable() { @Override public void run() { String readFromHce = new String(message); TextView result = (TextView) findViewById(R.id.refTextView); result.setText(readFromHce); } }); } @Override public void onError(Exception exception) { onMessage(exception.getMessage().getBytes()); } } 

Manifiesto:

 <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="19" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.NFC" /> <uses-feature android:name="android.hardware.nfc" android:required="true" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:name=".HceReader" 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.NDEF_DISCOVERED"/> <action android:name="android.nfc.action.TECH_DISCOVERED"/> <action android:name="android.nfc.action.TAG_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter> <meta-data android:name="android.nfc.action.TECH_DISCOVERED" android:resource="@xml/filter_nfc"/> 

Filter_nfc.xml

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

¿Alguien tiene una idea de lo que estoy haciendo mal? He buscado bastante sin encontrar una solución a esto. Así que otra vez. Puedo leer la etiqueta Ndef sin problemas. Sólo puedo leer la etiqueta IsoDep emulada cuando la pantalla del dispositivo HCE está bloqueada.

Agradecido por cualquier ayuda
Saludos

Editar: el código siguiente está funcionando

 public class NfcReader extends Activity implements OnMessageReceived, ReaderCallback { private static String TAG = NfcReader.class.getSimpleName(); private NfcAdapter nfcAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView result = (TextView) findViewById(R.id.refTextView); nfcAdapter = NfcAdapter.getDefaultAdapter(this); } @Override protected void onPause() { super.onPause(); nfcAdapter.disableReaderMode(this); } @Override protected void onResume() { super.onResume(); nfcAdapter.enableReaderMode(this, this, NfcAdapter.FLAG_READER_NFC_A, null); } public void onTagDiscovered(Tag tag) { Log.d(TAG, "Tag Found"); Ndef nDef = Ndef.get(tag); IsoDep isoDep = IsoDep.get(tag); if (nDef != null) { new ReadTag().execute(tag); } else if (isoDep != null){ IsoDepTransceiver transceiver = new IsoDepTransceiver(isoDep, this); transceiver.run(); } } @Override public void onMessage(final byte[] message) { runOnUiThread(new Runnable() { @Override public void run() { String readFromHce = new String(message); TextView result = (TextView) findViewById(R.id.refTextView); result.setText(readFromHce); } }); } @Override public void onError(Exception exception) { onMessage(exception.getMessage().getBytes()); } } 

Muchas gracias a NFC chico por la punta.

En Android 4.4 o superior, debe utilizar enableReaderMode () para ello.

En este modo, el controlador NFC sólo actuará como un lector / grabador de etiquetas NFC, desactivando así cualquier modo peer-to-peer (Android Beam) y de emulación de tarjeta del adaptador NFC en este dispositivo.

Para interactuar con etiquetas que se emulan en otro dispositivo Android mediante la emulación de tarjetas basada en host de Android, los indicadores recomendados son FLAG_READER_NFC_A y FLAG_READER_SKIP_NDEF_CHECK.

No hiciste nada mal. Lo que has intentado hacer no funcionará por desgracia.

Si su teléfono tiene emulación de tarjeta y peer-to-peer (android beam) en ejecución, y el lector (su otro teléfono) soporta peer-to-peer, la tecnología peer-to-peer tendrá prioridad sobre la emulación de la tarjeta .

Esto tiene sentido si piensas en ello: Si pones una tarjeta SIM habilitada para NFC en tu teléfono, tendrás algunas SIM basadas en emulaciones de tarjeta fuera de host ejecutándose. Si peer-to-peer no tendría prioridad sobre la emulación de la tarjeta, el haz de android dejaría de funcionar y verías conexiones a las etiquetas de IsoDep.

En el caso de que su teléfono esté bloqueado, el peer-to-peer se desactivará y la emulación de la tarjeta tendrá prioridad. Por lo tanto, puede acceder a la emulación de la tarjeta en este estado.

Si desea acceder a la emulación de la tarjeta incluso en el estado desbloqueado de la pantalla, su única opción es utilizar un dispositivo lector que no active el protocolo peer-to-peer (como un terminal de pago autónomo, por ejemplo).

En Android no hay manera de deshabilitar peer-to-peer. Desactivar Android Beam en la configuración no le ayudará ya sea porque sólo se desactivará el protocolo Beam de alto nivel. El protocolo peer-to-peer seguirá funcionando para evitar activamente que veas la emulación de otras personas. Este comportamiento se debe a que Google no desea que las personas accedan por error a la emulación de la tarjeta de pago por motivos de seguridad.

  • Mejor NFC SDK para ACR122U y ACR1222L
  • Obtenga la etiqueta NFC con NDEF Android Application Record (AAR)
  • ¿Cómo puede mi aplicación averiguar qué modo NFC está habilitado?
  • KitKat: Cómo enrutar las APDU a la tarjeta SIM
  • ¿Cómo transmitir un contacto desde su aplicación (usando NFC) y guardarlo en la lista de contactos en el dispositivo receptor?
  • Etiquetas RFID pasivas de larga distancia compatibles con teléfonos Android con NFC?
  • Utilice el emparejamiento seguro simple de Jelly Bean (Bluetooth) para emparejarlo con NFC
  • ¿Cómo averiguar si una etiqueta NFC aún está en el rango de un Android ahora?
  • Velocidad de lectura de etiqueta NFC
  • Inicio de la aplicación cuando MIFARE Classic se detecta con Android NFC
  • ¿Cuál es la diferencia entre TAG_DISCOVERED, NDEF_DISCOVERED y TECH_DISCOVERED con el descubrimiento de dispositivos NFC o etiqueta en android?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.