【问题标题】:How can I check if an app running on Android?如何检查应用程序是否在 Android 上运行?
【发布时间】:2011-05-11 21:51:07
【问题描述】:

我是一名 Android 开发人员,我想在我的应用程序中编写 if 语句。在此语句中,我想检查默认浏览器(Android 操作系统中的浏览器)是否正在运行。如何以编程方式执行此操作?

【问题讨论】:

    标签: java android browser if-statement


    【解决方案1】:

    添加以下 Helper 类:

    public class Helper {
    
            public static boolean isAppRunning(final Context context, final String packageName) {
                final ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
                final List<ActivityManager.RunningAppProcessInfo> procInfos = activityManager.getRunningAppProcesses();
                if (procInfos != null)
                {
                    for (final ActivityManager.RunningAppProcessInfo processInfo : procInfos) {
                        if (processInfo.processName.equals(packageName)) {
                            return true;
                        }
                    }
                }
                return false;
            }
        }
    

    现在您可以从下面的代码中检查您想要的应用程序是否正在运行:

    if (Helper.isAppRunning(YourActivity.this, "com.your.desired.app")) {
        // App is running
    } else {
        // App is not running
    }
    

    【讨论】:

    • 谢谢,但正如我每次运行 com.android.browser 时看到的那样。前景时,一般在列表的第 3 或第 4 位,否则仍在列表中。所以这个语句每次都返回真。我怎么解决这个问题?只有当最近的进程是浏览器时,它必须写“浏览器正在运行”。
    • RunningAppProcessInfo 中的“lru”字段将为您提供应用程序运行时的相关信息以供进一步参考检查文档页面 - developer.android.com/reference/android/app/…
    • 要获得更详细的信息,您可以在应用程序中维护一个计时器。在我过去的一个应用程序中显示进程状态,就像 gmail 聊天状态一样,我们维护了应用程序时间以及重要性值
    • @dhaval 有没有办法检查应用程序现在是否已进入后台(即用户不再可见)?
    • 有什么方法可以检查进程是暂停还是恢复?
    【解决方案2】:

    可以通过以下方法查看

    public static boolean isRunning(Context ctx) {
        ActivityManager activityManager = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
    
        List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(Integer.MAX_VALUE);
    
        for (ActivityManager.RunningTaskInfo task : tasks) {
            if (ctx.getPackageName().equalsIgnoreCase(task.baseActivity.getPackageName()))
                return true;
        }
        return false;
    }
    

    【讨论】:

    • 它是否在 kitkat 之上工作?如果是,请提供代码..谢谢
    • 已弃用
    【解决方案3】:

    isInBackground是应用的状态

    ActivityManager.RunningAppProcessInfo myProcess = new ActivityManager.RunningAppProcessInfo();
    ActivityManager.getMyMemoryState(myProcess);
    Boolean isInBackground = myProcess.importance != ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
    

    【讨论】:

      【解决方案4】:

      最好的解决办法是:

      创建一个这样的界面。

      interface LifeCycleDelegate {
          void onAppBackgrounded();
          void onAppForegrounded();
      }
      

      现在添加一个处理所有活动生命周期回调的类。

      public class AppLifecycleHandler implements 
       Application.ActivityLifecycleCallbacks, ComponentCallbacks2 {
      
      LifeCycleDelegate lifeCycleDelegate;
      boolean appInForeground = false;
      
      public AppLifecycleHandler(LifeCycleDelegate lifeCycleDelegate) {
          this.lifeCycleDelegate = lifeCycleDelegate;
      }
      
      @Override
      public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
      
      }
      
      @Override
      public void onActivityStarted(Activity activity) {
      
      }
      
      @Override
      public void onActivityResumed(Activity activity) {
          if (!appInForeground) {
              appInForeground = true;
              lifeCycleDelegate.onAppForegrounded();
          }
      }
      
      @Override
      public void onActivityPaused(Activity activity) {
      
      }
      
      @Override
      public void onActivityStopped(Activity activity) {
      
      }
      
      @Override
      public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
      
      }
      
      @Override
      public void onActivityDestroyed(Activity activity) {
      
      }
      
      @Override
      public void onTrimMemory(int level) {
          if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
              // lifecycleDelegate instance was passed in on the constructor
              appInForeground = false;
              lifeCycleDelegate.onAppBackgrounded();
          }
      }
      
      @Override
      public void onConfigurationChanged(Configuration newConfig) {
      
      }
      
      @Override
      public void onLowMemory() {
      
      }
      }
      

      现在在一个扩展应用程序的类中

      public class MyApplication extends Application implements 
       LifeCycleDelegate{
       @Override
      public void onCreate() {
          super.onCreate();
      
          AppLifecycleHandler lifeCycleHandler = new 
          AppLifecycleHandler(MyApplication.this);
          registerLifecycleHandler(lifeCycleHandler);
      }
      
      @Override
      public void onAppBackgrounded() {
          Log.d("Awww", "App in background");
      }
      
      @Override
      public void onAppForegrounded() {
          Log.d("Yeeey", "App in foreground");
      }
      
      private void registerLifecycleHandler(AppLifecycleHandler lifeCycleHandler) {
          registerActivityLifecycleCallbacks(lifeCycleHandler);
          registerComponentCallbacks(lifeCycleHandler);
      }
      }
      

      更多请参考:https://android.jlelse.eu/how-to-detect-android-application-open-and-close-background-and-foreground-events-1b4713784b57

      【讨论】:

      • 他说的是默认浏览器而不是他自己的应用程序!
      【解决方案5】:
      fun Context.isAppInForeground(): Boolean {
      
      val application = this.applicationContext
      val activityManager = this.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
      val runningProcessList = activityManager.runningAppProcesses
      
        if (runningProcessList != null) {
           val myApp = runningProcessList.find { it.processName == application.packageName }
           ActivityManager.getMyMemoryState(myApp)
           return myApp?.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND
        }
      
        return false
      }
      

      【讨论】:

        【解决方案6】:

        如果您使用的是 Kotlin

           private fun isAppRunning(context: Context, packageName: String): Boolean {
                val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
                activityManager.runningAppProcesses?.apply {
                    for (processInfo in this) {
                        if (processInfo.processName == packageName) {
                            return true
                        }
                    }
                }
                return false
            }
        

        【讨论】:

        • 自 API 21 起它将只返回自身进程。
        猜你喜欢
        • 2015-01-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-15
        • 1970-01-01
        • 2014-09-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多