问题
I have an application that uses the NFC. I have a MainActivity that extends a BaseActivity. In the BaseActivity, on the "onCreate" method, I initialize the nfc.
---- Base Activity ----
....
private void initializeNfc() {
NfcManager manager = (NfcManager) getSystemService(NFC_SERVICE);
nfcAdapter = manager.getDefaultAdapter();
IntentFilter filterNdef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
try {
filterNdef.addDataScheme(CipherClient.nfcDataScheme());
filterNdef.addDataAuthority(CipherClient.nfcDataAuthority(), null);
filterNdef.addDataPath(CipherClient.nfcDataPath(), PatternMatcher.PATTERN_SIMPLE_GLOB);
} catch (Exception e) {
Log.e(TAG, "Errore", e);
return;
}
intents = new IntentFilter[]{filterNdef};
pending = PendingIntent.getActivity(this, 0, new Intent(getApplicationContext(), getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
techs = new String[][]{new String[]{NfcF.class.getName()}};
}
In the MainActivity I have a slider with 4 tabs and in each tab I have a fragment. The fragment where I can use the nfc is only the number 0 (NfcFragment).
The first time I start the MainActivity, the "onCreate" method is called and the first fragment (FirstFragment) is displayed. If I'm not in the NfcFragment and I approach a nfc tag, I get a toast that says "move to the NfcFragment to use the nfc".
---- MainActivity ----
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
Log.i(TAG, "onPageSelected - position: "+position);
currentTabPosition = position;
if(position == 0) {
// I am in the NFC tab. So I set true the flag
if (verifyNfc()) {
nfcON = true;
}
}
else{
// I'm not on the nfc tab, so I set false the flag
nfcON = false;
enableForegroundDispatch();
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
private boolean verifyNfc() {
boolean nfcEnabled = nfcAdapter.isEnabled();
if (!nfcEnabled) {
Log.i(TAG, "NFC not activated");
// NFC disabled
Toast....
}
return nfcEnabled;
}
If I move to the NfcFragment and approach a nfc tag, the "onNewIntent" method is called and I open a new activity (MyNewActivity). From MyNewActivity I press back, "onBackPressed" is called and I do "finish()".
---- MainActivity ----
@Override
protected void onNewIntent(Intent intent) {
Log.i(TAG, "onNewIntent");
if (nfcON) {
// nfcHandlingInProgress is a variable that checks if you are already using the nfc (in read or write) or is free
if (!nfcHandlingInProgress) {
nfcHandlingInProgress = true;
handleIntent(intent);
}
else {
String message = "NFC already in use, wait a few moments and try again";
Log.d(TAG, message);
Toast...
}
}
else {
// If I am not on the tab that contains the NFC fragment, I do not continue and invite the user to move to this tab.
String message = "To use the NFC move to the NFC section";
Log.d(TAG, message);
Toast...
}
}
private void handleIntent(Intent intent) {
Log.i(TAG, "handleIntent");
..... // if the nfc scheme, data and authority are known, I start a new activity
nfcHandlingInProgress = false;
Intent i = new Intent(this, MyNewActivity.class);
startActivity(i);
}
@Override
protected void onPause() {
Log.i(TAG, "onPause");
super.onPause();
disableForegroundDispatch();
}
public void disableForegroundDispatch(){
Log.i(TAG, "disableForegroundDispatch");
try {
if (nfcAdapter != null) {
nfcAdapter.disableForegroundDispatch(this);
}
}
catch (Exception e){
Toast...
}
}
From MyNewActivity I go back and find myself again in the MainActivity (which is already instantiated and therefore is not called "onCreate" but "onResume").
---- MyNewActivity ----
@Override
public void onBackPressed() {
super.onBackPressed();
finish();
}
---- MainActivity ----
@Override
protected void onResume() {
Log.i(TAG, "onResume");
super.onResume();
enableForegroundDispatch();
if(currentTabPosition == 0)
nfcON = true;
else
nfcON = false;
}
public void enableForegroundDispatch(){
Log.i(TAG, "enableForegroundDispatch");
try {
if (nfcAdapter != null) {
if (nfcAdapter.isEnabled())
nfcAdapter.enableForegroundDispatch(this, pending, intents, techs);
}
}
catch (Exception e){
Toast...
}
}
NOW, if I go to a fragment that isn't NfcFragment, it should display a toast right? Instead no, from any fragment, if I approach a nfc tag, MyNewActivity is opened. The problem is that the onNewIntent method is no longer called, it is bypassed.
I used in "onPause" the method disableForegroundDispatch and in "onResume" the method enableForegroundDispatch correctly. I also used the flags FLAG_ACTIVITY_SINGLE_TOP, FLAG_ACTIVITY_SINGLE_TASK etc.
This behavior is solved if I re-initialize the nfc in the method onResume of MainActivity or if I do startActivity(this, MainActivity.class) in the method "onBackPressed" of MyNewActivity, because is called onCreate method and new instance of the activity is created. But it's a work around and I wouldn't want to initialize the nfc repeatedly.
---- MyNewActivity ----
// Solution 1 to which I do not want to resort because it is heavy to load 4 tabs together in the main activity
@Override
public void onBackPressed() {
super.onBackPressed();
Intent i = new Intent(this, MainActivity.class);
startActivity(i);
finish();
}
---- MainActivity ----
// Solution 2 that I don't want to use because onResume is called more than once
@Override
protected void onResume() {
Log.i(TAG, "onResume");
super.onResume();
// NEW NEW NEW
initializeNFC(); // <----------------------------
enableForegroundDispatch();
if(currentTabPosition == 0)
nfcON = true;
else
nfcON = false;
}
Please could someone give me a solution to initialize the nfc one time and intercept the nfc tag always with the onNewIntent method? Even if I come back to the MainActivity from MyNewActivity and so is called onResume method and not onCreate method.
Any suggestions ? Thank you very much
来源:https://stackoverflow.com/questions/57920613/android-nfc-in-tabs-viewpager-fragments-onnewintent-isnt-called-after-onpa