是否可以在 Android 11 中启动时启动 Activity?

Is it possible to launch an Activity on startup in Android 11?

在 Pixel 3a 上测试(模拟器和物理设备(我用过的设备))API 30 (11.0)。

回购: https://github.com/amdreallyfast/AndroidStartOnBootExample

目标: 我试图在启动时启动 android 应用程序,但失败了。

注意:我很清楚不应该对为一般 public 设计的应用程序执行此操作。这不是那个。目前,这只是个人项目的概念探索。更大的目标是修补用过的 Pixel 3a 并将其变成家庭实用设备。我不想每次需要打开应用程序时都手动启动它,而是希望它自动启动,所以我试图找到一种在启动时启动应用程序的方法。

另请注意:因为这是一个在启动时启动的项目,所以我无法使用调试器来完成大部分工作,而不得不依赖通知来检测进度。

进度: 我有一个 BroadcastReceiver,它通过启动服务来响应 BOOT_COMPLETED 意图。该服务的 onCreate(...) 函数创建了一个简单的意图来启动另一个应用程序(目前,只是 Google 地图,无需安装额外的软件即可使用)。

我还有 MainActivity,这是一个简单的程序,它有一个按钮,使用 intent 来启动相同的服务。我用它来比较在启动时启动服务和从已经 运行 activity.

启动服务之间的行为

已尝试设置意图标志 Intent.FLAG_ACTIVITY_NEW_TASK

问题: Google 地图在启动期间调用时不会从服务启动。我知道该服务的代码已正确设置以启动地图意图,因为启动 MainActivity 并按下按钮将启动该服务,然后启动 Google 地图就好了。我也知道启动时的代码 运行 已经到达启动地图意图的地步,因为通知如此指示。

我注意到不工作和工作之间的唯一区别似乎是服务启动的方式。

文档: 我找到了这个 android 文档页面:https://developer.android.com/guide/components/activities/background-starts。它说(部分):

Apps running on Android 10 or higher can start activities only when one or more of the following conditions are met:

  • The app has a visible window, such as an activity in the foreground.
  • <other possible conditions>

为什么这个不启动?我是不是理解错了? Google 大部分地图 当然 有一个可见的 window,所以我希望能够启动它。

注意:同样,我不打算向一般人发布我的应用程序 public。这只是给我的。

The larger goal is to tinker with a used Pixel 3a and turn it into a home utility device

编写启动器应用程序(即让您的 activity 响应 ACTION_VIEW/CATEGORY_HOME)并将其设置为默认启动器。它会在 phone 启动时自动启动,就像您当前的默认启动器一样。而且,您可以在自己的启动器中放置一个按钮或其他东西,通过显式 Intent.

启动真正的启动器

这将允许您跳过 on-boot 接收器和服务。

Why doesn't this start?

您不符合背景 activity 开始。

Google Maps most certainly has a visible window, so I am expecting to be able to start it.

首先,大概它在启动后没有可见的window。

其次,您没有编写 Google 地图应用,Google 地图也没有尝试从后台启动 activity。您正在编写自己的应用程序,并且您自己的应用程序正在尝试从后台启动 activity。而且,由于您自己的应用程序在启动后没有可见的 window,因此它不符合“应用程序具有可见的 window”规则下的背景 activity 启动条件。​​

根据@CommonsWare 的回答,这是我的 activity 在我的应用清单文件中的配置(只是为了完整起见):

<activity
    android:name="com.example.androidstartonboot.MainActivity"
    android:launchMode="singleTask"
    android:stateNotNeeded="true"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <action android:name="android.intent.action.VIEW" />

        <category android:name="android.intent.category.HOME" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

注意:严格来说,launchModestateNotNeeded并不是MainActivity启动成功所必需的,但我的理解是将它们添加到启动器是一种很好的做法。文档:https://developer.android.com/guide/topics/manifest/activity-element

启用:

  1. 运行 要安装的应用程序(或 运行 调试器)。
  2. 按“主页”按钮(Android 11 上的实心点)。 Android 应该提供一个选项,让应用程序可以用来响应 LAUNCHER 意图。应该有两个选项:“Pixel Launcher”(Android 默认值)和 MainActivity 的应用如上配置。
  3. Select 您的应用并选择“始终使用此应用”。

现在,每次您按下“主页”按钮时,您的应用程序应该 运行。

注意:要将“像素启动器”恢复为默认启动器:

  • 从顶部向下滑动
  • -> 设置
  • -> 应用和通知
  • -> 所有应用程序
  • -> 像素启动器
  • -> 高级
  • -> 主页(此时应该说“否”)
  • -> <选择“像素启动器”>

这是在 Android Studio Bumblebee | 2021.1.1 Patch 2 的 Kotlin 项目中测试的。

注意:如果还有一个 BroadcastReceiver 清单正在配置以响应意图过滤器 <action android:name="android.intent.action.BOOT_COMPLETED"。我尝试过这个。禁用 BroadcastReceiver 允许它工作。 Re-enabling 它阻止 MainActivity 在启动时启动。所以需要在这个启动器工作之前评论 out/removed。