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 标签。这很好用。
但在那之后,当我
单击 MainActivity 中的 BackPressed 按钮(即退出应用程序),并且
然后按住主屏幕按钮并在概览屏幕中 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())) {
...
}
}
我对 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 标签。这很好用。
但在那之后,当我
单击 MainActivity 中的 BackPressed 按钮(即退出应用程序),并且
然后按住主屏幕按钮并在概览屏幕中 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())) {
...
}
}