Определение текущего приложения переднего плана из фоновой задачи или службы

Я хочу иметь одно приложение, которое работает в фоновом режиме, которое знает, когда работает какое-либо из встроенных приложений (обмен сообщениями, контакты и т. Д.).

Поэтому мои вопросы:

  1. Как я должен запустить свое приложение в фоновом режиме.

  2. Как мое фоновое приложение может узнать, какое приложение на данный момент работает на переднем плане.

Было бы весьма полезно получить ответы от людей с опытом.

Что касается «2. Как мое фоновое приложение может знать, что приложение в настоящее время работает на переднем плане».

НЕ используйте метод getRunningAppProcesses() как это возвращает всевозможные системные мусора из моего опыта, и вы получите несколько результатов, которые имеют RunningAppProcessInfo.IMPORTANCE_FOREGROUND . getRunningTasks() этого используйте getRunningTasks()

Это код, который я использую в своем сервисе для определения текущего приложения переднего плана, его очень просто:

 ActivityManager am = (ActivityManager) AppService.this.getSystemService(ACTIVITY_SERVICE); // The first in the list of RunningTasks is always the foreground task. RunningTaskInfo foregroundTaskInfo = am.getRunningTasks(1).get(0); 

То есть, вы можете легко получить доступ к сведениям о приложении / деятельности переднего плана:

 String foregroundTaskPackageName = foregroundTaskInfo .topActivity.getPackageName(); PackageManager pm = AppService.this.getPackageManager(); PackageInfo foregroundAppPackageInfo = pm.getPackageInfo(foregroundTaskPackageName, 0); String foregroundTaskAppName = foregroundAppPackageInfo.applicationInfo.loadLabel(pm).toString(); 

Для этого требуется дополнительное разрешение в манифесте активности и прекрасно работает.

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

Я должен был правильно решить правильное решение. Приведенный ниже код является частью cyanogenmod7 (уловки с таблетками) и тестируется на Android 2.3.3 / gingerbread.

методы:

  • GetForegroundApp – возвращает приложение переднего плана.
  • GetActivityForApp – возвращает активность найденного приложения.
  • IsStillActive – определяет, является ли ранее обнаруженное приложение все еще активным приложением.
  • IsRunningService – вспомогательная функция для getForegroundApp

Это, надеюсь, полностью отвечает на этот вопрос (:

 private RunningAppProcessInfo getForegroundApp() { RunningAppProcessInfo result=null, info=null; if(mActivityManager==null) mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE); List <RunningAppProcessInfo> l = mActivityManager.getRunningAppProcesses(); Iterator <RunningAppProcessInfo> i = l.iterator(); while(i.hasNext()){ info = i.next(); if(info.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND && !isRunningService(info.processName)){ result=info; break; } } return result; } private ComponentName getActivityForApp(RunningAppProcessInfo target){ ComponentName result=null; ActivityManager.RunningTaskInfo info; if(target==null) return null; if(mActivityManager==null) mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE); List <ActivityManager.RunningTaskInfo> l = mActivityManager.getRunningTasks(9999); Iterator <ActivityManager.RunningTaskInfo> i = l.iterator(); while(i.hasNext()){ info=i.next(); if(info.baseActivity.getPackageName().equals(target.processName)){ result=info.topActivity; break; } } return result; } private boolean isStillActive(RunningAppProcessInfo process, ComponentName activity) { // activity can be null in cases, where one app starts another. for example, astro // starting rock player when a move file was clicked. we dont have an activity then, // but the package exits as soon as back is hit. so we can ignore the activity // in this case if(process==null) return false; RunningAppProcessInfo currentFg=getForegroundApp(); ComponentName currentActivity=getActivityForApp(currentFg); if(currentFg!=null && currentFg.processName.equals(process.processName) && (activity==null || currentActivity.compareTo(activity)==0)) return true; Slog.i(TAG, "isStillActive returns false - CallerProcess: " + process.processName + " CurrentProcess: " + (currentFg==null ? "null" : currentFg.processName) + " CallerActivity:" + (activity==null ? "null" : activity.toString()) + " CurrentActivity: " + (currentActivity==null ? "null" : currentActivity.toString())); return false; } private boolean isRunningService(String processname){ if(processname==null || processname.isEmpty()) return false; RunningServiceInfo service; if(mActivityManager==null) mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE); List <RunningServiceInfo> l = mActivityManager.getRunningServices(9999); Iterator <RunningServiceInfo> i = l.iterator(); while(i.hasNext()){ service = i.next(); if(service.process.equals(processname)) return true; } return false; } в private RunningAppProcessInfo getForegroundApp() { RunningAppProcessInfo result=null, info=null; if(mActivityManager==null) mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE); List <RunningAppProcessInfo> l = mActivityManager.getRunningAppProcesses(); Iterator <RunningAppProcessInfo> i = l.iterator(); while(i.hasNext()){ info = i.next(); if(info.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND && !isRunningService(info.processName)){ result=info; break; } } return result; } private ComponentName getActivityForApp(RunningAppProcessInfo target){ ComponentName result=null; ActivityManager.RunningTaskInfo info; if(target==null) return null; if(mActivityManager==null) mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE); List <ActivityManager.RunningTaskInfo> l = mActivityManager.getRunningTasks(9999); Iterator <ActivityManager.RunningTaskInfo> i = l.iterator(); while(i.hasNext()){ info=i.next(); if(info.baseActivity.getPackageName().equals(target.processName)){ result=info.topActivity; break; } } return result; } private boolean isStillActive(RunningAppProcessInfo process, ComponentName activity) { // activity can be null in cases, where one app starts another. for example, astro // starting rock player when a move file was clicked. we dont have an activity then, // but the package exits as soon as back is hit. so we can ignore the activity // in this case if(process==null) return false; RunningAppProcessInfo currentFg=getForegroundApp(); ComponentName currentActivity=getActivityForApp(currentFg); if(currentFg!=null && currentFg.processName.equals(process.processName) && (activity==null || currentActivity.compareTo(activity)==0)) return true; Slog.i(TAG, "isStillActive returns false - CallerProcess: " + process.processName + " CurrentProcess: " + (currentFg==null ? "null" : currentFg.processName) + " CallerActivity:" + (activity==null ? "null" : activity.toString()) + " CurrentActivity: " + (currentActivity==null ? "null" : currentActivity.toString())); return false; } private boolean isRunningService(String processname){ if(processname==null || processname.isEmpty()) return false; RunningServiceInfo service; if(mActivityManager==null) mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE); List <RunningServiceInfo> l = mActivityManager.getRunningServices(9999); Iterator <RunningServiceInfo> i = l.iterator(); while(i.hasNext()){ service = i.next(); if(service.process.equals(processname)) return true; } return false; } в private RunningAppProcessInfo getForegroundApp() { RunningAppProcessInfo result=null, info=null; if(mActivityManager==null) mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE); List <RunningAppProcessInfo> l = mActivityManager.getRunningAppProcesses(); Iterator <RunningAppProcessInfo> i = l.iterator(); while(i.hasNext()){ info = i.next(); if(info.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND && !isRunningService(info.processName)){ result=info; break; } } return result; } private ComponentName getActivityForApp(RunningAppProcessInfo target){ ComponentName result=null; ActivityManager.RunningTaskInfo info; if(target==null) return null; if(mActivityManager==null) mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE); List <ActivityManager.RunningTaskInfo> l = mActivityManager.getRunningTasks(9999); Iterator <ActivityManager.RunningTaskInfo> i = l.iterator(); while(i.hasNext()){ info=i.next(); if(info.baseActivity.getPackageName().equals(target.processName)){ result=info.topActivity; break; } } return result; } private boolean isStillActive(RunningAppProcessInfo process, ComponentName activity) { // activity can be null in cases, where one app starts another. for example, astro // starting rock player when a move file was clicked. we dont have an activity then, // but the package exits as soon as back is hit. so we can ignore the activity // in this case if(process==null) return false; RunningAppProcessInfo currentFg=getForegroundApp(); ComponentName currentActivity=getActivityForApp(currentFg); if(currentFg!=null && currentFg.processName.equals(process.processName) && (activity==null || currentActivity.compareTo(activity)==0)) return true; Slog.i(TAG, "isStillActive returns false - CallerProcess: " + process.processName + " CurrentProcess: " + (currentFg==null ? "null" : currentFg.processName) + " CallerActivity:" + (activity==null ? "null" : activity.toString()) + " CurrentActivity: " + (currentActivity==null ? "null" : currentActivity.toString())); return false; } private boolean isRunningService(String processname){ if(processname==null || processname.isEmpty()) return false; RunningServiceInfo service; if(mActivityManager==null) mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE); List <RunningServiceInfo> l = mActivityManager.getRunningServices(9999); Iterator <RunningServiceInfo> i = l.iterator(); while(i.hasNext()){ service = i.next(); if(service.process.equals(processname)) return true; } return false; } в private RunningAppProcessInfo getForegroundApp() { RunningAppProcessInfo result=null, info=null; if(mActivityManager==null) mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE); List <RunningAppProcessInfo> l = mActivityManager.getRunningAppProcesses(); Iterator <RunningAppProcessInfo> i = l.iterator(); while(i.hasNext()){ info = i.next(); if(info.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND && !isRunningService(info.processName)){ result=info; break; } } return result; } private ComponentName getActivityForApp(RunningAppProcessInfo target){ ComponentName result=null; ActivityManager.RunningTaskInfo info; if(target==null) return null; if(mActivityManager==null) mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE); List <ActivityManager.RunningTaskInfo> l = mActivityManager.getRunningTasks(9999); Iterator <ActivityManager.RunningTaskInfo> i = l.iterator(); while(i.hasNext()){ info=i.next(); if(info.baseActivity.getPackageName().equals(target.processName)){ result=info.topActivity; break; } } return result; } private boolean isStillActive(RunningAppProcessInfo process, ComponentName activity) { // activity can be null in cases, where one app starts another. for example, astro // starting rock player when a move file was clicked. we dont have an activity then, // but the package exits as soon as back is hit. so we can ignore the activity // in this case if(process==null) return false; RunningAppProcessInfo currentFg=getForegroundApp(); ComponentName currentActivity=getActivityForApp(currentFg); if(currentFg!=null && currentFg.processName.equals(process.processName) && (activity==null || currentActivity.compareTo(activity)==0)) return true; Slog.i(TAG, "isStillActive returns false - CallerProcess: " + process.processName + " CurrentProcess: " + (currentFg==null ? "null" : currentFg.processName) + " CallerActivity:" + (activity==null ? "null" : activity.toString()) + " CurrentActivity: " + (currentActivity==null ? "null" : currentActivity.toString())); return false; } private boolean isRunningService(String processname){ if(processname==null || processname.isEmpty()) return false; RunningServiceInfo service; if(mActivityManager==null) mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE); List <RunningServiceInfo> l = mActivityManager.getRunningServices(9999); Iterator <RunningServiceInfo> i = l.iterator(); while(i.hasNext()){ service = i.next(); if(service.process.equals(processname)) return true; } return false; } 

Попробуйте следующий код:

 ActivityManager activityManager = (ActivityManager) newContext.getSystemService( Context.ACTIVITY_SERVICE ); List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses(); for(RunningAppProcessInfo appProcess : appProcesses){ if(appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND){ Log.i("Foreground App", appProcess.processName); } } 

Имя процесса – это имя пакета приложения, запущенного на переднем плане. Сравните его с именем пакета вашего приложения. Если это то же самое, ваше приложение работает на переднем плане.

Надеюсь, это ответит на ваш вопрос.

С леденцов и далее это изменилось. Пожалуйста, найдите ниже код, прежде чем этот пользователь должен перейти в Настройки -> Безопасность -> (Прокрутить вниз до последнего) Приложения с доступом к использованию -> Дайте разрешения нашему приложению

 private void printForegroundTask() { String currentApp = "NULL"; if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { UsageStatsManager usm = (UsageStatsManager) this.getSystemService(Context.USAGE_STATS_SERVICE); long time = System.currentTimeMillis(); List<UsageStats> appList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000*1000, time); if (appList != null && appList.size() > 0) { SortedMap<Long, UsageStats> mySortedMap = new TreeMap<Long, UsageStats>(); for (UsageStats usageStats : appList) { mySortedMap.put(usageStats.getLastTimeUsed(), usageStats); } if (mySortedMap != null && !mySortedMap.isEmpty()) { currentApp = mySortedMap.get(mySortedMap.lastKey()).getPackageName(); } } } else { ActivityManager am = (ActivityManager)this.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningAppProcessInfo> tasks = am.getRunningAppProcesses(); currentApp = tasks.get(0).processName; } Log.e(TAG, "Current App in foreground is: " + currentApp); } 

Класс ActivityManager является подходящим инструментом для просмотра процессов.

Для запуска в фоновом режиме вы обычно хотите использовать службу .

Чтобы определить приложение переднего плана, вы можете использовать для обнаружения приложения переднего плана, вы можете использовать https://github.com/ricvalerio/foregroundappchecker . Он использует разные методы в зависимости от версии Android для Android.

Что касается сервиса, репо также предоставляет код, который вам нужен. По существу, пусть студия android создаст для вас сервис, а затем onCreate добавит фрагмент, который использует appChecker. Однако вам нужно запросить разрешение.

В леденец и вверх:

Добавить в избранное |

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

И сделайте что-нибудь вроде этого:

 if( mTaskId < 0 ) { List<AppTask> tasks = mActivityManager.getAppTasks(); if( tasks.size() > 0 ) mTaskId = tasks.get( 0 ).getTaskInfo().id; } 

Принимая во внимание, что getRunningTasks() устарел и getRunningAppProcesses() не является надежным, я пришел к решению объединить 2 подхода, упомянутых в StackOverflow:

  private boolean isAppInForeground(Context context) { if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { ActivityManager am = (ActivityManager) context.getSystemService(ACTIVITY_SERVICE); ActivityManager.RunningTaskInfo foregroundTaskInfo = am.getRunningTasks(1).get(0); String foregroundTaskPackageName = foregroundTaskInfo.topActivity.getPackageName(); return foregroundTaskPackageName.toLowerCase().equals(context.getPackageName().toLowerCase()); } else { ActivityManager.RunningAppProcessInfo appProcessInfo = new ActivityManager.RunningAppProcessInfo(); ActivityManager.getMyMemoryState(appProcessInfo); if (appProcessInfo.importance == IMPORTANCE_FOREGROUND || appProcessInfo.importance == IMPORTANCE_VISIBLE) { return true; } KeyguardManager km = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE); // App is foreground, but screen is locked, so show notification return km.inKeyguardRestrictedInputMode(); } } 

Сделайте что-то вроде этого:

 int showLimit = 20; /* Get all Tasks available (with limit set). */ ActivityManager mgr = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningTaskInfo> allTasks = mgr.getRunningTasks(showLimit); /* Loop through all tasks returned. */ for (ActivityManager.RunningTaskInfo aTask : allTasks) { Log.i("MyApp", "Task: " + aTask.baseActivity.getClassName()); if (aTask.baseActivity.getClassName().equals("com.android.email.activity.MessageList")) running=true; } 

Это сработало для меня. Но он дает только имя главного меню. То есть, если пользователь открыл Настройки -> Bluetooth -> Имя устройства, RunningAppProcessInfo называет его как «Настройки». Не удалось развернуть фурт

 ActivityManager activityManager = (ActivityManager) context.getSystemService( Context.ACTIVITY_SERVICE ); PackageManager pm = context.getPackageManager(); List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses(); for(RunningAppProcessInfo appProcess : appProcesses) { if(appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { CharSequence c = pm.getApplicationLabel(pm.getApplicationInfo(appProcess.processName, PackageManager.GET_META_DATA)); Log.i("Foreground App", "package: " + appProcess.processName + " App: " + c.toString()); } } 

Вот как я проверяю, находится ли мое приложение на переднем плане. Примечание. Я использую AsyncTask, как это предлагает официальная документация на Android. `

`

  private class CheckIfForeground extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... voids) { ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses(); for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) { if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { Log.i("Foreground App", appProcess.processName); if (mContext.getPackageName().equalsIgnoreCase(appProcess.processName)) { Log.i(Constants.TAG, "foreground true:" + appProcess.processName); foreground = true; // close_app(); } } } Log.d(Constants.TAG, "foreground value:" + foreground); if (foreground) { foreground = false; close_app(); Log.i(Constants.TAG, "Close App and start Activity:"); } else { //if not foreground close_app(); foreground = false; Log.i(Constants.TAG, "Close App"); } return null; } } 

И выполнить AsyncTask, как это. new CheckIfForeground().execute();

Я объединил два решения в одном методе, и он работает для меня для API 24 и API 21. Другие я не тестировал.

Код в Котлине:

 private fun isAppInForeground(context: Context): Boolean { val appProcessInfo = ActivityManager.RunningAppProcessInfo() ActivityManager.getMyMemoryState(appProcessInfo) if (appProcessInfo.importance == IMPORTANCE_FOREGROUND || appProcessInfo.importance == IMPORTANCE_VISIBLE) { return true } else if (appProcessInfo.importance == IMPORTANCE_TOP_SLEEPING || appProcessInfo.importance == IMPORTANCE_BACKGROUND) { return false } val am = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager val foregroundTaskInfo = am.getRunningTasks(1)[0] val foregroundTaskPackageName = foregroundTaskInfo.topActivity.packageName return foregroundTaskPackageName.toLowerCase() == context.packageName.toLowerCase() } 

И в манифесте

 <!-- Check whether app in background or foreground --> <uses-permission android:name="android.permission.GET_TASKS" /> 
Intereting Posts
Как добавить меню в FloatingActionButton в библиотеку дизайна Android, обновленную недавно? Работа с файлами ePub в android Как увеличить картинку Android TableLayout Какое влияние имеет множество отчетов о сбоях в приложении Android Java.io.IOException: SERVICE_NOT_AVAILABLE в GCM Client Можете ли вы одновременно сохранить / просмотреть видеофайл и данные датчика «Adb» не распознается как внутренняя или внешняя команда, операционная программа или командный файл Как заменить файл XML в APK? Предоставление нескольких опций выбора в браузере Android / iOS Могу ли я установить флаг BuildConfig, который возвращает, будет ли apk построена с помощью задачи «connectedAndroidTest»? Волейбол и данные обработки возвращены в фоновом режиме на Android Android активирует gps с помощью AlertDialog: как ждать, пока пользователь начнет действовать? Как предварительно заполнить базу данных sqlite Green DAO Как установить фон приложения Android? Android ClassNotFoundException для поддержки v7 TestActivity