安卓获取正在前台运行的应用,适用安卓5到14

前言:此方法没有使用无障碍、root、shizhuku等API,附上`Kotlin` 和 `java`两种代码,小白也能看懂

开门见山不啰嗦上代码

创建一个 Kotlin/java 文件/类,编写 

getTopAppPackagename 方法

1 Kotlin:

/**
 * ## 获取当前最顶层的应用
 */
@SuppressLint("ObsoleteSdkInt")
fun getTopAppPackagename(context: Context): Any = run {
    //声明包名
    var packagename = ""

    //通过上下文获取 ActivityManager
    val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager

    //根据安卓版本的不同进行处理
    //情况1:安卓5.0以下(其实没必要做这个,现在手机没有这么低的了)
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
        //获取一个正在运行的任务数组
        val runningTasks = activityManager.getRunningTasks(1)
        //将此数组的第一个元素赋值给$packagename,这个就是前台运行的应用
        packagename = runningTasks[0].topActivity!!.packageName

        //安卓5.0(同样没必要)
    } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {
        // 获取正在运行的程序,放到数组中
        val processes = activityManager.runningAppProcesses
        if (processes.size == 0) return packagename

        //遍历数组,如果遍历到权重最高的即是前台应用,返回其包名
        processes.forEach {
            if (it.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND)
                return it.processName
        }

        // 安卓 5.0 以上通用,通过查看应用使用情况来判断栈顶的应用
    } else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
        //获取当前时间
        val endTime = System.currentTimeMillis()
        //减去10秒,查询最近10秒内的应用使用情况
        val startTime = endTime - 10000 

        //使用统计管理器
        val usageStatsManager =
            context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager
        
        // 获取最近10秒的应用使用日志事件
        val usageEvents = usageStatsManager.queryEvents(startTime, endTime)

        //创建一个使用事件对象
        val event = UsageEvents.Event()
        
        //声明最后移动到前景时间
        var lastMoveToForegroundTime = 0L

        //遍历最近10秒事件
        while (usageEvents.hasNextEvent()) {
            // 获取下一条事件
            usageEvents.getNextEvent(event)
            
            // 条件判断,符合条件即是前台应用
            if (event.eventType == UsageEvents.Event.MOVE_TO_FOREGROUND && event.timeStamp > lastMoveToForegroundTime) {
                lastMoveToForegroundTime = event.timeStamp
                packagename = event.packageName
            }
        }
    }

    return packagename

}

考虑到会java的人不一定会 Kotlin, 附上Java代码,注释就免了看上面的一样:

 @SuppressLint("ObsoleteSdkInt")
    public static String getTopAppPackagename(Context context) {
        String packagename = "";

        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            List<ActivityManager.RunningTaskInfo> runningTasks = activityManager.getRunningTasks(1);
            packagename = runningTasks.get(0).topActivity.getPackageName();
        } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {
            List<ActivityManager.RunningAppProcessInfo> runningAppProcesses = activityManager.getRunningAppProcesses();
            if (runningAppProcesses.size() == 0) return packagename;
            for (ActivityManager.RunningAppProcessInfo appProcess : runningAppProcesses) {
                if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND)
                    return appProcess.processName;
            }
        } else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {

            long end = System.currentTimeMillis();

            long start = end - 10000;

            UsageStatsManager statsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
            UsageEvents usageEvents = statsManager.queryEvents(start, end);

            UsageEvents.Event event = new UsageEvents.Event();
            long lastMoveToForegroundTime = 0L;

            while (usageEvents.hasNextEvent()) {
                usageEvents.getNextEvent(event);
                if (event.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND && event.getTimeStamp() > lastMoveToForegroundTime) {
                    lastMoveToForegroundTime = event.getTimeStamp();
                    packagename = event.getPackageName();
                }
            }
        }
        return packagename;
    }

能做啥

获取到当前栈顶的应用后,那能干的事儿可就多咯。

广告投放优化

安全性增强

比如可以禁止使用一些软件来保证自己应用的安全

应用性能优化

例如,如果你的应用不是当前活跃的应用,那可能不需要在后台执行资源密集型的任务,从而节省电池和处理器资源。

应用使用统计

这个就不用多说了吧

应用状态检测

指定应用的壁纸设置

例如哪些微信壁纸、QQ壁纸之类的

扩展

1 权限申请

使用此方法需要在清单文件中注册:

    <!--查看应用使用情况-->
    <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"

5.0以上还需要在代码中动态申请(这个不用翻译成 java 了吧?):

val intent = Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS)

startActivityForResult(intent, USAGE_STATS_PERMISSION)

当然还要判断是否拥有这个权限,不然一打开就申请权限怪LOW的:

Kotlin:

fun haveUsageStatsPermission(context: Context) = run {
    val appOpsManager = context.getSystemService(APP_OPS_SERVICE) as AppOpsManager
    val i = appOpsManager.checkOpNoThrow(
        "android:get_usage_stats",
        Process.myUid(), context.packageName
    )
    val granted = i == AppOpsManager.MODE_ALLOWED
    granted
}

java:

public static boolean haveUsageStatsPermission(Context context) {
        AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        int i = appOpsManager.checkOpNoThrow(
                "android:get_usage_stats",
                Process.myUid(), context.getPackageName()
        );
        return i == AppOpsManager.MODE_ALLOWED;
}

2 后台保留

如果没有这个,你的应用在后台运行一段时间后就凉了,具体怎么做一搜一大堆,这里不多赘述。

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值