我一直在尝试创建一个可以读取两种不同类型的NFC标签的应用程序.一个应该是HCE-IsoDep,在Nexus 5上模拟,一个是Ndef-tag.我遇到了一个小问题:
我设法读取两种类型的标签,但不是我想要的方式.Ndef标签完全没问题.当我尝试阅读我遇到问题的HCE标签时.我只能在手机打开时读取标签,我模拟标签打开(屏幕打开,但锁定打开).每当我解锁屏幕时,它就不会再进行交互了,据我所知,它试图反射.
如果我试图在没有它的情况下onNewIntent
直接进行操作onTagDiscovered
,那么在HCE设备被锁定和解锁时它都可以工作,但是我无法读取Ndef标签.在logcat中,我收到消息:NfcService LLCP Activation Message
当我解锁时读取HCE标签.
当锁定我收到消息:NativeNfcTag Connect to a tag with a different handle
(在此之前,我得到:audio_hw_primary select_devices: out_snd_device(2: speaker) in_snd_device(0: )
)
我的代码如下:
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()); } }
android.nfc.tech.IsoDep android.nfc.tech.Ndef
有谁知道我做错了什么?我在没有找到解决方案的情况下搜索了很多.再说一遍.我可以毫无问题地阅读Ndef标签.当HCE设备上的屏幕被锁定时,我只能读取已验证的IsoDep标签.
感谢所有帮助
关心
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()); } }
非常感谢NFC人员提示.
在Android 4.4及更高版本上,您应该使用enableReaderMode().
在此模式下,NFC控制器将仅充当NFC标签读取器/写入器,从而禁用此设备上的NFC适配器的任何对等(Android Beam)和卡仿真模式.
要使用Android的基于主机的卡仿真与在其他Android设备上模拟的标签进行交互,建议的标志为FLAG_READER_NFC_A和FLAG_READER_SKIP_NDEF_CHECK.