【问题标题】:startActivity() from BroadcastReceiver来自 BroadcastReceiver 的 startActivity()
【发布时间】:2010-10-03 13:08:47
【问题描述】:

我正在尝试使用 onPause() 方法中实现的以下 BroadcastReceiver 在充电时自动启动我的夜间应用程序:

BroadcastReceiver test = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        unregisterReceiver(this);
        Intent i = new Intent(context, NightClock.class);
        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(i);   
    }           
};
registerReceiver(test, new IntentFilter(Intent.ACTION_POWER_CONNECTED));

插入 USB 电缆时会触发 onReceive() 方法,但活动不会启动。但是日志显示了这一点:

I/ActivityManager(   79): Starting activity: Intent { flg=0x10000000 cmp=com.meins.nightclock/.NightClock }

任何想法为什么日志显示活动已启动,但没有任何反应?

【问题讨论】:

  • 请使用 LogCat 中的更多内容更新您的问题——这一行之前的几行和这一行之后的十几行。另外,为什么FLAG_ACTIVITY_NEW_TASK?另外,当 ACTION_POWER_CONNECTED 发生时,注册此 BroadcastReceiver 的活动是否仍然存在?
  • 连接电源后,LogCat 中没有更多线路。 BroadcastReceiver 在它应该启动的同一个活动中注册。此活动仍在后台运行(LogCat 应用程序已被置于前面)。如果此活动在任务管理器中被终止,BroadcastReceiver 似乎根本不会触发。这种自动启动我的应用的方法从一开始就错了吗?

标签: android android-activity broadcastreceiver


【解决方案1】:

您已将上下文作为参数传递给 onRecieve() 方法,因此只需使用:

 @Override
public void onReceive(Context context, Intent intent) {
    //start activity
    Intent i = new Intent();
    i.setClassName("com.test", "com.test.MainActivity");
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(i);
}

它可以工作,当然你必须将包和活动类名称更改为你自己的。

【讨论】:

  • 为什么投反对票?这很糟糕吗?它帮助了我,所以 +1,因为我找不到任何说这是一种不好的方法。
  • @Mafro34 我刚刚尝试了相同的方法,我认为它不理想的原因是他设置的标志。因为除非这是您想要的(运行新任务),否则它可能会严重干扰您的应用程序逻辑 - 无论如何它都与我的逻辑有关。因此,除非这是您想要的,否则我建议您寻找另一种方法。
  • @AgentKnopf 看起来您别无选择:(来自developer.android.com/reference/android/content/…):“请注意,如果此方法是从 Activity 上下文外部调用的,则 Intent 必须包含FLAG_ACTIVITY_NEW_TASK 启动标志。这是因为,如果不从现有 Activity 启动,则没有现有任务可以放置新 Activity,因此需要将其放置在自己的单独任务中。”
  • FLAG_ACTIVITY_NEW_TASK 在应用程序未处于 forgound/inactive 状态时运行良好。我注意到在 MI 设备中,有一个额外的设置“在后台运行时显示弹出窗口”,当我设置它运行良好时,默认情况下它是关闭的。
【解决方案2】:

如果您的目标是希望在发送ACTION_POWER_CONNECTED 广播时启动NightClock,那么您使用BroadcastReceiver 的方法很好。但是,不要从活动中注册它。而是在清单中注册它:

<receiver android:name=".OnPowerReceiver">
        <intent-filter>
                <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
        </intent-filter>
</receiver>

然后,将您的 BroadcastReceiver 作为公共 Java 类(这里命名为 OnPowerReceiver,尽管您可以随意调用它),并将其命名为 startActivity()

请记住,用户可能不希望您这样做。除了启动“夜间时钟”之外,还有许多其他情况可以将手机连接到电源。我谦虚地建议您让用户通过主屏幕开始您的活动。

【讨论】:

  • 我已经在清单中注册了BroadcastReceiver,就像您在onReceive() 方法中使用此调用所说的那样:context.startActivity(new Intent(context, NightClock.class)); 但是当我将手机连接到电源时没有任何反应。如果我将Log.d(this.toString(), "trying to start app ..."); 添加到方法中,甚至不会添加日志条目。
  • @Gubbel:哎呀。试试&lt;action android:name="android.intent.action.ACTION_POWER_CONNECTED" /&gt;。大多数时候,他们在字符串中没有ACTION_,但显然他们在这个字符串中。
  • 如果应用程序从任务列表中删除会怎样?此处消息不会在您的广播接收器上触发。它将由“click_action”参数处理。
  • 你需要设置标志setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
【解决方案3】:

来自Docs

不要从广播接收器开始活动,因为用户体验不和谐;特别是如果有不止一个接收器。相反,请考虑显示通知。

【讨论】:

  • 他们在许多默认应用程序(如警报和来电)中覆盖了这一点。因此,如果用户希望这发生,这是他的电话。而你的回答并没有回答问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-19
相关资源
最近更新 更多