【问题标题】:How to check is app in foreground from service?如何从服务中检查应用程序是否在前台?
【发布时间】:2016-12-23 05:56:01
【问题描述】:

只有当应用程序不在前台时,我才需要向用户显示通知。这是我的公共类 MyFirebaseMessagingService 扩展

FirebaseMessagingService {
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        if(applicationInForeground()) {
            Map<String, String> data = remoteMessage.getData();
            sendNotification(data.get("title"), data.get("detail"));
        }

    }

需要实现applicationInForeground()方法

【问题讨论】:

标签: android android-service


【解决方案1】:

我只报告了@bompfanswer 的 Kotlin 版本

import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent
import androidx.lifecycle.ProcessLifecycleOwner
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage

class AppFirebaseMessagingService : FirebaseMessagingService(), LifecycleObserver {

    private var isAppInForeground = false

    override fun onCreate() {
        super.onCreate()
        ProcessLifecycleOwner.get().lifecycle.addObserver(this)
    }

    override fun onDestroy() {
        super.onDestroy()
        ProcessLifecycleOwner.get().lifecycle.removeObserver(this)
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun onForegroundStart() {
        isAppInForeground = true
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun onForegroundStop() {
        isAppInForeground = false
    }

    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        if (isAppInForeground) {
            // do foreground stuff on your activities
        } else {
            // send a notification
        }
    }
}

【讨论】:

    【解决方案2】:

    您可以从 android 系统服务控制正在运行的应用程序进程。试试这个:

    private boolean applicationInForeground() {
        ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> services = activityManager.getRunningAppProcesses();
        boolean isActivityFound = false;
    
        if (services.get(0).processName
                .equalsIgnoreCase(getPackageName()) && services.get(0).importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
            isActivityFound = true;
        }
    
        return isActivityFound;
    }
    

    祝你好运。

    【讨论】:

    • 大家好,我是安卓新手。我面临同样的问题,但坚持如何导入 getPackageName()。 getPackageName() 是否来自上下文?我在服务时如何访问上下文?
    • 我的另一个问题是,在 Android oreo 之前,这段代码是否可以在 Android jellybean 上运行?谢谢
    • 该功能不适用于 Android 7.0 服务。
    • 最好也检查 services.get(0).importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND
    【解决方案3】:

    您也可以尝试使用Android Jetpack lifecycle components

    public class AppFirebaseMessagingService extends FirebaseMessagingService implements LifecycleObserver {
    
        private boolean isAppInForeground;
    
        @Override
        public void onCreate() {
            super.onCreate();
    
            ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
    
            ProcessLifecycleOwner.get().getLifecycle().removeObserver(this);
        }
    
        @OnLifecycleEvent(Lifecycle.Event.ON_START)
        public void onForegroundStart() {
            isAppInForeground = true;
        }
    
        @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
        public void onForegroundStop() {
            isAppInForeground = false;
        }
    
        @Override
        public void onMessageReceived(RemoteMessage remoteMessage) {
            if(isAppInForeground) {
                // do foreground stuff on your activities
            } else {
                // send a notification
            }
        }
    }
    

    请参阅 here 如何导入必要的依赖项,因为生命周期不是标准 Android SDK 的一部分。

    【讨论】:

    • 为了使用它必须添加android.arch.lifecycle:extensionsandroid.arch.lifecycle:compiler的实现,请将其添加到您的答案中
    • @ZhebzhikBabich,我添加了 Android 文档的链接。
    • @ekashking,它是 this 类,确保在类路径中导入了正确的包。
    • 这就是我的猜测。我认为答案应该首先提到这一点。
    • 嗯,它是 Jetpack 支持库的一部分,添加支持库对于 Android 开发来说是相当标准的。我会澄清我的答案。
    【解决方案4】:

    在 2016 年 Google I/O 上,我发表了一次演讲,其中一个主题是 Firebase 如何检测您的应用是否在前台。您可以为此使用ActivityLifecycleCallbacks,方法是为应用程序中启动的每个活动增加一个计数器,然后为每个停止的活动减少它。如果计数器 > 1,则您的应用程序位于前台。演讲的相关部分可以在 YouTube here 上看到。

    【讨论】:

    • 非常感谢您分享该视频!
    • @doug-stevenson 为什么不在 FirebaseMessagingService 中公开这个方法,让安卓程序员过上更好的生活呢?更一般地说,为什么 com.google.firebase:** 不是开源的?
    • 我是通过弱引用进行此操作的,like this,您对此有何看法?
    • 你不是说计数器 > 0 :-)
    猜你喜欢
    • 2019-01-20
    • 1970-01-01
    • 1970-01-01
    • 2016-09-21
    • 1970-01-01
    • 2014-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多