如何Service
检查其中一个应用程序Activity
是否在前台运行?
9 回答
将以下方法与您的包名称一起使用。如果您的任何活动在前台,它将返回 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);
}
更新:
添加权限:
<uses-permission android:name="android.permission.GET_TASKS" />
使用 SharedPreferences 将应用的状态保存在 onResume、onPause 等中。
像这样:
@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();
}
然后在服务中:
if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("isActive", false)) {
return;
}
我同时使用了 onPause 和 onDestroy,因为有时它会直接跳到 onDestroy :) 它基本上都是巫术
无论如何,希望对某人有所帮助
从 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.
一种方法是在应用启动时绑定到服务。然后: 1. 如果您需要检查应用程序的任何活动是否正在运行,您可以为您的活动创建一个基类并覆盖 onPause 和 onResume。在 onPause 中,调用一个服务方法让它知道它在后台。在 onResume 中,调用一个服务方法让它知道它在前台。2. 如果您只需要对某些特定活动执行此操作,只需在这些活动上覆盖 onResume 和 onPause 或为这些活动创建基础活动。
Erian有正确的答案,但使用“getDefaultSharedPreferences”并不安全。当您启动服务时,它使用与 Activity 不同的实例。活动中偏好的任何更改,都不会更新服务中的默认共享偏好。因此,我将使用“.getSharedPreferences”更改 Erian 代码,如下所示:
在活动中:
@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();
}
服务中:
if (getApplicationContext().getSharedPreferences("preferences", MODE_MULTI_PROCESS).getBoolean("isActive", false)) {
return;
}
上面的大多数答案都有一个缺陷,如果您的活动具有触发顶部另一个活动的某些功能,例如发送电子邮件
topActivity
不会返回您的包名称,而是返回 Android 活动选择器包名称。
因此,最好检查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;
}
使用 Android 架构组件,检查这一点非常简单
annotationProcessor 'android.arch.lifecycle:compiler:1.1.1'
implementation 'android.arch.lifecycle:extensions:1.1.1'
生命周期观察者类,保留一个 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);
}
}
应用程序类观察者生命周期
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);
}
现在,您可以使用 Pref 标志在您喜欢的任何地方进行检查。
getRunningTasks() 已弃用
getRunningTask()
已被 android 弃用,现在我们可以使用getRunningAppProcesses()
. 这将返回一个列表或RunningAppProcessInfo
我们可以检查importance
第一个进程的位置。
更多详细信息请参见官方文档:https://developer.android.com/reference/android/app/ActivityManager#getRunningAppProcesses()
代码:
public boolean isAppInForeground() {
ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> runningTaskInfo = manager.getRunningAppProcesses();
if (runningTaskInfo.size() > 0)
return runningTaskInfo.get(0).importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
return false; // no running process
}
我认为您可以在 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;
}
使用以下方法获取当前活动的完整类名(包+类名),并检查它是否等于您想要的活动的完整类名(包+类名):
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;
}