【问题标题】:Either show notification or react in application显示通知或在应用程序中做出反应
【发布时间】:2015-04-29 17:14:48
【问题描述】:

我有一个后台服务在做一些工作——按时间间隔检索用户位置(使用startService 启动)。一旦达到特殊条件,我想做以下事情:

  1. 如果应用程序在前台,则启动特定活动。
  2. 如果应用程序不在前台或未关闭,则显示将在点击时启动所需活动的通知。

例如,我知道如何显示通知以及如何使用广播接收器处理来自服务器的意图。但是如何确定我的应用程序是否在前台?或者您可以提出完整的更好的解决方案?

【问题讨论】:

    标签: java android


    【解决方案1】:

    我确定我的应用程序是否在前台

    有几种方法可以找出前面的内容,但我实际上更喜欢自己跟踪它(因为这有助于我在需要时应用额外的逻辑)。另外,这是非常简单的任务。要做到这一点,您需要在某处使用基于int 的静态计数器(如果您有一个对象,则可以使用您的Application 对象,或者在其他地方拥有它,这并不重要)。在每个ActivityonResume() 中,您将计数器加一,在onPause() 中,您将其减一。如果计数器等于0,那么您的任何活动都不是在前台,所以从您的角度来看,您在后台并发布通知。为简单起见,我总是在我的 ActivityBase 课程中这样做,我的所有活动都会扩展。

    如果您不想自己跟踪,可以使用ActivityManager 来查看当前在前台的情况:

    public boolean isAppInForeground() {
        ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
        List<RunningTaskInfo> services = am.getRunningTasks(Integer.MAX_VALUE);
    
        return (services.get(0).topActivity.getPackageName().toString()
                            .equalsIgnoreCase(getPackageName().toString()));
     }
    

    但这需要在您的清单中输入&lt;uses-permission android:name="android.permission.GET_TASKS" /&gt;,因此并不总是受欢迎的。

    【讨论】:

    • 还有几个问题。我可以确定静态字段在应用程序和服务生命周期范围之间共享吗?如果应用程序完全关闭但服务正在运行怎么办?另外,如果应用程序崩溃了怎么办?在广播接收器中执行与打开的应用程序相关的操作是个好主意吗?
    • 我还添加了基于ActivityManager 的方法。至于您的问题:如果您的应用程序使用任何对象子类,您可以使用 Application 对象子类,因为每个应用程序总是有一个 Application 对象。或者,您可以将您的计数器保留在 Singleton 中,但如果您在应用程序中使用 Threads,请see this question
    • 如果您正在运行多个进程,则每个应用程序一个应用程序对象不适用。如果应用程序类和服务在同一个进程中,那么它们之间将可以使用相同的静态对象。如果与应用程序在同一进程中的服务正在运行,则应用程序也将运行。响应广播很好,但应该注意它们的安全问题,而且回调必须在 5 秒内响应,因此需要将任何繁重的工作交给服务
    • 顺便说一句,使用 getRunningTasks 和朋友被认为是不好的做法,code.google.com/p/android-developer-preview/issues/detail?id=29
    【解决方案2】:

    Marcin 的答案的替代方法是将您的活动绑定和取消绑定到服务。这将允许在该绑定存在时服务和活动之间进行通信,并且服务将知道能够处理该场景的活动当前是否可用 - 例如。如果用户处于某个重要过程的中间(例如接受 T&C/EULA 或其他),您可能不想直接启动 Activity,因此服务可以告诉 Activity 发生了事件,但 Activity 可以响应事件正确。

    【讨论】:

    • 您的意思是同时使用startServicebinsService 启动服务,如果活页夹处于活动状态,则向其发送信息并显示通知?
    • 是的,这就是我的意思。仅绑定的服务只有在绑定了某些内容时才会保持活动状态,因此如果您希望服务在 ui 不在屏幕上时处于活动状态,请启动 Activity,然后也绑定到它。请注意,必须明确停止已启动的服务,因此如果它正在做任何耗尽电池电量的事情,您应该有一个超时或其他东西来确保它不会一直运行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多