Android在AMS中拦截某个Activity的启动

2024-04-26 01:36

本文主要是介绍Android在AMS中拦截某个Activity的启动,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • Android在AMS中拦截某个具体Activity的启动
    • 方案一(推荐):在ActivityTaskManagerService.startActivityAsUser方法中去作拦截
    • 方案二:在Dialog.show()方法中直接对这个包名所创建的Dialog做限制

Android在AMS中拦截某个具体Activity的启动

最近在开发的过程中遇到这样一个问题,Android13项目带有GMS应用和服务的情况下,如果在系统中操作Location(位置信息),com.google.android.gms这个应用会弹出一个关于Location相关的提示框,因此非常影响我当下的业务需求和使用,所以我们研究如何屏蔽这个来自GMS的应用发出的弹窗。

通过adb命令可以查询当前Activity的包名和具体Calss名

adb shell dumpsys activity |findstr "mFocus"

方案一(推荐):在ActivityTaskManagerService.startActivityAsUser方法中去作拦截

system/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

AMS(ActivityManagerService)先校验一下Activity的正确性,如果正确的话,会暂存一下Activity的信息。然后,AMS会通知Launcher程序pause Activity(在AMS所在进程执行)

下面是AMS创建Activity的调用流程():

  • ActivityManagerService.startActivity

  • ActivityTaskManagerService.startActivity

  • ActivityTaskManagerService.startActivityAsUser(我是在这一步进行Activity的拦截的,因为这个方法中的参数比较明显,基本可以直接调用)

private final String GOOGLE_PACKAGE = "com.google.android.gms";
private final String GOOGLE_LOCATION_ACTIVITY = "com.google.android.gms.location.settings.LocationOffWarningActivity";private int startActivityAsUser(IApplicationThread caller, String callingPackage,@Nullable String callingFeatureId, Intent intent, String resolvedType,IBinder resultTo, String resultWho, int requestCode, int startFlags,ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {assertPackageMatchesCallingUid(callingPackage);enforceNotIsolatedCaller("startActivityAsUser");//........省略多余代码.........// for disable google pop-up location alerts beginActivityInfo aInfo = mTaskSupervisor.resolveActivity(intent, resolvedType,startFlags, profilerInfo, userId, Binder.getCallingUid());Log.d(TAG, "callingPackage = " + callingPackage);Log.d(TAG, "aInfo.taskAffinity = " + aInfo.taskAffinity);Log.d(TAG, "getCurrentApp() = " + getCurrentApp());if (GOOGLE_PACKAGE.equals(callingPackage) && GOOGLE_LOCATION_ACTIVITY.equals(aInfo.taskAffinity))) {Log.d(TAG, "Block Google location pop-ups");return ActivityManager.START_CANCELED;}// for disable google pop-up location alerts enduserId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");//........省略多余代码.........
}

方案二:在Dialog.show()方法中直接对这个包名所创建的Dialog做限制

在上述第一个方案之前,我一开始遇到这个问题,脑海里直接想的是在Dialog.show()方法中里面去做拦截(因为弹窗本身就是一个Dialog)。我确实也尝试了,下面是我修改的代码。
但是后来我发现这样修改后,我思考了一下,会存在两个问题,例如:

1.在Dialog中只能通过包名去拦截,不能直接拦截某一个指定的弹窗(或者说是Activity)。拦截一个和拦截这个包名中的全部来源,在本质上还是有区别的。

2.虽然这种方式可以达到拦截Dialog弹窗的目的,但是依旧还是会走Activity的创建流程。既然弹窗都屏蔽掉了,那这样会有什么影响呢?
因为我项目中的业务是在某个应用的使用过程中不想要出现这个提示框,那么我就要获取到当前顶层运行的应用和Activity,

system/frameworks/base/core/java/android/app/Dialog.java
private final String GOOGLE_PACKAGE = "com.google.android.gms";public void show() {//........省略多余代码.........onStart();mDecor = mWindow.getDecorView();// for disable google pop-up location alerts beginLog.d(TAG, "mContext.getPackageName() = " + mContext.getPackageName());if(GOOGLE_PACKAGE_NAME.equals(mContext.getPackageName())) { Log.d(TAG, "Disable Google location pop-ups");return;}// for disable google pop-up location alerts endif (mActionBar == null && mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {final ApplicationInfo info = mContext.getApplicationInfo();mWindow.setDefaultIcon(info.icon);mWindow.setDefaultLogo(info.logo);mActionBar = new WindowDecorActionBar(this);}//........省略多余代码.........
那天,我听到了种子破土的声音,又细微又坚定。

这篇关于Android在AMS中拦截某个Activity的启动的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/936357

相关文章

Android实现图片浏览功能的示例详解(附带源码)

《Android实现图片浏览功能的示例详解(附带源码)》在许多应用中,都需要展示图片并支持用户进行浏览,本文主要为大家介绍了如何通过Android实现图片浏览功能,感兴趣的小伙伴可以跟随小编一起学习一... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码

在Android中使用WebView在线查看PDF文件的方法示例

《在Android中使用WebView在线查看PDF文件的方法示例》在Android应用开发中,有时我们需要在客户端展示PDF文件,以便用户可以阅读或交互,:本文主要介绍在Android中使用We... 目录简介:1. WebView组件介绍2. 在androidManifest.XML中添加Interne

Android协程高级用法大全

《Android协程高级用法大全》这篇文章给大家介绍Android协程高级用法大全,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友跟随小编一起学习吧... 目录1️⃣ 协程作用域(CoroutineScope)与生命周期绑定Activity/Fragment 中手

SpringBoot通过main方法启动web项目实践

《SpringBoot通过main方法启动web项目实践》SpringBoot通过SpringApplication.run()启动Web项目,自动推断应用类型,加载初始化器与监听器,配置Spring... 目录1. 启动入口:SpringApplication.run()2. SpringApplicat

解决Nginx启动报错Job for nginx.service failed because the control process exited with error code问题

《解决Nginx启动报错Jobfornginx.servicefailedbecausethecontrolprocessexitedwitherrorcode问题》Nginx启... 目录一、报错如下二、解决原因三、解决方式总结一、报错如下Job for nginx.service failed bec

Spring Boot项目如何使用外部application.yml配置文件启动JAR包

《SpringBoot项目如何使用外部application.yml配置文件启动JAR包》文章介绍了SpringBoot项目通过指定外部application.yml配置文件启动JAR包的方法,包括... 目录Spring Boot项目中使用外部application.yml配置文件启动JAR包一、基本原理

Android 缓存日志Logcat导出与分析最佳实践

《Android缓存日志Logcat导出与分析最佳实践》本文全面介绍AndroidLogcat缓存日志的导出与分析方法,涵盖按进程、缓冲区类型及日志级别过滤,自动化工具使用,常见问题解决方案和最佳实... 目录android 缓存日志(Logcat)导出与分析全攻略为什么要导出缓存日志?按需过滤导出1. 按

解决若依微服务框架启动报错的问题

《解决若依微服务框架启动报错的问题》Invalidboundstatement错误通常由MyBatis映射文件未正确加载或Nacos配置未读取导致,需检查XML的namespace与方法ID是否匹配,... 目录ruoyi-system模块报错报错详情nacos文件目录总结ruoyi-systnGLNYpe

解决hive启动时java.net.ConnectException:拒绝连接的问题

《解决hive启动时java.net.ConnectException:拒绝连接的问题》Hadoop集群连接被拒,需检查集群是否启动、关闭防火墙/SELinux、确认安全模式退出,若问题仍存,查看日志... 目录错误发生原因解决方式1.关闭防火墙2.关闭selinux3.启动集群4.检查集群是否正常启动5.

Springboot项目启动失败提示找不到dao类的解决

《Springboot项目启动失败提示找不到dao类的解决》SpringBoot启动失败,因ProductServiceImpl未正确注入ProductDao,原因:Dao未注册为Bean,解决:在启... 目录错误描述原因解决方法总结***************************APPLICA编