Android系统 自定义开机广播,禁止后台服务,运行手动安装应用接收开机广播

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: Android系统 自定义开机广播,禁止后台服务,运行手动安装应用接收开机广播

Android 高版本引入了一些限制和变化,不像以前7.1以下的方便,对我们客制化搬砖效率和用户都有一定的影响。例如,Android 8+限制了后台应用启动活动的能力,增加了后台位置访问权限的要求,以及禁止了手动安装的应用在未打开的情况下接收开机广播。

本文将介绍如何通过修改Android源码来实现以下三个目标:

  • 自定义开机广播:在系统启动完成后发送一个自定义的广播,让自定义的应用可以接收并执行相应的操作。
  • 禁止后台服务:取消对后台应用启动服务的限制,让任何应用都可以在后台运行服务。
  • 运行手动安装应用接收开机广播:允许手动安装的应用在未打开的情况下接收系统的开机广播,让它们可以在开机后自动启动。

自定义开机广播

背景知识

开机广播是一种特殊的系统广播,它在系统启动完成后发送给所有注册了android.intent.action.BOOT_COMPLETED过滤器的应用。开机广播可以让应用在开机后执行一些初始化或定期的任务,例如更新数据,启动服务,设置闹钟等。

修改方法

要实现自定义开机广播,我们需要修改两个文件:

  • frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:这个文件是ActivityManagerService类的源码,它负责管理系统中所有活动、进程、服务和广播等组件。我们需要修改它的broadcastIntentLocked方法,这个方法是用来发送广播的核心方法。
  • frameworks/base/services/core/java/com/android/server/am/UserController.java:这个文件是UserController类的源码,它负责管理系统中所有用户和用户相关的操作。我们需要修改它的finishUserUnlockedCompleted方法,这个方法是在用户解锁完成后调用的。

具体的修改步骤如下:

  1. ActivityManagerService.java中找到broadcastIntentLocked方法,在第15846行添加一行代码:
|| "com.ln28.intent.action.BOOT_COMPLETED".equals(action)

这样就可以让我们自定义的开机广播通过系统的保护检查,不被拒绝发送。

  1. 在同一个文件中,在第15906行注释掉以下代码:
if (callerApp != null) {
    Log.wtf(TAG, "Sending non-protected broadcast " + action
                    + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
            new Throwable());
} else {
    Log.wtf(TAG, "Sending non-protected broadcast " + action
                    + " from system uid " + UserHandle.formatUid(callingUid)
                    + " pkg " + callerPackage,
            new Throwable());
}

这样就可以避免发送我们自定义的开机广播时产生不必要的警告日志。

  1. UserController.java中找到finishUserUnlockedCompleted方法,在第729行添加以下代码:
///ln28 add custom broadcast cast  
final Intent custombootIntent = new Intent("com.ln28.intent.action.BOOT_COMPLETED", null);
custombootIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
custombootIntent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
            | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
            | Intent.FLAG_RECEIVER_OFFLOAD);
final int callinguid = Binder.getCallingUid();
final int callingpid = Binder.getCallingPid();
FgThread.getHandler().post(() -> {
    mInjector.loadUserRecents(userId);
});
FgThread.getHandler().post(() -> {
    mInjector.broadcastIntent(custombootIntent,
            null, null, 0, null, null,
            null, AppOpsManager.OP_NONE,
            null, true, false, MY_PID, SYSTEM_UID, callinguid,
            callingpid, userId);
}); 
///ln28 add custom broadcast cast

这样就可以在用户解锁完成后发送我们自定义的开机广播,其中com.ln28.intent.action.BOOT_COMPLETED是我们自定义的广播的动作,userId是当前用户的ID,callinguidcallingpid是调用者的UID和PID,MY_PIDSYSTEM_UID是系统的PID和UID,其他参数可以参考broadcastIntentLocked方法的注释。

修改效果

修改完成后,我们需要重新编译并刷入系统。可以在任何应用中注册一个广播接收器,用来接收我们自定义的开机广播。例如,我们可以在AndroidManifest.xml中添加以下代码:

<receiver android:name=".CustomBootReceiver">
    <intent-filter>
        <action android:name="com.ln28.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>

然后,在CustomBootReceiver类中实现onReceive方法,用来处理我们自定义的开机广播。例如,我们可以在onReceive方法中打印一条日志:

public class CustomBootReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d("CustomBootReceiver", "Received custom boot completed broadcast");
    }
}

这样,当我们开机并解锁后,就可以在日志中看到以下信息:

08-07 17:00:11.062  1229  1229 D CustomBootReceiver: Received custom boot completed broadcast

这说明我们成功地实现了自定义开机广播的功能。

注意: 测试发现自定义开机广播比系统自带的开机广播 要早1分钟!!

禁止后台服务和

背景知识

后台服务是一种在后台运行的组件,它可以执行一些不需要用户交互的长时间运行的任务。后台服务通常通过调用startServicebindService方法来启动。

但是,从Android 8.0(API级别26)开始,系统对后台服务的启动做了一些限制。具体来说,当应用处于后台时(即没有任何可见的活动),它不能直接启动服务。如果它尝试这样做,系统会抛出一个IllegalStateException异常,并显示以下错误信息:

java.lang.IllegalStateException: Not allowed to start service Intent { cmp=com.xxx/.MyService }: app is in background uid UidRecord{...}

为了避免这个异常,应用需要使用以下两种方式之一来启动服务:

  • 使用前台服务:前台服务是一种显示一个通知栏图标的服务,它表明该服务正在执行一些用户关心的操作。要使用前台服务,应用需要在服务启动后调用startForeground方法,并传递一个有效的通知对象。
  • 使用作业调度器:作业调度器是一种让应用在满足一定条件时执行一些任务的机制。要使用作业调度器,应用需要创建一个继承自JobService的类,并在其中实现任务的逻辑。然后,应用需要使用JobScheduler类来创建一个JobInfo对象,并指定任务的触发条件和执行策略。最后,应用需要使用schedule方法来提交任务给系统

修改方法

要实现禁止后台服务的功能,我们只需要修改一个文件:

  • frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:这个文件是ActivityManagerService类的源码,它负责管理系统中所有活动、进程、服务和广播等组件。我们需要修改它的appRestrictedInBackgroundLocked方法,这个方法是用来检查应用是否可以在后台启动服务的。

具体的修改步骤如下:

  1. ActivityManagerService.java中找到appRestrictedInBackgroundLocked方法,在第6275行注释掉以下代码:
if (packageTargetSdk >= Build.VERSION_CODES.O) {
    if (DEBUG_BACKGROUND_CHECK) {
        Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
    }
    return ActivityManager.APP_START_MODE_DELAYED_RIGID;
}

这样就可以取消对目标SDK为O+的应用的后台服务启动限制。

修改效果

修改完成后,我们需要重新编译并刷入系统。然后,我们可以在任何应用中创建一个后台服务,并在AndroidManifest.xml中声明它。例如,我们可以创建一个MyService类,继承自Service,并在其中打印一条日志:

public class MyService extends Service {
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("MyService", "Service started");
        return START_STICKY;
    }
}

然后,在AndroidManifest.xml中添加以下代码:

<service android:name=".MyService" />

这样,当我们在应用中调用以下代码时:

startService(new Intent(this, MyService.class));

就可以在日志中看到以下信息:

08-07 17:41:14.125  1229  1229 D MyService: Service started

这说明我们成功地实现了禁止后台服务的功能。

运行手动安装应用接收开机广播

背景知识

手动安装应用是指通过非官方渠道(例如APK文件)安装的应用,它们通常不受系统的信任和管理。手动安装应用在Android 11中受到了一些限制,例如不能在后台访问剪贴板,不能请求敏感权限,以及不能在未打开的情况下接收开机广播。

开机广播是一种特殊的系统广播,它在系统启动完成后发送给所有注册了android.intent.action.BOOT_COMPLETED过滤器的应用。开机广播可以让应用在开机后执行一些初始化或定期的任务,例如更新数据,启动服务,设置闹钟等。

修改方法

要实现运行手动安装应用接收开机广播的功能,我们需要修改一个文件:

  • frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:这个文件是ActivityManagerService类的源码,它负责管理系统中所有活动、进程、服务和广播等组件。

具体的修改步骤如下:

  1. 在同一个文件中,在第15957行注释掉以下代码:
intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);

并在下一行添加以下代码:

intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);

这样就可以让后台服务启动时发送的广播包含已停止的应用,让它们可以接收到广播并启动服务。

这样就可以让所有应用都不受安装来源的限制,无论它们是不是即时应用。

修改效果

修改完成后,我们需要重新编译并刷入系统。可以在任何手动安装的应用中注册一个广播接收器,用来接收系统的开机广播。例如,我们可以在AndroidManifest.xml中添加以下代码:

<receiver android:name=".BootReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>

然后,在BootReceiver类中实现onReceive方法,用来处理系统的开机广播。例如,我们可以在onReceive方法中打印一条日志:

public class BootReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d("SystemBootReceiver", "Received boot completed broadcast");
    }
}

这样,当我们开机并解锁后,就可以在日志中看到以下信息:

08-07 17:01:14.175  1229  1229 D SystemBootReceiver: Received system boot completed broadcast

这说明我们成功地实现了运行手动安装应用接收开机广播的功能。

总结

本文介绍了如何通过修改Android源码来实现三个目标:

  • 自定义开机广播:在系统启动完成后发送一个自定义的广播,让感兴趣的应用可以接收并执行相应的操作。
  • 禁止后台服务:取消对后台应用启动服务的限制,让任何应用都可以在后台运行服务。
  • 运行手动安装应用接收开机广播:允许手动安装的应用在未打开的情况下接收系统的开机广播,让它们可以在开机后自动启动。
相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
1月前
|
前端开发 Java Shell
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
183 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
1月前
|
Dart 前端开发 Android开发
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
59 4
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
3月前
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
112 14
|
3月前
|
搜索推荐 前端开发 测试技术
打造个性化安卓应用:从设计到开发的全面指南
在这个数字时代,拥有一个定制的移动应用不仅是一种趋势,更是个人或企业品牌的重要延伸。本文将引导你通过一系列简单易懂的步骤,从构思你的应用理念开始,直至实现一个功能齐全的安卓应用。无论你是编程新手还是希望拓展技能的开发者,这篇文章都将为你提供必要的工具和知识,帮助你将创意转化为现实。
|
3月前
|
Java Android开发 开发者
探索安卓开发:构建你的第一个“Hello World”应用
在安卓开发的浩瀚海洋中,每个新手都渴望扬帆起航。本文将作为你的指南针,引领你通过创建一个简单的“Hello World”应用,迈出安卓开发的第一步。我们将一起搭建开发环境、了解基本概念,并编写第一行代码。就像印度圣雄甘地所说:“你必须成为你希望在世界上看到的改变。”让我们一起开始这段旅程,成为我们想要见到的开发者吧!
104 0
|
5天前
|
JavaScript Linux 网络安全
Termux安卓终端美化与开发实战:从下载到插件优化,小白也能玩转Linux
Termux是一款安卓平台上的开源终端模拟器,支持apt包管理、SSH连接及Python/Node.js/C++开发环境搭建,被誉为“手机上的Linux系统”。其特点包括零ROOT权限、跨平台开发和强大扩展性。本文详细介绍其安装准备、基础与高级环境配置、必备插件推荐、常见问题解决方法以及延伸学习资源,帮助用户充分利用Termux进行开发与学习。适用于Android 7+设备,原创内容转载请注明来源。
54 19
|
1月前
|
JavaScript 搜索推荐 Android开发
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
69 8
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
|
2月前
|
缓存 前端开发 Android开发
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
121 12
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
|
1月前
|
安全 Android开发 iOS开发
escrcpy:【技术党必看】Android开发,Escrcpy 让你无线投屏新体验!图形界面掌控 Android,30-120fps 超流畅!🔥
escrcpy 是一款基于 Scrcpy 的开源项目,使用 Electron 构建,提供图形化界面来显示和控制 Android 设备。它支持 USB 和 Wi-Fi 连接,帧率可达 30-120fps,延迟低至 35-70ms,启动迅速且画质清晰。escrcpy 拥有丰富的功能,包括自动化任务、多设备管理、反向网络共享、批量操作等,无需注册账号或广告干扰。适用于游戏直播、办公协作和教育演示等多种场景,是一款轻量级、高性能的 Android 控制工具。
|
2月前
|
Dart 前端开发 Android开发
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
46 1
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈

热门文章

最新文章