android如何不修改系统代码拦截Activity启动禁止打开某些应用在车机行车过程?-学员答疑总结

android 应用启动监测/拦截,白名单应用 需求:做一个系统服务或者应用;可以根据后台配置的黑白名单,禁用应用启动。如果是黑名单应用,则点击了,也无法启动。 这里不做后台拉取黑名单的动作。只做 如何检测其他应用启动。检测到了,就可以禁止启动了。 具体如下。 这里作为非系统app来进行说明,系统app要简单一些,但差别不大。 知识点及介绍参考文章如下: IActivityController 调用系统hide函数 反射 权限 签名及gradle中如何加载签名,及如何生成相关签名文件 IActivityController 使用IActivityCo 阅读详情

背景:

近来有学员朋友在群里有问到一个很特别的需求,他的原文疑问如下:

在这里插入图片描述
转化一下他的需求如下2个要求:
1、要控制一些app在行车过程禁止打开
2、要求不可以修改任何的系统源,即不修改系统相关代码,即最好可以apk直接实现(当然可以系统app)

需求剖析:
这里其实只是第一个要求很多人可能觉得很简单,学员们纷纷回答直接startActivity时候搞个名单不就好了
学员1回答
这个需要修改system_server代码,所以pass

也有的回答直接在桌面Launcher的applist进行入口判断不然启动
学员2回答
这个学员大概思路就是,可以在桌面applist图标点击进行屏蔽,这个明显不行哈,首先不说改了Launcher代码,最重要是只是applist点击进行屏蔽根本无法覆盖,你能保证你的app启动都是通过桌面点击么,完全有可能其他场景,比如后台service启动,或者其他Activity拉起。

所以关键难度是第二个要求,不允许修改任何的系统代码,那么就需要寻找到系统是否现成有相关的接口可以直接。

实现线索寻找

学员朋友们也在积极的寻找相关的方案,最后有一个积极学员找到了一个如下方法:
frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java

   /**
     * Executing activity start request and starts the journey of starting an activity. Here
     * begins with performing several preliminary checks. The normally activity launch flow will
     * go through {@link #startActivityUnchecked} to {@link #startActivityInner}.
     */
    private int executeRequest(Request request) {
       //省略
        if (mService.mController != null) {
         	       //这里会调用activityStarting来返回abort,这个abort值决定是否启动
                abort |= !mService.mController.activityStarting(watchIntent,
                        aInfo.applicationInfo.packageName);
            } catch (RemoteException e) {
                mService.mController = null;
            }
        }

//省略
        if (abort) {
            //判断如果是abort,则直接返回,不进行启动
            return START_ABORTED;
        }

上面核心就是在系统启动Activity时候,会调用一下mController的activityStarting方法来确定是否要抛弃启动。那么这里的activityStarting具体如何实现呢?这里需要先了解mController是啥类型

    IActivityController mController = null;

实际上就是一个binder通讯的bp,看看对应aidl的接口说明:
frameworks/base/core/java/android/app/IActivityController.aidl


/**
 * Testing interface to monitor what is happening in the activity manager
 * while tests are running.  Not for normal application development.
 * {@hide}
 */
interface IActivityController
{
    /**
     * The system is trying to start an activity.  Return true to allow
     * it to be started as normal, or false to cancel/reject this activity.
     */
    boolean activityStarting(in Intent intent, String pkg);
    
    /**
     * The system is trying to return to an activity.  Return true to allow
     * it to be resumed as normal, or false to cancel/reject this activity.
     */
    boolean activityResuming(String pkg);
    
    /**
     * An application process has crashed (in Java).  Return true for the
     * normal error recovery (app crash dialog) to occur, false to kill
     * it immediately.
     */
    boolean appCrashed(String processName, int pid,
            String shortMsg, String longMsg,
            long timeMillis, String stackTrace);
    
    /**
     * Early call as soon as an ANR is detected.
     */
    int appEarlyNotResponding(String processName, int pid, String annotation);

    /**
     * An application process is not responding.  Return 0 to show the "app
     * not responding" dialog, 1 to continue waiting, or -1 to kill it
     * immediately.
     */
    int appNotResponding(String processName, int pid, String processStats);

    /**
     * The system process watchdog has detected that the system seems to be
     * hung.  Return 1 to continue waiting, or -1 to let it continue with its
     * normal kill.
     */
    int systemNotResponding(String msg);
}

注释明显看出IActivityController实际上是监测AMS一些实际的发生接口,一般用于一些测试来监测系统的Activity的一些状态,这个不针对普通第三方app,属于一个隐藏api,不过对于系统app肯定是可见的。
那么下面重点就是看看这个IActivityController怎么用的,这里找到了一个am命令案例,主要有如下几步:
frameworks/base/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
1 构造出IActivityController的实现类
可以看到,主要是对IActivityController.Stub


    static final class MyActivityController extends IActivityController.Stub {
        //省略
        @Override
        public boolean activityResuming(String pkg) {
          //省略
            return true;
        }

        @Override
        public boolean activityStarting(Intent intent, String pkg) {
            if (!shouldHandlePackageOrProcess(pkg)) {
                return true;
            }
  //省略
            return true;
        }

2 调用ams接口设置Controller
frameworks/base/services/core/java/com/android/server/am/ActivityManagerShellCommand.java

   void run() throws RemoteException {
                mInterface.setActivityController(this, mMonkey);

最后这里会跨进程到atms,设置到atms的mController,其实就是IActivityController的bp传递到了atms,方便atms有啥动作时候进行回调
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

@Override
public void setActivityController(IActivityController controller, boolean imAMonkey) {
    mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
            "setActivityController()");//注意这类有权限检测
    synchronized (mGlobalLock) {
        mController = controller;
        mControllerIsAMonkey = imAMonkey;
        Watchdog.getInstance().setActivityController(controller);
    }
}

上面分析完成后总结流图如下:
在这里插入图片描述

实战体验验证:

根据源码可以知道其实am命令就可以测试这个接口:

emu64x:/ # am -h | grep monitor 
  monitor [--gdb <port>] [-p <TARGET>] [-s] [-c] [-k]
      Start monitoring for crashes or ANRs.

大家只需要关心-p参数就是指定的进程名字,一般就是包名。

不做任何修改使用am monitor命令监测一下短信Activity的启动

emu64x:/ # am monitor -p  com.android.messaging

Monitoring activity manager...  available commands:
(q)uit: finish monitoring
** Activity starting: com.android.messaging
** Activity starting: com.android.messaging

可以看到这里有输出 Activity starting: com.android.messaging,而且画面也正常显示短信,那么如果我们对 IActivityController.Stub的实现方法activityStarting返回false呢?
在这里插入图片描述
发现点击短信时候再也无法打开Activity,点击其他的Activity没有问题.
在这里插入图片描述
上图可以看到短信无法打开,但是其他电话可以打开。

其实其他Monkey等也有相关的案例可以参考:

development/cmds/monkey/src/com/android/commands/monkey/Monkey.java

在这里插入图片描述

所以大家完全可以在自己系统app上也类似做一个。

使用要注意以下几点:

1、继承实现 IActivityController.Stub里面的任何方法,一定不要做任何的耗时操作,因为这里是atms同步binder调用的

2、调用setActivityController注意声明相关权限SET_ACTIVITY_WATCHER

更多framework实战干货,请关注下面“千里马学框架”

Android Activity——启动过程探索(二) 在《Android Activity——启动过程探索(一)》中我们知道了Activity启动的生命周期回调,并且分析了其中当前Activity的 onPause() 和新打开的Activity的 onCreate() 回调方法执行步骤,在这篇文章中接着分析新打开的Activity的 onStart()和onResume()回调执行过程。 注意:以下分析过程,源码版本为 Android 10(Api 29),不同Android版本可能有一些差别。 新的Activity调用 onStart() 根据上图查看对 阅读详情

相关推荐

限制apk使用时长第二篇-限制/拦截Apk启动-应用锁功能

看到手机端有应用限时使用;之前有客户提到过教育软件限制使用时长的客需,后面负责这个客需的同事没有搞定,没有去实现,这个客需点废弃掉了那么自己就私下里去实现这样的一个功能。这个方法允许设置一个 IActivityController 接口的实现,AMS 会在关键的活动生命周期事件发生时回调该控制器。这通常用于:系统测试框架(如 Monkey 测试)调试工具特殊的系统监控场景上面着重分析、了解了AMS里面的setActivityController 方法,以此功能实现 限时应用中拦截应用功能。

十年饮冰,难凉热血 1387

Android之Monkey源码分析(第七篇:Monkey程序如何获知App崩溃,然后自己停止运行的逻辑分析)

前言 Monkey程序是用来执行稳定性测试的,被测App如果出现崩溃,Monkey程序会第一时间收集日志,App出现ANR,Monkey程序也会第一时间收集日志,这些都究竟是怎么做到的呢?这就依靠的是ActivityController ...

王员外的博客 5000

Android10 AMS详情分析四 (Activity 的管理)

Android 是如何管理Activity的,

qq_18420641的博客 1062

解决setActivityController导致部分功能无法执行

项目背景 :需要监听某个Activity打开执行某些操作,于是选取ActivityManagerNative.getDefault().setActivityController()监听,使用后此功能正常执行,然而测试发现一些系统无法正常调用,于是排查得知ActivityManager.isUserAMonkey()获取的结果值为true,导致系统认为是在Monkey测试,于是部分功能无法调用。

qq_44203816的博客 455

Flowable多数据源实战:从配置到指定Schema的避坑指南

本文详细介绍了Flowable多数据源配置的实战指南,包括基础配置、数据源Bean创建、指定Schema的进阶配置以及常见问题排查。通过具体代码示例和避坑建议,帮助开发者高效实现多租户系统中的工作流引擎集成,特别强调了schema设置和事务管理的注意事项。

weixin_30824599的博客 486

Cadence 17.2 OrCAD原理图库实战:从零创建电阻/电容/LED元件(附封装技巧)

本文以Cadence 17.2 OrCAD为核心,详细讲解了如何从零开始工程化地创建电阻、电容、LED等原理图库元件。内容涵盖库架构设计、符号绘制、引脚属性管理、封装关联技巧以及设计规则检查,旨在帮助硬件工程师构建规范、可复用且易于维护的元件库,为高效PCB设计奠定坚实基础。

weixin_29195615的博客 400

深入理解IActivityController

一、研究背景 最近在学习别人代码,在代码中使用IActivityController.aidl统计设备中所有app的状态,包括activityStarting、activityResuming、appCrashed、appEarlyNotResponding、appNotResponding、systemNotResponding。后面我们会对这些方法单独介绍。发现这个写法很神奇,故想学习一下,...

JianYeung的博客 5746

从‘最速控制’到代码:深入拆解韩京清ADRC中TD跟踪器的fhan函数(含Matlab/Simulink实例)

本文深入解析韩京清ADRC中的fhan函数,从理论到代码实现,详细拆解其在Matlab/Simulink中的应用。通过分析最速控制问题和非线性TD的连续形式,揭示fhan函数在信号处理和噪声抑制中的独特优势,并提供工程实践中的参数整定和优化技巧。

weixin_42659194的博客 247

监听系统任意一个app启动代码

在项目开发中碰到一个问题,需要监听到任意一个app打开,不管是手动打开还是自动跳转到别的apk,都可以捉取到启动信息。参考了一些资料发现有两种方式。第一种:实现IActivityController.Stub这个类,系统本身有这个接口可以调用的,但是因为系统是隐藏该接口的,所以需要自己实现它。继承了这个类后它会重写activityStarting,这个可以抓取任意启动的app的包名。代码如下:

格物的专栏 6324

今天出一个candence 17.4 allego的安装教程

7、安装完成,接下来进行补丁更新,找到Hotfix_SPB17.40.035_wint.iso软件 ,右击鼠标选择装载。6、因为之前选择的定制安装,这一步不知道具体要安装啥,因此都勾选,点击NECK,接下来等待安装完成。后面经过仔细对比,发现是前面更新补丁时选择了F盘,F盘是candence安装包,不是补丁。8、在破戒大师里选择安装更新补丁,并找到刚才装载的安装包里的程序,点击下一步。3、打开破戒大师,找到安装candence进行如下图选择,点击下一步。有耐心的人可以重新卸了再装一边,我就不卸了,直接装。

hcvinh的博客 2726

AI提示词实战:用EARS语法5步搞定产品需求拆解(附完整案例)

本文详细介绍了如何运用EARS语法将模糊的产品需求进行原子化拆解,转化为清晰、可执行的结构化指令。通过一个完整的自由职业者项目管理工具案例,演示了从原始需求分析到构建增强AI提示词的五步实战流程,帮助产品经理和技术人员实现高效、精准的需求传达与协作。

nokia的博客 1033

Android实现APP启动监听和拦截

可以实现应用锁

lontano_0406的博客 3622

IC617多线程仿真卡死?手把手教你用TigerVNC替换解决ADE XL Explorer问题(附Manjaro/Centos8实测)

本文针对IC617在Manjaro、CentOS 8等高版本Linux系统中运行ADE XL Explorer进行多线程仿真时出现的卡死问题,提供了详细的诊断与解决方案。文章指出问题根源在于软件内置的旧版VNC组件不兼容,并手把手指导用户通过使用TigerVNC替换原组件来彻底解决,附有在Manjaro和CentOS 8系统上的实测步骤与验证方法。

hill8的博客 774

【Activity】基于Android9.0的Activity的finish流程分析

目录 1. IActivityController.aidl 1.1 接口中的方法说明 1.2 应用如何使用IActivityController 1.2.1 自行类实现IActivityController.Stub 1.2.2 获取IActivityManager代理对象并调用setActivityController 2. finish流程 本文章意在分析Activity的fi...

明朗晨光的专栏 3971

11、Windows Autopilot 部署与设备注册全攻略

本文详细介绍了Windows Autopilot的完整部署流程,涵盖注册配置文件设置、注册状态页面(ESP)配置、设备注册方法(包括CSV导入、JSON注入、在线注册等)、自动化脚本实现及故障排除技巧。通过手动与PowerShell自动化两种方式指导用户完成配置,并提供流程图、最佳实践和常见问题解答,帮助IT管理员高效实现设备零接触部署与管理。

ii567的博客 342

深入解析雪球网股票行情数据爬取:基于WebSocket与API的实时数据获取技术实践

本文详细介绍了如何使用Python爬虫技术获取雪球网的股票行情数据,涵盖了WebSocket实时数据连接和RESTful API接口调用两种主要技术方案。完整的WebSocket客户端,支持实时行情订阅和数据处理功能丰富的API客户端,支持多种数据类型的获取数据存储和管理系统,使用SQLite进行数据持久化实时监控和预警系统,支持自定义预警规则技术指标计算,提供基本的数据分析功能。

2201_76125261的博客 1255

IActivityController实现app启动监听

文章目录理解IActivityController一 IActivityController.aidl简介二代码实现 理解IActivityController 一 IActivityController.aidl简介 IActivityController.aidl是系统自带的aidl,在Am的内部类MyActivityController有实现这个aidl接口,主要用于app状态监听控制。对于应用开发者来说,此接口为给我们提供了各种可能性,比如统计每个app启动次数,crash次数等。这里我们先看下他的

d773689630的专栏 1884

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

多种方式实现动态替换Android默认桌面Launcher

动态替换Android默认桌面Launcher 文章目录动态替换Android默认桌面Launcher背景简介技术方案三种方案方案一方案二方案三风险 背景简介 Launcher-是安卓系统中的桌面启动器,安卓系统的桌面UI统称为Launcher。Launcher是安卓系统中的主要程序组件之一,安卓系统中如果没有Launcher就无法启动Android 当前场景 现在安卓设备应用越来越广泛,有...

rui1605的博客 2万+

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

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

最近在开发的过程中遇到这样一个问题,Android13项目带有GMS应用和服务的情况下,如果在系统中操作Location(位置信息),com.google.android.gms这个应用会弹出一个关于Location相关的提示框,因此非常影响我当下的业务需求和使用,所以我们研究如何屏蔽这个来自GMS的应用发出的弹窗。拦截一个和拦截这个包名中的全部来源,在本质上还是有区别的。因为我项目中的业务是在某个应用的使用过程中不想要出现这个提示框,那么我就要获取到当前顶层运行的应用和Activity,

不要用过去的错误约束现在的自己。 1982

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

onDestroy原因

Activity原因: onconfigchange(横竖屏) activity.finish framework remove-task:"remove-task" wm_finish_activity: [MainActivity,app-request] finish-imm:finishIfPossible clear rencenttask wm_destroy_activity: [MainActivity,finish-imm:recent-task-trimmed] useru

langjian2012的专栏 649

Android app启动流程分析

app的启动方式 App启动有三种状态,每种状态都会影响App对用户可感知的时间:冷启动,热启动和温启动。 注意:在冷启动中,应用从头开始启动。在其他状态下,系统需要将后台运行中的应用带入前台。建议您始终在假定冷启动的基础上进行优化。这样做也可以提升温启动和热启动的性能。 冷启动 冷启动是指应用从头开始启动:系统进程在冷启动后才创建应用进程。发生冷启动的情况包括应用自设备启动后或系统终止应用后首次启动 特点:冷启动因为系统会重新创建一个新的进程分配给它,所以会先创建和初始化Application类,再创建和

离开家坐火车的博客 1056

Android AMS源码阅读分析(一)

最近学习了柯元旦所著《Android内核剖析》之AMS原理篇章,结合自己的理解以及对源码的分析,记录一下学习心得,AMS代码非常多,而且和Application以及Activity之间的交互也相对繁杂,这里学习大致的主干流程,之后有时间会再去细看。 AMS的功能 AMS的功能可以概述为以下三个: 首先来看看这个统一调度各个应用程序之间的activity,可以把AMS理解成一个管理员,管理着手机里...

qq_26984087的博客 7282

Android实现监听APP启动、前台和后台

IActivityController.aidl是系统自带的aidl,在Am的内部类MyActivityController有实现这个aidl接口,主要用于app状态监听控制。对于应用开发者来说,此接口为给我们提供了各种可能性,比如统计每个app启动次数,crash次数等。这里我们先看下他的方法:activityStarting:当系统正在启动一个activity时会触发,当返回true,表示允许启动。当返回状态noraml/false分别表示停止/拒绝启动activity。

纸上得来终觉浅,绝知此事要躬行 1万+

Android 中拦截 Activity 的启动(拦截系统的 Intent)

目的最近因为项目需要,我们自己定制的只能硬件里面没有系统的电话、相机、短信、浏览器等组件,如果其他 App 来发 Intent 调用的话,程序就会崩溃。要求我们做一个系统拦截,拦截这些意图。有几种方法: 1.写一个 App 专门来拦截这些 Intent。(通用性比较高) 2.在源码层做拦截。(比较简单)给程序加锁360等相关程序可以给我们装上的应用程序加锁,也就是我们在点开某个应用程序的时候,会

有酒平步上青天 1万+

如何生成内部hide接口实例并通过反射作为参数进行传递

一、前言 在android系统源码中,有很多的api是隐藏的,在eclipse中通过sdk是无法访问到的。这些api有的是整个类/接口、有的是某个具体的方法、或者变量,在源码中通过文档注释内的“@hide”字符进行标识。如果我们需要去访问这些被hide的方法、类,可以采用如下两种方式: 1、在源码环境下进行访问,即将我们的工程放到源码下进行编译,这样是可以访问的; 2、通过java的反射机制

4381
上一篇: 自由开发者aosp源码修改部分如何提交保存上传服务器?-记录AI帮助我们实现过程
下一篇: Android.bp如何快速掌握经验分享
千里马学框架
博客等级 码龄6年 1万+粉丝 650原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马学框架

帮助你了,就请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值