Android 从历史记录启动时,getIntent() 未返回预期的 Intent

Android getIntent() not returning expected Intent when launched from history

我对 Activity 生命周期和 NFC 有疑问:

我有一个带有 AndroidManifest.xml 条目的 MainActivity:

<activity
    android:name=".ui.main.MainActivity"
    android:finishOnTaskLaunch="true"
    android:launchMode="singleTask"

    android:theme="@style/AppTheme.NoActionBar">

    <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" />
        <data android:mimeType="application/androidbeam" />
    </intent-filter>

    <intent-filter>
        <action android:name="android.nfc.action.NDEF_DISCOVERED" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="application/nfctag" />
    </intent-filter>

    <meta-data
        android:name="android.nfc.action.TECH_DISCOVERED"
        android:resource="@xml/nfc_tech_filter" />
</activity>

其中 launchMode="singleTask" 用于 NFC 以防止多个 MainActivity 实例。

在 MainActivity 我有以下代码:

public class MainActivity extends BaseActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Timber.d("onCreate");
        setContentView(R.layout.activity_main);
        handleIntent(getIntent());
    }

    @Override
    protected void onNewIntent(Intent intent) {
        Timber.d("OnNewIntent");
        handleIntent(intent);
    }

    private void handleIntent(Intent intent){
         String action = intent.getAction();
            String intent_type = intent.getType();
            Timber.d("Intent action:" + action + "\n " + "Intent type:" + intent_type);
          if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action) || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
                // Handle data from intent.getParcelableExtra()
                Timber.d("onNFCDataReaded");

          }
          // and implementing creating of activity here
    }

    @Override
    protected void onResume() {
        super.onResume();
        Timber.d("onResume");
        enableNFCDispatch(); 
    }

    @Override
    protected void onPause() {
        Timber.d("onPause");
        super.onPause();
        disableNFCDispatch();
    }

    @Override
    protected void onDestroy() {  
        super.onDestroy();
        Timber.d("OnDestroy"); 
    }

    @Override
    public void onBackPressed() { 
        super.onBackPressed();
        Timber.d("OnBackPressed");
    }

}

一切都按预期工作,除了一个用例:

当我首先使用 Android Beam 或 NFC 标签打开应用程序时,会调用 onCreate() 并将从 getIntent() 接收到的数据传递给 handleIntent()另一个 phone 或 NFC 标签。这很好用。

但在那之后,当我

  1. 单击 MainActivity 中的 BackPressed 按钮(即退出应用程序),并且

  2. 然后按住主屏幕按钮并在概览屏幕中 select 我的应用程序,

我的应用程序再次打开并再次调用 onCreate()。但是,getIntent() returns 意图与 相同的数据 (intent.getAction(), intent.getParcelableExtra()) 就像我用 Android Beam 或 NFC 标签得到的一样!

我不明白为什么!我希望收到新的意向;就像我点击应用程序图标时创建应用程序一样。

有人可以帮我解决这个问题吗?

这是我的主要Activity生命周期:

MainActivity: onCreate
MainActivity: handleIntent
MainActivity:  Intent action: android.nfc.action.NDEF_DISCOVERED 
               Intent type: application/androidbeam
MainActivity: onNFCDataReaded
MainActivity: OnResume  
MainActivity: OnBackPressed
MainActivity: onPause
MainActivity: OnDestroy

//After that, I am holding Home Button and selecting my application from
//OverViewScreen, and getting next Log:

MainActivity: onCreate
MainActivity: handleIntent
MainActivity: Intent action:android.nfc.action.NDEF_DISCOVERED  
              Intent type:application/androidbeam      
             - // I do not expect it here !!!!! 
MainActivity: onNFCDataReaded      
MainActivity: OnResume

这是预期的行为。当您将 activity 置于后台并稍后从历史记录(长按主页键)再次打开 activity 时,Android 将重新创建之前的 activity 堆栈和 activity 将使用与之前打开时相同的参数启动。 IE。如果它是带着意图 NDEF_DISCOVERED 启动的,它将再次收到该意图。

但是,您可以很容易地检测到 activity 是按原意启动的还是从历史记录启动的。在后一种情况下,Android 将标志 FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY 添加到意图中。因此,您可以在 handleIntent() 方法中测试此标志:

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())) {
        ...
    }
}