【问题标题】:Receiving consecutive SEND intents brings app back to the front, but does not update Intent接收连续的 SEND Intent 将应用程序带回最前面,但不会更新 Intent
【发布时间】:2015-05-13 08:07:39
【问题描述】:

在我正在进行的一个项目中,我遇到了接收外部意图的问题,即非启动器意图。我有一个Activity,可以使用普通的LAUNCHER 意图启动,但它也响应来自其他应用程序的SEND 意图,例如在 YouTube 应用中分享视频链接。我第一次分享来自其他应用程序的链接时,我的Activity 被创建,我可以使用getIntent() 来获取意图的详细信息,即EXTRA_TEXT。如果我关闭我的Activity 并使用另一个链接重试,那也可以。但是,如果我不关闭我的Activity,通过“主页”或“最近启动的应用程序”返回另一个应用程序,并分享另一个链接,我的Activity 会回到前台,但getIntent() 结果在意图中,而不是我认为会触发我Activity重启的新意图。

我创建了一个 MCVE 来说明这个问题:

Activity:

public class MainActivity extends ActionBarActivity {
    private TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d("MainActivity", "onCreate");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = (TextView) findViewById(R.id.intent_text);
    }

    @Override
    protected void onResume() {
        Log.d("MainActivity", "onResume");
        super.onResume();
        Intent intent = getIntent();
        String text;
        if (intent.hasExtra(Intent.EXTRA_TEXT)) {
            text = intent.getExtras().getString(Intent.EXTRA_TEXT);
        } else {
            text = "nothing";
        }
        tv.setText(text);
    }
}

清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.intenttest"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="IntentTest"
        android:theme="@style/Theme.AppCompat" >
        <activity
            android:name=".MainActivity"
            android:label="IntentTest" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.SEND" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="text/*" />
            </intent-filter>
        </activity>
    </application>

</manifest>

为了完整起见,简单的布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.intenttest.MainActivity" >

    <TextView
        android:id="@+id/intent_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>
  1. 启动应用,文本视图打印“无”
  2. 启动 YouTube 应用,共享链接,选择此应用,应用重新启动,文本视图显示 YouTube 共享的任何文本
  3. 新闻主页
  4. 返回 YouTube 应用,分享不同的链接,选择此应用,应用重新启动,文本视图显示与之前相同的旧文本
  5. 从“最近的应用”中按回或滑动应用
  6. 返回 YouTube 应用,分享另一个链接,选择此应用,应用重新启动(重新创建),文本视图显示 YouTube 刚刚分享的新文本

我觉得我在这里缺少一些基本的东西。如何让我的应用响应新的Intent

【问题讨论】:

  • 在 oncreate 之前尝试这个覆盖:@Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent);设置意图(意图); }
  • onNewIntent() 只有在活动设置为 android:launchMode="singleTop" 时才会被调用,正如 David Wasser 在他的回答中所描述的那样。

标签: android android-intent android-activity


【解决方案1】:

android:launchMode="singleTop" 添加到&lt;activity&gt; 描述中。

当 Activity 启动时(如果它尚未运行),Android 将调用 onCreate(),您可以通过调用 getIntent() 获取 Intent(就像您已经在做的那样)。

如果 Activity 在您的应用已经运行时启动,Android 会将其置于前台并调用 onNewIntent() 并传入新的 Intent。您应该重写此方法并对传递的Intent 执行某些操作(将其保存在成员变量中或从中提取您想要的内容或其他内容)。之后Android会调用onResume()

调用getIntent() 将始终返回最初用于启动活动的Intent

【讨论】:

  • 虽然这回答了这个问题,但我不得不说我有点困惑。根据developer.android.com/guide/topics/manifest/…“每次有一个“标准”活动的新意图时,都会创建一个新的类实例来响应该意图。每个实例处理一个意图。因此,如果我希望我的活动是 singleTop,则应该为每个意图启动一个新实例,但事实并非如此。
  • 我接受答案,因为它帮助我朝正确的方向挖掘,但官方文档仍然让我感到困惑。我不明白为什么“标准”启动模式在这里不起作用。
  • 一般来说,文档说的是真的。但是,文档中的其他地方描述了一些要点。如果您使用FLAG_ACTIVITY_NEW_TASK 启动一个 Intent(当您使用 YouTube 的 SHARE 操作时可能在此处完成),并且正在启动的 Activity 是现有任务的根 Activity(在这种情况下是),那么现有任务仅被带到前台(没有其他任何事情发生)。这记录在这里:developer.android.com/reference/android/content/…
  • 这就是发生的情况,例如,当您将应用程序放在免费环境中并单击主屏幕上的应用程序图标(或从最近任务列表中选择您的应用程序)时。 Android 通过为根 Activity 创建 Intent 并设置 FLAG_ACTIVITY_NEW_TASK 来启动应用程序。如果应用程序尚未运行,它将启动,但如果它已经在运行,您不想让它再次启动。您只希望 Android 将现有任务带到前台。我希望你现在更清楚了。
  • 您可以通过为 SEND 操作创建一个单独的 Activity 来使这项工作更好(并更好地控制其工作方式)。您通过将 SEND 操作与根 (LAUNCHER) 操作混合在一起使这变得复杂。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-30
  • 1970-01-01
相关资源
最近更新 更多