I am trying to create an application that can read two different types of NFC tags. It is assumed that HCE-IsoDep is emulated on Nexus 5, and one is the Ndef tag. However, I ran into a small problem:
I manage to read both types of tags, but not the way I want to do it. The Ndef tag is not a problem at all. When I try to read the HCE tag, I run into my problem. I can only read the tag when the phone is on, which I imitate the tag is locked (the screen is on, but the lock is on). Whenever I unlock the screen, it will no longer interact, and as far as I can understand, it is trying to turn on the beam.
If I try to do this without onNewIntentand just go to onTagDiscovered, it works at the same time when the HCE device is locked and unlocked, but then I canβt read the Ndef tag. In logcat, I get the message: NfcService LLCP Activation Messagewhen I read the HCE tag when unlocking.
When locked, I get the message NativeNfcTag Connect to a tag with a different handle(and before that I get: audio_hw_primary select_devices: out_snd_device(2: speaker) in_snd_device(0: ))
My code is as follows:
Main:
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());
}
}
manifest:
<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>
Does anyone have an idea what I'm doing wrong? I searched around quite a bit, not finding a solution for this. So again. I can read the Ndef tag without any problems. I can only read the emultated IsoDep tag when the screen on the HCE device is locked.
Thanks for any help
Relationship
Edit: code below works
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());
}
}
Many thanks to the NFC guy for the tip.