android5.0之后如何获取当前运行的应用包名

android5.0之后如何获取当前运行的应用包名

标签: android运行栈getRunningTasksgetRunningAppProcess
228人阅读 评论(0) 收藏 举报
本文章已收录于:
分类:

最近在项目中需要在用户处于某一个指定的应用(非当前项目的应用)界面时,自动弹出提示窗口。为了判断触发时机,我们需要判断当前前台应用的包名,那么如何获取前台应用的包名呢?

一种很自然的思路是获取当前运行栈中栈顶的activity,然后获取该activity的包名,最后进行判断,于是有了下面的代码——

/**
 * 如何获取前台应用的包名呢?
 * 一种很自然的思路是获取当前运行栈中栈顶的activity,然后获取该activity的包名,最后进行判断
 *
 * @param context
 * @return
 */
public static String getTopActivity(Context context) {
    try {
        ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        //获取正在运行的task列表,其中1表示最近运行的task,通过该数字限制列表中task数目,最近运行的靠前
        List<ActivityManager.RunningTaskInfo> runningTaskInfos = manager.getRunningTasks(1);

        if (runningTaskInfos != null && runningTaskInfos.size() != 0) {
            return (runningTaskInfos.get(0).baseActivity).getPackageName();
        }
    } catch (Exception e) {
        Log.d("GsonUtils", "Exception=" + e.toString());
    }
    return "";
}


这种方式在android5.0之前是没有问题的,然而,Android 5.0开始,Google开始对getRunningTasks接口进行限制使用。 之前,使用该接口需要 android.permission.GET_TASKS即使是自己开发的普通应用,只要声明该权限,即可以使用getRunningTasks接口。但从5.0开始,这种方式以及废弃。

应用要使用该接口必须声明权限Android.permission.REAL_GET_TASKS而这个权限是不对三方应用开放的。(在Manifest里申请了也没有作用),系统应用(有系统签名)可以调用该权限。

于是,有了另外一种思路:即运行应用的进程名称默认为包名,那么是不是可以通过获取进程信息间接获取到前台运行应用的包名呢?

/**
 * android 5.0之后如何获取当前运行的应用包名?
 * 即运行应用的进程名称默认为包名,那么是不是可以通过获取进程信息间接获取到前台运行应用的包名呢?
 *
 * @param context
 * @return
 */
public static String getLollipopRecentTask(Context context) {
    final int PROCESS_STATE_TOP = 2;
    try {
        //通过反射获取私有成员变量processState,稍后需要判断该变量的值
        Field processStateField = ActivityManager.RunningAppProcessInfo.class.getDeclaredField("processState");
        List<ActivityManager.RunningAppProcessInfo> processes = ((ActivityManager) context.getSystemService(
                Context.ACTIVITY_SERVICE)).getRunningAppProcesses();
        for (ActivityManager.RunningAppProcessInfo process : processes) {
            //判断进程是否为前台进程
            if (process.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                int state = processStateField.getInt(process);
                //processState值为2
                if (state == PROCESS_STATE_TOP) {
                    String[] packname = process.pkgList;
                    return packname[0];
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return "";
}

但是该方法的前提是前台Activity所在进程的名称为包名,若在manifest中自定义了其他的进程名,则失效。

以上。

方法2:

/**
 * 先看看android5.0之前的获取方法获取当前运行的应用包名
 *
 * @param context
 * @return
 */
public static String getPackageNameBefore(Context context) {
    ActivityManager activityManager = (ActivityManager) context.getSystemService(ACTIVITY_SERVICE);
    // 1、得到当前运行的任务栈,参数就是得到多少个任务栈,1就是只拿一个任务栈
    // 对应的也就是正在运行的任务栈啦 ,注意别忘了在清单文件中添加获取的权限
    List runTaskInfos =
            activityManager.getRunningTasks(1);
    //拿到当前运行的任务栈
    ActivityManager.RunningTaskInfo runningTaskInfo = (ActivityManager.RunningTaskInfo) runTaskInfos.get(0);
    //拿到要运行的Activity的包名
    String runningpackageName = runningTaskInfo.baseActivity.getPackageName();
    return runningpackageName;
}


/**
 * android 5.0之后如何获取当前运行的应用包名?
 * @param context
 * @return
 */
public static String getCurrentPkgName(Context context) {
    ActivityManager.RunningAppProcessInfo currentInfo = null;
    Field field = null;
    int START_TASK_TO_FRONT = 2;
    String pkgName = null;
    try {
        field = ActivityManager.RunningAppProcessInfo.class.getDeclaredField("processState");
    } catch (Exception e) {
        e.printStackTrace();
    }
    ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    List appList = am.getRunningAppProcesses();
    List<ActivityManager.RunningAppProcessInfo> processes = ((ActivityManager) context.getSystemService(
            Context.ACTIVITY_SERVICE)).getRunningAppProcesses();
    for (ActivityManager.RunningAppProcessInfo app : processes) {
        if (app.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
            Integer state = null;
            try {
                state = field.getInt(app);
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (state != null && state == START_TASK_TO_FRONT) {
                currentInfo = app;
                break;
            }
        }
    }
    if (currentInfo != null) {
        pkgName = currentInfo.processName;
    }
    return pkgName;
}




/**
 * 获取当前应用名称
 *
 * @param context
 * @return
 */
public static String getAppName(Context context) {
    String appName = null;
    PackageManager packageManager = context.getPackageManager();
    try {
        ApplicationInfo applicationInfo = packageManager.getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
        //CharSequence这两者效果是一样的.
        appName = packageManager.getApplicationLabel(applicationInfo).toString();
        appName = (String) packageManager.getApplicationLabel(applicationInfo);

    } catch (Exception e) {
        e.printStackTrace();
        Log.d("GsonUtils", "Exception=" + e.toString());
        return null;
    }
    return appName;
}

0
0
 
 

我的同类文章

/**
 * 获取当前应用名称
 *
 * @param context
 * @return
 */
public static String getAppName(Context context) {
    String appName = null;
    PackageManager packageManager = context.getPackageManager();
    try {
        ApplicationInfo applicationInfo = packageManager.getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
        //CharSequence这两者效果是一样的.
        appName = packageManager.getApplicationLabel(applicationInfo).toString();
        appName = (String) packageManager.getApplicationLabel(applicationInfo);

    } catch (Exception e) {
        e.printStackTrace();
        Log.d("GsonUtils", "Exception=" + e.toString());
        return null;
    }
    return appName;
}

最近在项目中需要在用户处于某一个指定的应用(非当前项目的应用)界面时,自动弹出提示窗口。为了判断触发时机,我们需要判断当前前台应用的包名,那么如何获取前台应用的包名呢?

一种很自然的思路是获取当前运行栈中栈顶的activity,然后获取该activity的包名,最后进行判断,于是有了下面的代码——

/**
 * 如何获取前台应用的包名呢?
 * 一种很自然的思路是获取当前运行栈中栈顶的activity,然后获取该activity的包名,最后进行判断
 *
 * @param context
 * @return
 */
public static String getTopActivity(Context context) {
    try {
        ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        //获取正在运行的task列表,其中1表示最近运行的task,通过该数字限制列表中task数目,最近运行的靠前
        List<ActivityManager.RunningTaskInfo> runningTaskInfos = manager.getRunningTasks(1);

        if (runningTaskInfos != null && runningTaskInfos.size() != 0) {
            return (runningTaskInfos.get(0).baseActivity).getPackageName();
        }
    } catch (Exception e) {
        Log.d("GsonUtils", "Exception=" + e.toString());
    }
    return "";
}


这种方式在android5.0之前是没有问题的,然而,Android 5.0开始,Google开始对getRunningTasks接口进行限制使用。 之前,使用该接口需要 android.permission.GET_TASKS即使是自己开发的普通应用,只要声明该权限,即可以使用getRunningTasks接口。但从5.0开始,这种方式以及废弃。

应用要使用该接口必须声明权限Android.permission.REAL_GET_TASKS而这个权限是不对三方应用开放的。(在Manifest里申请了也没有作用),系统应用(有系统签名)可以调用该权限。

于是,有了另外一种思路:即运行应用的进程名称默认为包名,那么是不是可以通过获取进程信息间接获取到前台运行应用的包名呢?

/**
 * android 5.0之后如何获取当前运行的应用包名?
 * 即运行应用的进程名称默认为包名,那么是不是可以通过获取进程信息间接获取到前台运行应用的包名呢?
 *
 * @param context
 * @return
 */
public static String getLollipopRecentTask(Context context) {
    final int PROCESS_STATE_TOP = 2;
    try {
        //通过反射获取私有成员变量processState,稍后需要判断该变量的值
        Field processStateField = ActivityManager.RunningAppProcessInfo.class.getDeclaredField("processState");
        List<ActivityManager.RunningAppProcessInfo> processes = ((ActivityManager) context.getSystemService(
                Context.ACTIVITY_SERVICE)).getRunningAppProcesses();
        for (ActivityManager.RunningAppProcessInfo process : processes) {
            //判断进程是否为前台进程
            if (process.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                int state = processStateField.getInt(process);
                //processState值为2
                if (state == PROCESS_STATE_TOP) {
                    String[] packname = process.pkgList;
                    return packname[0];
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return "";
}

但是该方法的前提是前台Activity所在进程的名称为包名,若在manifest中自定义了其他的进程名,则失效。

以上。

方法2:

/**
 * 先看看android5.0之前的获取方法获取当前运行的应用包名
 *
 * @param context
 * @return
 */
public static String getPackageNameBefore(Context context) {
    ActivityManager activityManager = (ActivityManager) context.getSystemService(ACTIVITY_SERVICE);
    // 1、得到当前运行的任务栈,参数就是得到多少个任务栈,1就是只拿一个任务栈
    // 对应的也就是正在运行的任务栈啦 ,注意别忘了在清单文件中添加获取的权限
    List runTaskInfos =
            activityManager.getRunningTasks(1);
    //拿到当前运行的任务栈
    ActivityManager.RunningTaskInfo runningTaskInfo = (ActivityManager.RunningTaskInfo) runTaskInfos.get(0);
    //拿到要运行的Activity的包名
    String runningpackageName = runningTaskInfo.baseActivity.getPackageName();
    return runningpackageName;
}


/**
 * android 5.0之后如何获取当前运行的应用包名?
 * @param context
 * @return
 */
public static String getCurrentPkgName(Context context) {
    ActivityManager.RunningAppProcessInfo currentInfo = null;
    Field field = null;
    int START_TASK_TO_FRONT = 2;
    String pkgName = null;
    try {
        field = ActivityManager.RunningAppProcessInfo.class.getDeclaredField("processState");
    } catch (Exception e) {
        e.printStackTrace();
    }
    ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    List appList = am.getRunningAppProcesses();
    List<ActivityManager.RunningAppProcessInfo> processes = ((ActivityManager) context.getSystemService(
            Context.ACTIVITY_SERVICE)).getRunningAppProcesses();
    for (ActivityManager.RunningAppProcessInfo app : processes) {
        if (app.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
            Integer state = null;
            try {
                state = field.getInt(app);
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (state != null && state == START_TASK_TO_FRONT) {
                currentInfo = app;
                break;
            }
        }
    }
    if (currentInfo != null) {
        pkgName = currentInfo.processName;
    }
    return pkgName;
}




/**
 * 获取当前应用名称
 *
 * @param context
 * @return
 */
public static String getAppName(Context context) {
    String appName = null;
    PackageManager packageManager = context.getPackageManager();
    try {
        ApplicationInfo applicationInfo = packageManager.getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
        //CharSequence这两者效果是一样的.
        appName = packageManager.getApplicationLabel(applicationInfo).toString();
        appName = (String) packageManager.getApplicationLabel(applicationInfo);

    } catch (Exception e) {
        e.printStackTrace();
        Log.d("GsonUtils", "Exception=" + e.toString());
        return null;
    }
    return appName;
}

猜你喜欢

转载自blog.csdn.net/dianziagen/article/details/61199482