如何确定Android Service 是不是在前台运行?
Posted
技术标签:
【中文标题】如何确定Android Service 是不是在前台运行?【英文标题】:How to determine if an Android Service is running in the foreground?如何确定Android Service 是否在前台运行? 【发布时间】:2011-09-21 02:26:24 【问题描述】:我有一个我认为在前台运行的服务,我如何检查我的实现是否正常工作?
【问题讨论】:
【参考方案1】:public static boolean isServiceRunningInForeground(Context context, Class<?> serviceClass)
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE))
if (serviceClass.getName().equals(service.service.getClassName()))
if (service.foreground)
return true;
return false;
【讨论】:
我发现此答案中的代码比已接受答案中的代码更简洁,并且与已接受的答案不同,即使有超过 50 个服务正在运行,它也能正常工作。 与接受的相同,但更清晰、更短、更简单。还要检查所有服务,不仅仅是 50。 这里唯一的问题是“从 Oreo 开始,此方法不再适用于第三方应用程序。为了向后兼容,它仍将返回调用者自己的服务。” 如果我想在 android O 中做同样的事情怎么办? getRunningServices 在 Android 9 中已弃用【参考方案2】:private boolean isServiceRunning(String serviceName)
boolean serviceRunning = false;
ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RunningServiceInfo> l = am.getRunningServices(50);
Iterator<ActivityManager.RunningServiceInfo> i = l.iterator();
while (i.hasNext())
ActivityManager.RunningServiceInfo runningServiceInfo = i
.next();
if(runningServiceInfo.service.getClassName().equals(serviceName))
serviceRunning = true;
if(runningServiceInfo.foreground)
//service run in foreground
return serviceRunning;
如果您想知道您的服务是否在前台运行,只需打开其他一些胖应用程序,然后检查服务是否仍在运行或检查标志 service.foreground
。
【讨论】:
谢谢,效果很好!我只需要添加这一行: serviceInForeground = runningServiceInfo.foreground; onDestroy() 中的 stopForeground(true) 怎么样?这不会阻止服务在前台运行吗? @user811985 仅供参考,RunningServiceInfo.foreground 上的文档指出:“如果服务已要求作为前台进程运行,则设置为 true。”。也就是说,它不会告诉你 android 是否真的接受了前台服务。 developer.android.com/reference/android/app/… 不幸的是,GetRunningServices 现在被标记为已弃用【参考方案3】:更有效的答案变体:https://***.com/a/36127260/1275265
public static boolean isServiceRunningInForeground(Context context, Class<?> serviceClass)
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE))
if (serviceClass.getName().equals(service.service.getClassName()))
return service.foreground;
return false;
【讨论】:
【参考方案4】:从 API 26 开始,getRunningService()
已弃用。
现在的一个解决方案是将您的活动绑定到您的服务。然后您可以从您的 Activity 中调用您的 Service 的方法,以检查它是否正在运行。
1 - 在您的 Service 中,创建一个扩展 Binder 并返回您的 Service 的类
public class LocalBinder extends Binder
MyService getService()
return MyService.this;
2 - 在您的服务中,声明活页夹
private final IBinder binder = new LocalBinder();
3 - 在您的 Service 中,实现 onBind()
,这将返回 Binder
@Nullable
@Override
public IBinder onBind(Intent intent)
return binder;
4 - 在您的服务中,创建一个检查它是否正在运行的方法(例如检查变量是否已初始化)
public boolean isRunning()
// If running
return true;
// If not running
return false;
5 - 在您的 Activity 中,创建一个保存您的服务的变量
private MyService myService;
6 - 现在,在您的 Activity 中,您可以绑定到您的服务
private void checkIfEnabled()
ServiceConnection connection = new ServiceConnection()
@Override
public void onServiceConnected(ComponentName className,
IBinder service)
MyService.LocalBinder binder = (MyService.LocalBinder) service;
myService = binder.getService();
// Calling your service public method
if(myService.isRunning())
// Your service is enabled
else
// Your service is disabled
@Override
public void onServiceDisconnected(ComponentName arg0)
;
// Bind to MyService
Intent intent = new Intent(this, MyService.class);
bindService(intent, connection, Context.BIND_AUTO_CREATE);
欲了解更多信息,请查看官方文档中的Bound services overview。
【讨论】:
【参考方案5】:这适用于我在 Coinverse 应用程序中获取加密新闻。
这是最简洁的 Kotlin 解决方案。感谢Abbas Naqdi 在此GitHub issue。
@Suppress("DEPRECATION") // Deprecated for third party Services.
fun <T> Context.isServiceRunning(service: Class<T>) =
(getSystemService(ACTIVITY_SERVICE) as ActivityManager)
.getRunningServices(Integer.MAX_VALUE)
.any it.service.className == service.name
【讨论】:
如果您需要停止服务,这是 Android 9.0 的 latest implementation。 问题是关于前台运行的服务。所以你也应该检查it.foreground
。【参考方案6】:
对亚当的回答稍作改动:
@Suppress("DEPRECATION") // Deprecated for third party Services.
fun <T> Context.isServiceForegrounded(service: Class<T>) =
(getSystemService(ACTIVITY_SERVICE) as? ActivityManager)
?.getRunningServices(Integer.MAX_VALUE)
?.find it.service.className == service.name
?.foreground == true
【讨论】:
以上是关于如何确定Android Service 是不是在前台运行?的主要内容,如果未能解决你的问题,请参考以下文章
Android入门第42天-Android中的Service(IntentService)