Android 判断应用前后台运行状态并获取当前 Activity 实例

Android获取当前在前台运行的应用和判断当前应用进程是否存在 要实现只在特定应用(比如“K歌”)运行时显示对话框,你需要在触发对话框的事件中加入判断逻辑,检查当前是否是特定应用正在运行。在Android中,可以通过检查当前在前台运行的应用来实现这一功能。这通常涉及到使用来获取前台应用的信息。 阅读详情

判断应用是否处于运行状态,如果处于运行状态是在前台运行还是在后台运行,以及如何获取应用当前展示的 Activity 实例(Activity 堆栈中的Top Activity),是Android 开发人员经常遇到的问题,特别是在后台运行的 service 中单凭一个 context 对象处理这些,常见应用场景如消息推送:当推送通知到达客户端时是否需要展示通知栏消息,当用户点击通知栏消息时,如何启动应用,如何触发对应 Activity 的跳转等。

Android 5.0(Lollipop,API 21)之前,我们可以通过ActivityManager提供的getRunningTasks方法获取当前设备所有处于运行状态的应用信息,从而判断自己的应用的运行状态,包括topActivity信息,如:

public static ComponentName getTopActivity(Context context){
    ActivityManager activityManager = (ActivityManager) context.getSystemService(Service.ACTIVITY_SERVICE);
    List<ActivityManager.RunningTaskInfo> runningTaskInfoList = activityManager.getRunningTasks(Integer.MAX_VALUE);
    for (ActivityManager.RunningTaskInfo taskInfo : runningTaskInfoList) {
        if (taskInfo.topActivity.getPackageName().equals(context.getPackageName())){
            return taskInfo.topActivity;
        }
    }
    return null;
}


然而,Google 为了提升 Android 系统的安全性,从 5.0 开始,废弃了getRunningTasks方法,不再为开发人员提供类似的服务,仅可作为开发时的调试和展示,源代码中明确写有注释信息:

Note: this method is only intended for debugging and presenting task management user interfaces. This should never be used for core logic in an application, such as deciding between different behaviors based on the information found here. Such uses arenot supported, and will likely break in the future. For example, if multiple applications can be actively running at the same time, assumptions made about the meaning of the data here for purposes of control flow will be incorrect.

机智如你,此刻肯定和我一样,想到了尚未被标注Deprecated的getRunningAppProcesses方法,获取处于“运行状态”的应用进程信息。结合包名和importance属性值的联合判断,即可判定应用是否处于前台运行状态:

    public static boolean isAppRunningForeground(Context context){
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Service.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> runningAppProcessInfoList = activityManager.getRunningAppProcesses();
        if (runningAppProcessInfoList==null){
            return false;
        }
        for (ActivityManager.RunningAppProcessInfo processInfo : runningAppProcessInfoList) {
            if (processInfo.processName.equals(context.getPackageName())
                    && processInfo.importance==ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND){
                return true;
            }
        }
        return false;
    }

注意:一定要添加processInfo.importance==ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND 这句判断,区分process与task的区别。实际上,此处后台服务在运行,processInfo.processName.equals(context.getPackageName())一定为true。

不幸的是,如同getRunningTasks方法,getRunningAppProcesses方法在源码中一样被注明,该方法仅用于调试和展示性工作:

Note: this method is only intended for debugging or building a user-facing process management UI.

既然系统API出于安全的考虑,已经无法获取应用的前后台状态,只能另辟蹊径了。比如利用 Activity 的生命周期变化,自定义一个全局变量来保存应用的状态,然后将当前 Activity 的实例对象保存在全局变量中。

很多人喜欢将这个全局变量放置在自定义的 Application 类中,并且采用强引用的方式定义,这种做法不仅会给 Application 带来压力(增加应用的启动初始化时间等),还会造成内存泄漏。这里推荐一篇有关Java 中的四种引用方式的文章:Java 7之基础 - 强引用、弱引用、软引用、虚引用

基于这些考虑,我们可以使用饿汉式单例模式保存 Activity 的实例,如:

public class CustomActivityManager {

    private static AppActivityManager customActivityManager = new CustomActivityManager();
    private WeakReference<Activity> topActivity;

    private CustomActivityManager() {

    }

    public static CustomActivityManager getInstance(){
        return customActivityManager;
    }

    public Activity getTopActivity() {
        if (topActivity!=null){
            return topActivity.get();
        }
        return null;
    }

    public void setTopActivity(Activity topActivity) {
        this.topActivity = new WeakReference<>(topActivity);
    }

}


然后在 Activity 的生命周期函数中赋值修改这个状态值。有两种方式,第一种,在自定义的 BaseActivity 中重写 Activity 的 onResume() 和 onStop(),然后其他所有 Activity 均继承自这个 BaseActivity;第二种,借助 API 14 版本引入的ActivityLifecycleCallbacks类,在 Application 中注册使用:

public class CustomApplication extends Application{

    @Override
    public void onCreate() {
        super.onCreate();
        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {

            }

            @Override
            public void onActivityStarted(Activity activity) {

            }

            @Override
            public void onActivityResumed(Activity activity) {
                CustomActivityManager.getInstance().setTopActivity(activity);
            }

            @Override
            public void onActivityPaused(Activity activity) {

            }

            @Override
            public void onActivityStopped(Activity activity) {
                CustomActivityManager.getInstance().setTopActivity(null);
            }

            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

            }

            @Override
            public void onActivityDestroyed(Activity activity) {

            }
        });
    }
}

注意:再次强调,ActivityLifecycleCallbacks 类是有版本限制的,如果你的应用需要兼容到 API 14版本以下,就不能采取这种方式。

有了这个保存 Activity 状态的全局变量,就可以在后台服务中判断应用的运行状态,进行其它操作。比如,当消息推送的场景,当用户点击通知栏消息时,打开应用:如果应用处于关闭状态,重新启动;如果处于后台运行状态,打开应用并显示当前 Activity 即可。参考代码:

public static void launchApp(Context context){
    Intent intent;
    if (CsjActivityManager.getInstance().getTopActivity()!=null){
        intent = new Intent();
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 
                | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
    }else{
        intent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    }
    context.startActivity(intent);
}

以上便是有关 Android 开发获取应用的前后台运行状态的一些见解,感谢 技术小黑屋 提供的 Activity 状态保存方式。也许这些还不是最好的解决方案,欢迎大家踊跃留言,提出自己的见解,重在交流。最后,再分享一项黑科技,通过访问/proc 文件的方式获取应用信息,无需任何权限,只是在 Android Nougat 上不起作用,有兴趣的朋友可以了解以下,地址如下:

https://github.com/jaredrummler/AndroidProcesses

原文地址:http://blog.youkuaiyun.com/growing_tree/article/details/53007279

Android 应用在后台时,跳转 Activity 会自动切换应用至前台 本博客 demo 见:demo。平常用手机的时候经常碰到这种情况,用首屏广告举个栗子~很多应用都会有首屏广告 activity A,假设此应用是 app C,如果此时要使用别的应用,就会使得 app C 在后台运行。可是当 activity A 的广告结束后自动跳转 activity B 的时候 app C 总是会自动跳出来切换到前台展示,挡住了我们正在使用的应用,体验非常不好。这是 androi... 阅读详情

相关推荐

Android获取当前运行在前台的应用程序可以通过以下几种方法实现。下面将详细介绍这些方法,并提供相应的源代码示例。

以上代码中,我们通过监听AccessibilityEvent的TYPE_WINDOW_STATE_CHANGED事件获取前台应用程序的包名。Android获取当前运行在前台的应用程序可以通过以下几种方法实现。综上所述,本文介绍了三种获取Android前台应用程序的方法。然后遍历统计信息列表,找到最近使用的应用程序,得到其包名。方法获取所有正在运行的应用程序进程列表,然后遍历列表查找到前台运行的应用程序,得到其包名。需要注意的是,使用AccessibilityService需要获取权限。

2301_79326588的博客 826

ActivityManager.getRunningTasks笔记

// getRunningTasks(int),获取int个任务栈列表,但返回的列表size可能会小于int // getRunningTasks(int).get(0):获取当前正在运行的任务栈对象,通过这个对象可获取栈中activity的数量、正处于运行状态的activity数量等等信息 // getRunningTasks(int).get(0).topActivity:获取当前正在运行的任...

yuyang_1995 1510

Python中的串口通信库pyserial(基础)

pyserial是一个跨平台的库,可以在多个操作系统上使用,包括Windows、Linux和MacOS。:flushInput方法用于清除输入缓冲区中的所有数据,flushOutput方法用于清除输出缓冲区中的所有待发送数据。:PySerial允许在创建Serial对象后,通过修改对象的属性来设置串口参数,如波特率、数据位、校验位和停止位。同时,也提供了方法或属性来检查串口的状态,如是否已打开。:sendBreak方法用于向串口发送一个BREAK信号,这可以用于向连接的设备发送一个中断或重置信号。

weixin_44217158的博客 1万+

Android ADB命令获取前台APP包名

获取前台APP包名

ajdjcfdn的博客 2140

CentOS 7下Multipath多路径存储的实战配置与性能优化

本文详细介绍了在CentOS 7系统中配置与优化Multipath多路径存储的完整实战流程。从安装部署、核心配置文件解读,到性能调优与生产环境避坑指南,全面解析如何利用Device Mapper Multipath构建高可用、负载均衡的存储链路,提升存储系统可靠性与I/O性能。

weixin_29278805的博客 320

Xilinx System Generator多速率系统(Multi-Rate Systems)的使用

在本实验练习中,您将学习在System Generator中如何使用多个时钟域有效地实现具有多个数据速率的设计。

白码王子小张的博客 1093

Android 获取前台应用的方法总结

应用开发中,经常遇到需要获取系统正在运行的前台应用是什么应用,例如桌面悬浮窗挂件,需要获取当前是不是处于桌面;然而随着Android版本的迭代,获取前台应用的方法都陆续被制裁,因此对这些方法做一个总结。 Android5.0以前版本 getRunningTasks()    在Android 5.0以前的版本中,google提供了getRunningTasks()方法来获取所有正在运行的应用

AdobeSolo的博客 1万+

【图像去噪】论文精读:FM2S: Self-Supervised Fluorescence Microscopy Denoising With Single Noisy Image

论文题目:FM2S: Self-Supervised Fluorescence Microscopy Denoising With Single Noisy Image —— FM2S:单噪声图像自监督荧光显微镜去噪arXiv 2024!显微图像去噪!通过可视化详细的细胞结构和生物过程,荧光显微镜具有显着先进的生物学研究。然而,由于难以精确建模固有噪声和获取干净图像进行训练,这种图像去噪任务往往面临挑战,这限制了大多数现有方法。在本文中,我们提出了一种有效的。

主要更新底层视觉(去噪、超分等)相关的科研内容,形式为【论文精读】+【论文复现】 408

Android中获取当前正在显示的Activity实例

Android开发中需要用到当前 activity实例,如何获取当前正在显示的Activity实例 1.保存当前Activity实例 import android.app.Activity; import java.lang.ref.WeakReference; public class MyActivityManager { private static MyActivityManag...

wusejiege6的博客 1万+

ximalaya 新xm-sign逆向思路

本文主要介绍目标网站新xm-sign值的逆向思路。仅代表个人理解,如有其他建议可在评论区沟通。声明仅仅记录一下自己的学习方法,不作为其他参考、更不作为商业用途。如有侵犯请联系本人删除。

weixin_66580433的博客 2017

初学者入门YOLO目标检测:从懵圈到上手,这篇文章讲透所有核心(附学习路径+避坑指南)

目标:比如训练一个“检测苹果和橘子”的模型,或者“检测人脸”的模型;任务:学会用LabelImg标注数据,制作YOLO格式的数据集,用命令行训练模型;关键:不用追求高精度,能训练出一个能检测出目标的模型就行。很多初学者卡在入门阶段,不是因为智商不够,而是因为“想太多,做太少”——总觉得要把所有原理搞懂才能动手,结果越想越怕,最后放弃。先动手,再动脑。先跑通一个案例,获得成就感;再制作自定义数据集,训练简单模型;最后再回头去理解原理,优化模型。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 688

Android获取Activity(应用)的运行状态及其他信息

Android获取Activity(应用)的运行状态及其他信息 检测某Activity是否在当前Task的栈顶 判断Android应用是否在前台 获取Android手机内安装的所有桌面 Android 判断程序前后台状态

宋金时的专栏 1万+

【AirPlay】苹果认证MFI学习

配件认证是一个过程,通过这个过程,可验证其配件符合MFi技术规范,并通过苹果指定的任何认证测试。MFi门户中的产品计划 "认证 "页面将指导你完成特定配件所需的认证步骤,并指出何时完成所有要求。在完成所有MFi认证要求之前,你不得制造、分发或销售任何配件。在开始MFi认证过程之前,你必须测试你的配件,以确保它符合最新的MFi技术规范,通过产品计划 "测试计划 "上的所有适用测试,并与它将声称具有兼容性的每个苹果设备兼容。

天天的博客 2275

通过反射获取当前Activity实例

转自:https://blog.csdn.net/baidu_31093133/article/details/52785580 步骤: 1、 获取ActivityThread中保存的所有的ActivityRecord  2 、从ActivityRecord中获取状态不是pause的Activity并返回,这个Activity就是当前处于活动状态的Activity public stati...

xuwb123xuwb的博客 2742

图形推理2-四大类六提示

图形推理笔记2

小y的学习笔记 6739

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

有关安卓的Activity前后台切换

本文仅是AI问答记录备忘。

x5237732的博客 2785

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

android 判断activity状态,Android获取Activity(应用)的运行状态及其他信息

检测某Activity是否在当前Task的栈顶public static boolean isTopActivy(String cmdName, Context context){ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);List runningTas...

weixin_36337389的博客 721

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Android 判断应用是否在运行以及判断处于顶层的activity

1、必须添加权限: /** * * @Description: TODO 判断activity是否在应用的最顶层 * @param context 上下文 * @param intent intent携带activity * @return boolean true为在最顶层,false为否 * @author Sunday * @date 2016年3

前端梦工厂 3772

android判断当前应用是否启动、app运行状态、某个界面是否在前台工具类整理

/** * 判断当前应用是否启动 * * @param context * @return */ public static boolean getCurrentTask(Context context) { ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACT...

huangwenkui1990的专栏 5647

android判断某个应用或者activity是否在运行

android中判断某个应用或者activity是否在运行

look to the master, follow the master, 6004

如何判断Android应用置于前后台

记录两种获取应用程序置于前后台状态方法。第一种使用Android系统API;第二种使用Activity生命周期。

埋头苦干程序猿 5271

android获取activity状态,Android获取Activity(应用)的执行状态及其它信息

检測某Activity是否在当前Task的栈顶public static boolean isTopActivy(String cmdName, Context context){ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);List runningTas...

weixin_32111725的博客 1119

android 判断activity状态,【已解决】Android中判断当前处于哪个Activity

【背景】android项目中,需要根据当前处于哪个activity去决定后续动作。所以需要去获得当前处于哪个activity。【解决过程】1.搜:android check current activity参考:感觉很麻烦啊。2.参考:需要每个activity都去给onResume添加代码,也很麻烦。3.搜:android current which activity参考:没找到合适的。4.还是参...

weixin_42386361的博客 2986

android 判断当前应用的是否为前台task 判断当前的activity是否为top activity 判断当前应用的是否为后台task

import java.util.List; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; import android.util

u010441701的专栏 2106

Android前后台状态判断及锁屏操作

写在前面: 最近做项目有一个锁屏的功能,需求是:当APP从后台切到前台时,需要打开锁屏页面(5分钟内不锁屏) APP前后台说明   前台:有一个或多个Activity可见   后台:应用内所有Activity不可见 兼容性:Android4.0及以上 ActivityLifecycleCallbacks added in [API level 14] 参考 http://blog.csdn....

qq_35874340的博客 1512
上一篇: Unity3D之Mecanim动画系统学习笔记(七):IK(反向动力学)动画
下一篇: AndroidProcess
cbbbc
博客等级 码龄15年 609粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值