获取前台应用的打开 activity
Get open activity of the foreground app
我需要获取前台App的当前Activity。我尝试遵循 this answer and later used this library(因为第一个解决方案仅适用于 Lollipop),它们确实很好地告诉了前台应用程序的包名称,但我需要知道什么 activity 是打开的。
由于安全问题,您应该无法执行此操作。您不希望其他应用知道您当前打开的 activity。所以其他应用程序不希望您监视它们。这是一个 OS 限制。
嘿@Capitan Luzzatto,
- Pre LOLLIPOP(API 21) 我们可以从 ActivityManager
中获取 运行 个应用程序列表
- 但是从 LOLLIPOP 我们应该只从 UsageStatsManager
首先你需要2个权限才能阅读任务
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
并且您应该首先检查用户 API 级别是否为 21 或更高,如果是,您应该获得使用权限设置的访问权限,如下所示
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP && !mIsChecked) {
if (getUsageStatsList(getActivity()).isEmpty()) {
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
startActivity(intent);
}
}
获取使用情况统计列表
public static List<UsageStats> getUsageStatsList(Context context){
UsageStatsManager usm = (UsageStatsManager) context.getSystemService("usagestats");
Calendar calendar = Calendar.getInstance();
long endTime = calendar.getTimeInMillis();
calendar.add(Calendar.DATE, -1);
long startTime = calendar.getTimeInMillis();
List<UsageStats> usageStatsList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY,startTime,endTime);
return usageStatsList;
}
终于可以通过以下方法获取最新的Foreground app了
public String getRecentApps(Context context) {
String topPackageName = "";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
UsageStatsManager mUsageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
long time = System.currentTimeMillis();
UsageEvents usageEvents = mUsageStatsManager.queryEvents(time - 1000 * 30, System.currentTimeMillis() + (10 * 1000));
UsageEvents.Event event = new UsageEvents.Event();
while (usageEvents.hasNextEvent()) {
usageEvents.getNextEvent(event);
}
if (event != null && !TextUtils.isEmpty(event.getPackageName()) && event.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) {
if (AndroidUtils.isRecentActivity(event.getClassName())) {
return event.getClassName();
}
return event.getPackageName();
} else {
topPackageName = "";
}
} else {
ActivityManager am = (ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
ComponentName componentInfo = taskInfo.get(0).topActivity;
if (AndroidUtils.isRecentActivity(componentInfo.getClassName())) {
return componentInfo.getClassName();
}
topPackageName = componentInfo.getPackageName();
}
return topPackageName;
}
要获得前景 activity 使用这样的方法
public String getRecentActivity(Context context) {
String topActivityName = "";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
UsageStatsManager mUsageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
long time = System.currentTimeMillis();
UsageEvents usageEvents = mUsageStatsManager.queryEvents(time - 1000 * 30, System.currentTimeMillis() + (10 * 1000));
UsageEvents.Event event = new UsageEvents.Event();
while (usageEvents.hasNextEvent()) {
usageEvents.getNextEvent(event);
}
if (event != null && !TextUtils.isEmpty(event.getPackageName()) && event.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) {
return event.getClassName();
} else {
topActivityName = "";
}
} else {
ActivityManager am = (ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
ComponentName componentInfo = taskInfo.get(0).topActivity;
topActivityName = componentInfo.getClassName();
}
return topActivityName;
}
AndroidUtils.java - 要以 Hack 方式获取设备最近的屏幕,也许我们应该对此进行更多调查,不确定它是否适用于所有设备,但它适用于几乎所有设备
public class AndroidUtils {
private static final String RECENT_ACTIVITY;
static {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
RECENT_ACTIVITY = "com.android.systemui.recents.RecentsActivity";
} else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR1) {
RECENT_ACTIVITY = "com.android.systemui.recent.RecentsActivity";
} else {
RECENT_ACTIVITY = "com.android.internal.policy.impl.RecentApplicationDialog";
}
}
/**
* To get the Device recent screen activity
*
* @param className
* @return activity
*/
public static boolean isRecentActivity(String className) {
if (RECENT_ACTIVITY.equalsIgnoreCase(className)) {
return true;
}
return false;
}
}
我需要获取前台App的当前Activity。我尝试遵循 this answer and later used this library(因为第一个解决方案仅适用于 Lollipop),它们确实很好地告诉了前台应用程序的包名称,但我需要知道什么 activity 是打开的。
由于安全问题,您应该无法执行此操作。您不希望其他应用知道您当前打开的 activity。所以其他应用程序不希望您监视它们。这是一个 OS 限制。
嘿@Capitan Luzzatto,
- Pre LOLLIPOP(API 21) 我们可以从 ActivityManager 中获取 运行 个应用程序列表
- 但是从 LOLLIPOP 我们应该只从 UsageStatsManager
首先你需要2个权限才能阅读任务
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
并且您应该首先检查用户 API 级别是否为 21 或更高,如果是,您应该获得使用权限设置的访问权限,如下所示
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP && !mIsChecked) {
if (getUsageStatsList(getActivity()).isEmpty()) {
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
startActivity(intent);
}
}
获取使用情况统计列表
public static List<UsageStats> getUsageStatsList(Context context){
UsageStatsManager usm = (UsageStatsManager) context.getSystemService("usagestats");
Calendar calendar = Calendar.getInstance();
long endTime = calendar.getTimeInMillis();
calendar.add(Calendar.DATE, -1);
long startTime = calendar.getTimeInMillis();
List<UsageStats> usageStatsList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY,startTime,endTime);
return usageStatsList;
}
终于可以通过以下方法获取最新的Foreground app了
public String getRecentApps(Context context) {
String topPackageName = "";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
UsageStatsManager mUsageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
long time = System.currentTimeMillis();
UsageEvents usageEvents = mUsageStatsManager.queryEvents(time - 1000 * 30, System.currentTimeMillis() + (10 * 1000));
UsageEvents.Event event = new UsageEvents.Event();
while (usageEvents.hasNextEvent()) {
usageEvents.getNextEvent(event);
}
if (event != null && !TextUtils.isEmpty(event.getPackageName()) && event.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) {
if (AndroidUtils.isRecentActivity(event.getClassName())) {
return event.getClassName();
}
return event.getPackageName();
} else {
topPackageName = "";
}
} else {
ActivityManager am = (ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
ComponentName componentInfo = taskInfo.get(0).topActivity;
if (AndroidUtils.isRecentActivity(componentInfo.getClassName())) {
return componentInfo.getClassName();
}
topPackageName = componentInfo.getPackageName();
}
return topPackageName;
}
要获得前景 activity 使用这样的方法
public String getRecentActivity(Context context) {
String topActivityName = "";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
UsageStatsManager mUsageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
long time = System.currentTimeMillis();
UsageEvents usageEvents = mUsageStatsManager.queryEvents(time - 1000 * 30, System.currentTimeMillis() + (10 * 1000));
UsageEvents.Event event = new UsageEvents.Event();
while (usageEvents.hasNextEvent()) {
usageEvents.getNextEvent(event);
}
if (event != null && !TextUtils.isEmpty(event.getPackageName()) && event.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) {
return event.getClassName();
} else {
topActivityName = "";
}
} else {
ActivityManager am = (ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
ComponentName componentInfo = taskInfo.get(0).topActivity;
topActivityName = componentInfo.getClassName();
}
return topActivityName;
}
AndroidUtils.java - 要以 Hack 方式获取设备最近的屏幕,也许我们应该对此进行更多调查,不确定它是否适用于所有设备,但它适用于几乎所有设备
public class AndroidUtils {
private static final String RECENT_ACTIVITY;
static {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
RECENT_ACTIVITY = "com.android.systemui.recents.RecentsActivity";
} else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR1) {
RECENT_ACTIVITY = "com.android.systemui.recent.RecentsActivity";
} else {
RECENT_ACTIVITY = "com.android.internal.policy.impl.RecentApplicationDialog";
}
}
/**
* To get the Device recent screen activity
*
* @param className
* @return activity
*/
public static boolean isRecentActivity(String className) {
if (RECENT_ACTIVITY.equalsIgnoreCase(className)) {
return true;
}
return false;
}
}