如何从服务中检查应用程序是否在前台?

24

如果应用程序不在前台,我需要向用户显示通知。这是我的公共类MyFirebaseMessagingService:

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

    }

需要实现applicationInForeground()方法


1
请查看以下链接:https://dev59.com/LnI95IYBdhLWcg3www2Y - Rachit Solanki
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Vladyslav Matviienko
您在应用程序中使用了多少个活动? - Mayur Raval
FCM数据消息有两种类型:后台数据消息和前台显示消息。您必须使用不同的配置来接收后台或前台消息。请参考此处:https://dev59.com/JVoU5IYBdhLWcg3wM08H - Praveen
请查看Sam的回答:https://dev59.com/tm865IYBdhLWcg3wUs7z 基于该答案的Github项目:https://github.com/seguri/GetForegroundActivity - Milon
谷歌的解决方案在这里:https://dev59.com/KHA65IYBdhLWcg3wuhIR#48767617 - StepanM
4个回答

27

你可以通过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;
}

祝你好运。


你好,我是Android新手。我遇到了同样的问题,但卡在如何导入getPackageName()上。getPackageName()是从context中获取的吗?我在服务中如何访问context? - Pewh Gosh
还有一个问题,这段代码能在 Android Jellybean 到 Android Oreo 上运行吗?谢谢。 - Pewh Gosh
3
该函数在Android 7.0的服务中无法正常工作。 - Shajeel Afzal
1
最好还是检查 services.get(0).importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND。 - Dobry

22
在2016年的Google I/O大会上,我做了一个演讲,其中一个话题是Firebase如何检测你的应用程序是否在前台运行。你可以使用ActivityLifecycleCallbacks来实现这一点,通过为每个启动的活动增加计数器,然后为每个停止的活动减少计数器。如果计数器大于1,则表示你的应用程序在前台运行。演讲中相关部分可以在YouTube here观看。

1
非常感谢您分享那个视频! - Bilal Soomro
13
为什么不将这种方法公开在FirebaseMessagingService中,以便Android程序员拥有更好的体验?另外,为什么com.google.firebase:**不是开源的? - rashtao
我正在使用弱引用来完成此操作,像这样,你对此有何想法? - Sarthak Mittal
1
难道你的意思不是 counter > 0 吗 :-) - Ido Sofi

20

你也可以尝试使用Android Jetpack生命周期组件

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
        }
    }
}

请查看此处,了解如何导入必要的依赖项,因为Lifecycle不是标准Android SDK的一部分。


1
为了使用 android.arch.lifecycle:extensionsandroid.arch.lifecycle:compiler 的实现,必须将它们添加到您的答案中,请添加。 - Eugene Babich
1
@ZhebzhikBabich,我已经添加了一个链接到Android文档。 - bompf
@ekashking,这是这个类,请确保在您的类路径中导入了正确的包。 - bompf
那正是我猜测的。我认为答案应该从首先提到开始。 - ekashking
好的,这是Jetpack支持库的一部分,添加支持库对于Android开发来说是相当标准的。我会澄清我的答案。 - bompf

4

我刚刚报告了一个Kotlin版本的答案,这是@bompf回答

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
        }
    }
}

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