I was trying to find a working example of how it is possible to read a message stored on a NDEF tag within the app's active Activity. By far the best I have is such a code:
public class Activity1_3_1_1 extends AppCompatActivity {
private Button done;
NfcAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity1_3_1_1);
done = findViewById(R.id.button5);
done.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
switchActivityTo1();
}
});
}
private void switchActivityTo1() {
Intent switchActivityIntent = new Intent(this, MainActivity.class);
startActivity(switchActivityIntent);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
adapter = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); // get the detected tag
Parcelable[] msgs =
intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefRecord firstRecord = ((NdefMessage) msgs[0]).getRecords()[0];
byte[] payload = firstRecord.getPayload();
int payloadLength = payload.length;
int langLength = payload[0];
int textLength = payloadLength - langLength - 1;
byte[] text = new byte[textLength];
System.arraycopy(payload, 1 + langLength, text, 0, textLength);
Toast.makeText(getApplicationContext(), new String(text), Toast.LENGTH_LONG).show();//display the response on screen
}
}
}
And the Manifest file:
...
<uses-permission android:name="android.permission.NFC"/>
<uses-feature android:name="android.hardware.nfc"/>
...
<activity
android:name=".Activity1_3_1_1"
android:exported="true"
android:alwaysRetainTaskState="true"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
The problem is that NFC Service is launching instead of app's onNewIntent() method. And it is a problem for me figuring out am I messed up with Manifest file definition (because one of solutions was to modify Manifest file in order to NFC Service won't launch) or it is problem inside the Activity code itself. Or, perhaps, both.
So the normal pattern for NFC in Android is:-
1)When you App is not running an you want it started when a certain type of NFC Tag is presented to the device then you put your intent-filters
in the manifest. Your App then gets started and passed an Intent
that you need to process in your onCreate
method using getIntent()
2a)Your App is already running in the foreground then you use enableForegroundDispatch
, giving it a pending Intent on what you want to be notified about, this is then processed in onNewIntent
when your App is restarted (paused and resumed) to receive the Intent.
onNewIntent
won't get invoked by any manifest entry.
or
2b)Your App is already running in the foreground then you use enableReaderMode
which is a better replacement for enableForegroundDispatch
, you then process the Tag in onTagDiscovered
which is in a separate thread.
How to process the Intent
received via pattern 1 and 2a is the same, just they need to be called from the correct path in the code that matches the method that triggered the Intent i.e in onCreate
or in onNewIntent
Check out Empty NFC Tag read and write Android Application. Mobile own message returning while scanning Empty Tag but Application not working? for an example of how to use Manifest and enableForeGroundDispatch
The are also plenty examples of using enableReaderMode
on Stackoverflow as well.