Не удается получить название активности переднего плана только в Android Lollipop 5.0
Я использую следующий код, чтобы получить имя активности приложения переднего плана в переменной foregroundTaskPackageName. Он работает на всех версиях ОС от 4.1 до 4.4, но не работает в Android 5.0 Lollipop.
Может ли кто-нибудь помочь с тем, что изменилось в 5.0 Lollipop? В Lollipop - текст, который я получаю для foregroundTaskPackageName, - это просто "Launcher3". Я использую эмулятор Genymotion.
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
RunningTaskInfo foregroundTaskInfo = am.getRunningTasks(1).get(0); // get
// list
// of
// running
// tasks
String foregroundTaskAppName = null;
String foregroundTaskPackageName = foregroundTaskInfo.topActivity
.getPackageName();
Ответы
Ответ 1
Вам нужно использовать новый UsageStatsManager
и вызвать его метод queryUsageStats
, чтобы получить историю запущенных действий.
Обратите внимание, что пользователю будет необходимо предоставить доступ к статусу использования в настройках устройства в Security- > Apps с использованием доступа.
Ссылки:
UsageStatsManager
документация
queryUsageStats
документация по методу
Ответ 2
Это работает для меня на Lollipop (21):
ActivityManager manager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> tasks = manager.getRunningAppProcesses();
Log.i("current_app",tasks.get(0).processName);
Ответ 3
вы можете использовать код ниже и получить текущее имя пакета действий переднего плана.
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
// intentionally using string value as Context.USAGE_STATS_SERVICE was
// strangely only added in API 22 (LOLLIPOP_MR1)
@SuppressWarnings("WrongConstant")
UsageStatsManager usm = (UsageStatsManager) getSystemService("usagestats");
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) getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> tasks = am
.getRunningAppProcesses();
currentApp = tasks.get(0).processName;
}
Добавьте эти разрешения в файл манифеста (первый для < API 21, второй для >= API 21).
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" />
Ответ 4
getRunningTasks()
Этот метод устарел на уровне API 21. По состоянию на LOLLIPOP это метод больше не доступен для сторонних приложений: введение рецентов, ориентированных на документ, означает, что он может информация для вызывающего абонента. Для обратной совместимости все равно будет вернуть небольшое подмножество своих данных: по крайней мере, собственные задачи вызывающего абонента, и, возможно, некоторые другие задачи, такие как дома, которые, как известно, не являются чувствительным.
Ответ 5
доступный, но не лучший способ - использовать доступность.
Объявить службу доступности в XML файле AndroidManifest
<service
android:name=".MyAccessibilityService"
android:label="@string/accessibility_service_label"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" >
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/accessibility_service_config" />
</service>
accessibility_service_config.xml файл
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/accessibility_service_desc"
android:accessibilityEventTypes="typeAllMask"
android:accessibilityFlags="flagDefault|flagIncludeNotImportantViews"
android:accessibilityFeedbackType="feedbackSpoken"
android:notificationTimeout="100"
android:canRetrieveWindowContent="true"
/>
сохранить имя активности при изменении состояния окна
public class MyAccessibilityService extends AccessibilityService{
public static String sActivityName;
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
// TODO Auto-generated method stub
if(event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED){
Log.d("activitytest", "onAccessibilityEvent with window state changed");
sActivityName = event.getClassName().toString();
}
}
@Override
public void onInterrupt() {
// TODO Auto-generated method stub
}
}
Недостатком является то, что вы должны позволить пользователям включить вашу службу доступности в настройках.
Ответ 6
Я создал класс, который использует команду /system/bin/toolbox
для идентификации процессов, а затем идентифицирует видимое приложение.
Необходимо добавить идентификационные системные приложения без использования пользовательских интерфейсов и андроидных пусковых установок.
ProcessManager.java
Ответ 7
Попробуйте это
public static boolean isForeground(Context context) {
ActivityManager manager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> tasks = manager.getRunningAppProcesses();
if(tasks.isEmpty())
return false;
for (ActivityManager.RunningAppProcessInfo task : tasks) {
if(context.getPackageName().equalsIgnoreCase(task.processName)){
return task.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
}
}
return false;
}