方法一:通过获取最上层Activity的包名来进行对比
private String getTopActivityPkgName() {
String topPkgName = "";
//get top activity package name
ActivityManager am = (ActivityManager) mContext.getSystemService(mContext.ACTIVITY_SERVICE);
ComponentName comp = am.getRunningTasks(1).get(0).topActivity;
topPkgName = comp.getPackageName();
return topPkgName;
}
通过对比topPkgName与targetPkgName是否一致,来判断targetPkgName是否运行在最上层。
问题:通过am.getRunningTasks(1).get(0).topActivity获取到的Activity会经常出现获取到的Activity为桌面,导致判断异常。
(原因:从一个应用切换到另一个应用,有几率判断错误,判断为显示为桌面(launcher))
方法二:通过getRunningAppProcesses来进行判断
private String getTopActivityPkgName() {
String topPkgName = "";
//get top activity package name
ActivityManager am = (ActivityManager) mContext.getSystemService(mContext.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> pis = am.getRunningAppProcesses();
ActivityManager.RunningAppProcessInfo topAppProcess = pis.get(0);
if (topAppProcess != null && topAppProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
topPkgName = topAppProcess.processName;
}
return topPkgName;
}
通过对比topPkgName与targetPkgName是否一致,来判断targetPkgName是否运行在最上层。
问题:通过这种方式获取到的topPkgName会出现为空的情况,导致判断异常。
方法三:通过getFocusedStackInfo方式来获取
public String getTopActivityPkgName() {
String topPackageName = "";
try {
final StackInfo focusedStack = ActivityManager.getService().getFocusedStackInfo();
if (focusedStack != null) {
if (focusedStack.stackId != 0
&& focusedStack.topActivity != null
&& focusedStack.topActivity.getClassName() != null) {
topPackageName = focusedStack.topActivity.getPackageName();
}
}
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
return topPackageName;
}
通过对比topPkgName与targetPkgName是否一致,来判断targetPkgName是否运行在最上层。
问题:通过这种方式获取topPkgName的时候会出现没有权限异常的情况,从而导致失败:
ActivityManager: Permission Denial: getStackInfo() from pid=1053, uid=1047 requires android.permission.MANAGE_ACTIVITY_STACKS
遇到过的问题:微信、支付宝扫码无法打开;原因:没有声明android.permission.MANAGE_ACTIVITY_STACKS权限的应用/相机应用等,打不开相机,提示相机不可用。
方法四:直接通过uid getUidProcessState来进行判断是否在最上层运行(当前运行应用)
private boolean isAppTop(int callingUid) {
final ActivityManagerInternal ami =
LocalServices.getService(ActivityManagerInternal.class);
if (ami == null) {
return false;
}
final int procState = ami.getUidProcessState(callingUid);
final boolean isUidActive = ami.isUidActive(callingUid);
return (isUidActive && procState <= ActivityManager.PROCESS_STATE_TOP);
}
目前没发现啥问题,完美~