Android 检查活动是否正在从服务运行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12172092/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 09:58:43  来源:igfitidea点击:

Check if Activity is running from Service

androidandroid-activityandroid-service

提问by Taranfx

How can a Servicecheck if one of it's application's Activityis running in foreground?

如何Service检查其中一个应用程序Activity是否在前台运行?

回答by Rasel

Use the below method with your package name. It will return true if any of your activities is in foreground.

将以下方法与您的包名称一起使用。如果您的任何活动在前台,它将返回 true。

public boolean isForeground(String myPackage) {
    ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
    List<ActivityManager.RunningTaskInfo> runningTaskInfo = manager.getRunningTasks(1); 
    ComponentName componentInfo = runningTaskInfo.get(0).topActivity;
    return componentInfo.getPackageName().equals(myPackage);
}

Update:

更新:

Add Permission:

添加权限:

<uses-permission android:name="android.permission.GET_TASKS" />

回答by eiran

Use SharedPreferences to save the status of your app in onResume, onPause etc.

使用 SharedPreferences 将您的应用程序的状态保存在 onResume、onPause 等中。

like so:

像这样:

 @Override
public void onPause() {
    super.onPause();
    PreferenceManager.getDefaultSharedPreferences(this).edit().putBoolean("isActive", false).commit();
}

@Override
public void onDestroy() {
    super.onDestroy();
    PreferenceManager.getDefaultSharedPreferences(this).edit().putBoolean("isActive", false).commit();
}

@Override
public void onResume() {
    super.onResume();
    PreferenceManager.getDefaultSharedPreferences(this).edit().putBoolean("isActive", true).commit();
}

and then in the service:

然后在服务中:

if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("isActive", false)) {
            return;
}

i used both onPause and onDestroy because sometimes it jumps straight to onDestroy:) it's basically all voodoo

我同时使用了 onPause 和 onDestroy 因为有时它会直接跳转到 onDestroy :) 基本上都是伏都教

anyway, hope that helps someone

无论如何,希望能帮助某人

回答by Comtaler

Starting from Lollipop, getRunningTasksis deprecated:

从 Lollipop 开始,getRunningTasks已弃用:

 * <p><b>Note: this method is only intended for debugging and presenting
 * task management user interfaces</b>.  This should never be used for
 * core logic in an application, such as deciding between different
 * behaviors based on the information found here.</p>
 *
 * @deprecated As of {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this method
 * is no longer available to third party applications.
 * <p><b>Note: this method is only intended for debugging and presenting
 * task management user interfaces</b>.  This should never be used for
 * core logic in an application, such as deciding between different
 * behaviors based on the information found here.</p>
 *
 * @deprecated As of {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this method
 * is no longer available to third party applications.

One way to do this is to bind to the service on app start. Then: 1. If you need to check any of the app's activity is running, you can create a base class for your activities and override onPause and onResume. In onPause, call a service method to let it know it is on the background. In onResume, call a service method to let it know it is on the foreground. 2. If you only need to do this on some specific activity, just override onResume and onPause on those activities or create a base activity for those activities.

一种方法是在应用程序启动时绑定到服务。然后: 1. 如果您需要检查任何应用程序的活动是否正在运行,您可以为您的活动创建一个基类并覆盖 onPause 和 onResume。在 onPause 中,调用一个服务方法让它知道它在后台。在 onResume 中,调用一个服务方法让它知道它在前台。2. 如果您只需要对某些特定活动执行此操作,只需覆盖这些活动的 onResume 和 onPause 或为这些活动创建基础活动。

回答by ForceMagic

There is one flaw to most of the answers above, if your activity has some feature which triggers another activity over the top, e.g. sending an email

上面的大多数答案都有一个缺陷,如果您的活动具有某些功能会触发另一项活动,例如发送电子邮件

enter image description here

在此处输入图片说明

the topActivitywill not return your package name but instead the Android activity selector package name.

topActivity不会返回你的包的名字,而是Android的活动选择包名。

Thus, it is better to check for the baseActivityinstead of the topActivity.

因此,最好检查baseActivity而不是topActivity

public boolean isMainActivityRunning(String packageName) {
    ActivityManager activityManager = (ActivityManager) getSystemService (Context.ACTIVITY_SERVICE);
    List<RunningTaskInfo> tasksInfo = activityManager.getRunningTasks(Integer.MAX_VALUE); 

    for (int i = 0; i < tasksInfo.size(); i++) {
        if (tasksInfo.get(i).baseActivity.getPackageName().toString().equals(packageName)
            return true;
    }

    return false;
} 

回答by nnyerges

Erianhas the correct answer, but its not safe to use "getDefaultSharedPreferences". When you start a Service it use a differente instance that the Activity. Any changes of preferences in the activity, doesnt update the default shared preferences in the Service. So i will change Erian code with ".getSharedPreferences" like this:

Erian有正确的答案,但使用“getDefaultSharedPreferences”并不安全。当您启动服务时,它使用与活动不同的实例。活动中首选项的任何更改都不会更新服务中的默认共享首选项。因此,我将使用“.getSharedPreferences”更改 Erian 代码,如下所示:

In Activity:

在活动中:

    @Override
    public void onPause() {
        super.onPause();
        getApplicationContext().getSharedPreferences("preferences", MODE_MULTI_PROCESS).edit().putBoolean("isActive", false).commit();;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        getApplicationContext().getSharedPreferences("preferences", MODE_MULTI_PROCESS).edit().putBoolean("isActive", false).commit();
    }

    @Override
    public void onResume() {
        super.onResume();
        getApplicationContext().getSharedPreferences("preferences", MODE_MULTI_PROCESS).edit().putBoolean("isActive", false).commit();
    }

In Service:

服务中:

    if (getApplicationContext().getSharedPreferences("preferences", MODE_MULTI_PROCESS).getBoolean("isActive", false)) {
        return;
    }

回答by Veeresh Charantimath

With Android Architecture Components it is quite straight forward to check this

使用 Android 架构组件,检查这一点非常简单

annotationProcessor 'android.arch.lifecycle:compiler:1.1.1'
implementation 'android.arch.lifecycle:extensions:1.1.1'

The lifecycle observer class, keeping a pref flag

生命周期观察者类,保留一个 pref 标志

public class AppLifecycleObserver implements LifecycleObserver {

public static final String TAG = "AppLifecycleObserver";

@OnLifecycleEvent(Lifecycle.Event.ON_START)
void onEnterForeground() {
    Log.d(TAG, "onEnterForeground");
    PreferencesUtils.save(Constants.IN_FOREGROUND, true);
}

@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
void onEnterBackground() {
    Log.d(TAG, "onEnterBackground");
    PreferencesUtils.save(Constants.IN_FOREGROUND, false);
  }
}

Application Class observers the lifecycle

应用程序类观察者生命周期

public class App extends Application {


private static App instance;

public static App getInstance() {
    return instance;
}

@Override
public void onCreate() {
    super.onCreate();

    AppLifecycleObserver appLifecycleObserver = new AppLifecycleObserver();
    ProcessLifecycleOwner.get().getLifecycle().addObserver(appLifecycleObserver);
}

Now, you can use the Pref flag to check anywhere you please.

现在,您可以使用 Pref 标志在任何您喜欢的地方进行检查。

回答by VendettaDroid

I think you can getRunninTasks on Android and check with your packagename if the task is running or not.

我认为您可以在 Android 上 getRunninTasks 并检查您的包名是否正在运行任务。

public boolean isServiceRunning() { 

ActivityManager activityManager = (ActivityManager)Monitor.this.getSystemService (Context.ACTIVITY_SERVICE); 
List<RunningTaskInfo> services = activityManager.getRunningTasks(Integer.MAX_VALUE); 
isServiceFound = false; 
for (int i = 0; i < services.size(); i++) { 
    if (services.get(i).topActivity.toString().equalsIgnoreCase("ComponentInfo{com.lyo.AutoMessage/com.lyo.AutoMessage.TextLogList}")) {
        isServiceFound = true;
    }
} 
return isServiceFound; 
} 

回答by Abdulla

Use the below method to get full class name (package+class name) of the current activity and check if it is equal to full class name (package+class name) of activity you want:

使用以下方法获取当前活动的完整类名(包+类名),并检查它是否等于您想要的活动的完整类名(包+类名):

 public String getCurrentClass() {

    ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
    List<ActivityManager.RunningTaskInfo> runningTaskInfo = manager.getRunningTasks(1);

    ComponentName componentInfo = runningTaskInfo.get(0).topActivity;
    String className = componentInfo.getClassName();
    return className;
 }