安卓启动器:在启动器中按下Home键返回默认屏幕

5
在默认的Android启动器中,当您在另一个活动中按下主页键时,将启动启动器。在启动器中再次按下主页键将重置为默认主屏幕页面。我不明白这是如何完成的。Android发送相同的意图,无论启动器是否在前台。用户应用程序也无法拦截主页键。
有没有一种方法可以实现这个功能?
2个回答

13

无论启动器是否在前台,Android都会发送相同的意图。

正确。

用户应用程序也无法拦截Home键。

正确。

我不明白这是如何实现的。

如果调用 startActivity() 将导致 Intent 被传递到现有的活动实例,则不会创建新实例(按定义),而是使用 onNewIntent() 调用现有实例而不是 onCreate()

对于主屏幕来说,通常真正的主屏幕活动将在清单中使用 android:launchMode="singleTask"android:launchMode="singleInstance",例如:

    <activity
        android:name="Launcher"
        android:launchMode="singleTask"
        android:clearTaskOnLaunch="true"
        android:stateNotNeeded="true"
        android:theme="@style/Theme"
        android:screenOrientation="nosensor"
        android:windowSoftInputMode="stateUnspecified|adjustPan">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.HOME"/>
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.MONKEY" />
        </intent-filter>
    </activity>

(来自 AOSP中的旧版启动器

然后,活动可以实现onNewIntent()来执行某些操作。在上述旧版启动器的情况下,它的onNewIntent()包括

            if (!mWorkspace.isDefaultScreenShowing()) {
                mWorkspace.moveToDefaultScreen();
            }

这个功能可能会使UI在主屏幕活动管理的一组屏幕中,如果用户正在查看其他屏幕,则将其动画返回到默认屏幕。
另一种触发onNewIntent()的方法是通过在调用startActivity()时选择性地包含适当的标志(例如FLAG_ACTIVITY_REORDER_TO_FRONT)在Intent中来实现,而不是使用android:launchMode。

非常感谢提供的信息。我尝试了另一种方法,使用FLAG_ACTIVITY_REORDER_TO_FRONT和FLAG_ACTIVITY_SINGLE_TOP来触发onNewIntent(),但是onNewIntent()没有被触发。我是否遗漏了什么?谢谢。 - kevdliu
@kevdliu:嗯......试试FLAG_ACTIVITY_CLEAR_TOPFLAG_ACTIVITY_SINGLE_TOP的组合吧。我知道这个方法是可行的,因为我在一些NFC示例应用程序中使用它来获取NFC标签事件并将其传递给正在运行的活动(而不是启动另一个副本)。我以为FLAG_ACTIVITY_REORDER_TO_FRONT会有同样的效果。请记住,只有当活动已经存在时,onNewIntent()才会被调用--如果您使用了finish()或BACK按钮来关闭活动,则必须创建一个新的活动并调用onCreate()而不是onNewIntent() - CommonsWare
1
谢谢您的回复。我接受了您的答案,因为它回答了我的原始问题。但实际上,我正在尝试编写一个模拟主页键启动行为的主屏幕启动器应用程序。如果您能帮助我,我将不胜感激。我使用getLaunchIntentForPackage()获取了主屏幕的启动意图,添加了标志,并使用startactivity()启动了它。然而,启动器的onNewIntent()没有被调用。 - kevdliu
@kevdliu:你需要查看启动器的源代码,因为我不知道它可能在做什么。如果你没有这样的源代码,那么你可能就没办法了。 - CommonsWare
1
我认为决定因素是: if ((intent.getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) - kevdliu

5
更具体地说,执行以下操作
@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    if ((intent.getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) !=
            Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) {
        goHome();
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接