如何从服务(Service)启动(Activity)?

40

一个Service是否可以启动另一个Activity?如果可以,我们如何实现呢?

4个回答

75

android.app.Serviceandroid.app.Context 的子类,因此您可以直接使用 startActivity。但是,由于您在任何活动之外启动它,因此您需要在意图上设置 FLAG_ACTIVITY_NEW_TASK 标志。

例如:

Intent i = new Intent();
i.setClass(this, MyActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);

这里的 this 是指您的服务。


1
这很好,但每次活动启动时都会像新启动的活动一样。而且这种调用只能工作一次。或者我错过了什么!? - uzay95
@MarcinGil,你知道这是有意为之的行为吗?换句话说,你知道Google工程师是否设计了服务以能够在没有用户交互的情况下打开一个活动,并且这个过程总是顺畅的吗? - MikeIsrael
@MikeIsrael 我相信是这样的。想象一下,后台运行的系统服务无法在来电时显示接受/拒绝活动。由于您是服务的开发人员,并且知道要显示什么活动,这完全取决于您。您可以使用从应用程序启动的服务执行某些操作,例如在通知栏中更新状态并在单击时启动应用程序。 - Marcin Gil
@MarcinGil,这更像是我的问题。既然已经有了一种机制(通知)来请求打开应用程序,那么直接启动活动是否会成为一种从启动应用程序的过程中删除用户输入表单的黑客方式? - MikeIsrael
@MikeIsrael 不需要黑客技巧。你可以像回答中一样从服务中调用 startActivity()。何时调用取决于你。举个快速的例子:实现一个注册广播的服务,然后使用闹钟发送此广播。在广播处理程序中启动所需的活动。这样,您可以启动服务一次,在应用关闭后让其保持活动状态,并在某些触发器下自动打开某些活动,无需进一步用户交互。 - Marcin Gil
显示剩余4条评论

21
即使框架允许您从服务启动活动,这可能不是一个合适的解决方案。原因是在服务希望与用户交互时,服务任务可能或可能不是用户关注的焦点。打断用户当前正在进行的操作被认为是不良的设计形式,尤其是来自一些应该在后台运行的东西。
因此,您应该考虑使用具有 PendingIntent 的通知和通知服务,在用户决定调查时启动所需的活动。将其视为延迟满足。

1
讲得好!我讨厌闹钟按照我作为用户告诉它要做的事情打扰我的睡眠...允许这样做的目的是为了让最终用户自行决定他们认为重要的事情...如果你担心在用户请求打开特定应用程序的那一刻打断用户正在进行的事情,那么你就没有考虑到用户的需求和愿望。 - me_
1
回答电话是一个完美的例子......你认为与其直接接听电话,你应该下拉通知区域,点击电话应用程序通知,然后选择接听、发送未接来电原因或忽略呼叫?这对用户来说更方便了吗? - me_

8
我曾经遇到过一个问题,就是从服务启动一个活动时,由于缺少FLAG_ACTIVITY_NEW_TASK意图标志而无法启动该活动。

不知道为什么,但我可以在Service中直接启动Activity而不需要任何标志,它可以正常工作。 - Siddhpura Amit

7
这肯定会解决你的问题。
Intent intent = new Intent();
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ComponentName cn = new ComponentName(this, TaxiPlexer.class);
intent.setComponent(cn);
startActivity(intent);

你好, 我在使用FCM服务时遇到了一个问题,即当应用程序关闭时启动活动。 上述代码仅在应用程序已经打开时起作用。 请帮助我解决这个问题,使得可以从后台运行的服务中打开应用程序。 - Dipanki Jadav
@DipankiJadav 面对相同的问题,你找到解决方法了吗? - Aparna

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