Search code examples
javaandroidnfcandroid-lifecyclerfid

Android NFC always calling onCreate when app is closed


enter image description hereI made app that detects nfc tag. All work fine, when my app is closed and i scan the nfc tag with my phone it shows me an activity have onCreate() method , when i scan again for the 2nd time it works , i dont know if im wrong in the lifecycle of the app or that i missed something in my code? when i open app , scanning is working : 1st photo when app is closed 2nd photo : from 2nd photo but in the 2nd scan it worksenter image description here this is my code

public class NfcActivity extends AppCompatActivity {

    private static final String TAG = "NfcActivity";

    private NfcAdapter mNfcAdapter;
    private TextView mTextView;
    PendingIntent pendingIntent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_nfc);
        mTextView = findViewById(R.id.tv_nfc_detail);
        mNfcAdapter = NfcAdapter.getDefaultAdapter(getApplicationContext());
        if (mNfcAdapter == null) {
            Toast.makeText(this, "Cet appareil ne supporte pas nfc", Toast.LENGTH_SHORT).show();
            finish();
            return;
        }
        if (!mNfcAdapter.isEnabled()) {
            startActivity(new Intent("android.settings.NFC_SETTINGS"));
            Toast.makeText(this, "Activer nfc", Toast.LENGTH_SHORT).show();
        }

        pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,
            getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
    }

    @Override
    protected void onPause() {
        super.onPause();
        mNfcAdapter.disableForegroundDispatch(this);
    }

    @Override
    protected void onResume() {
        super.onResume();
        pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,
            getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
        IntentFilter[] intentFilters = new IntentFilter[]{};
        mNfcAdapter.enableForegroundDispatch(this, pendingIntent, intentFilters, null);

    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
//        if ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == 0) {
            if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())
                    || NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction()) || NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
                Tag iTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
                mTextView.setText(TagReader.readTag(iTag, intent));
            }
      //  }
    }
}
<activity android:name=".Activities.NfcActivity" android:launchMode="singleTask">

    <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" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.nfc.action.TECH_DISCOVERED" />
    </intent-filter>
</activity> 

Solution

  • Edit: see full solution in related:


    You are only processing the intent the 2nd time round.

    Add a new method based on your current onNewIntent() method like this:

    private void onNewNfcTag(Intent intent) {
        if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())
                || NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction()) 
                || NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
            Tag iTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
            mTextView.setText(TagReader.readTag(iTag, intent));
        }
    }
    

    Change your onNewIntent() to call this new method:

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        onNewNfcTag(intent);
    }
    

    Call this same method from onCreate() with the intent from getIntent():

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // .... your code already here
        onNewNfcTag(getIntent());
    }