当前位置: 首页 > news >正文

Android 源码集成可卸载 APP

android系统包含三类APP: 1、可自由卸载APP安装在 /data/app目录下。 2、系统APP放在 /system/app目录。 3、特权APP放在 /system/priv-app目录。

系统编译后,打包前, /data分区不起作用,因此系统打包前,可以先将APP全部拷贝到 /system分区的 /system/usr/app目录下。

1、拷贝APP暂存到 /system/usr/app 目录

 在 /build/target/product/base_product.mk中添加如下命令, 会将 /apps/apps目录下的所有文件拷贝到 /system/usr/app ,将 shell脚本拷贝到 /system/bin目录

# 拷贝APP
PRODUCT_COPY_FILES += $(call find-copy-subdir-files,*,/data1/rom/android/lineageOS2/apps/apps,/system/usr/app)
# 拷贝shell
PRODUCT_COPY_FILES += $(call find-copy-subdir-files,*,/data1/rom/android/lineageOS2/apps/shell,/system/bin)

2、绕过拷贝 .apk文件时校验

 注释 /build/core/Makefile 如下 apk拷贝报错代码

define check-product-copy-files
$(if $(filter %.apk, $(1)),$(error \Prebuilt apk found in PRODUCT_COPY_FILES: $(1), use BUILD_PREBUILT instead!))
endef

3、系统启动执行init.rc脚本时,拷贝APP到 /data分区

在 init.rc文件中定义如下service , 并在 on boot 事件中 执行 preinstall

service preinstall /system/bin/preinstall.shclass mainuser rootgroup rootoneshoton bootxxxxxxxxxx.....start preinstall

4、shell 脚本文件如下 

#!/system/bin/shCUSTOMIZED_APK=/system/usr/app
DATA_APK=/data/appecho "CUSTOMIZED_APK=${CUSTOMIZED_APK}"
#获取是否已经预安装过标记位
PREINSTALL_RESULT=`getprop persist.sys.preinstall.value`
echo "PREINSTALL_RESULT=${PREINSTALL_RESULT}"
apk_files=""
#判断标记位是否为空,为空则没有预装过。然后将所有apk均copy到data/app下面。if [ -z "${PREINSTALL_RESULT}" ]; thencd ${CUSTOMIZED_APK}apk_files=$(ls *.apk )echo "apks files = ${apk_files}"for apkfile in $apk_filesdoecho " apkfiles = ${apkfile} "cp -vf ${CUSTOMIZED_APK}/${apkfile} ${DATA_APK}/${apkfile}echo "start copy "chmod 777 ${DATA_APK}/${apkfile}done#设置标记位
setprop persist.sys.preinstall.value 1# 拷贝 设备改机文件
cp /system/etc/device.json /data/system/device.json
chmod 666 /data/system/device.json
# 拷贝adb公钥
cp /system/etc/adb_keys /data/system/adb_keys
chown -R shell:shell /data/system/adb_keys
chmod 666 /data/system/adb_keyscd ../..fi

5、添加selinux权限

file_contexts文件: system/sepolicy/private/file_contexts 添加下面一行:

/system/bin/preinstall.sh  u:object_r:preinstall_exec:s0

同目录新建文件 preinstall.te 内容如下:

type preinstall, domain;
type preinstall_exec, exec_type, file_type;init_daemon_domain(preinstall)
#全部默认允许
permissive preinstall;

修改 init.te 允许读取并执行 preinstall:

#默认全部允许
allow init preinstall_exec:file {read open getattr execute};

android 11 系统 在 system/sepolicy/prebuilts/api/30.0/private 目录同步修改

TODO

最后一次拉取的android11源码 将 apk拷贝到 /data/app目录后开机没有扫描安装,原因待分析

FIXED : 

在 PackageManagerService. assertPackageIsValid 方法中 ,如下代码段:

// If we're only installing presumed-existing packages, require that the
// scanned APK is both already known and at the path previously established
// for it.  Previously unknown packages we pick up normally, but if we have an
// a priori expectation about this package's install presence, enforce it.
// With a singular exception for new system packages. When an OTA contains
// a new system package, we allow the codepath to change from a system location
// to the user-installed location. If we don't allow this change, any newer,
// user-installed version of the application will be ignored.
if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {if (mExpectingBetter.containsKey(pkg.getPackageName())) {logCriticalInfo(Log.WARN,"Relax SCAN_REQUIRE_KNOWN requirement for package "+ pkg.getPackageName());} else {PackageSetting known = mSettings.getPackageLPr(pkg.getPackageName());if (known != null) {if (DEBUG_PACKAGE_SCANNING) {Log.d(TAG, "Examining " + pkg.getCodePath()+ " and requiring known paths " + known.codePathString+ " & " + known.resourcePathString);}if (!pkg.getCodePath().equals(known.codePathString)|| !pkg.getCodePath().equals(known.resourcePathString)) {throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,"Application package " + pkg.getPackageName()+ " found at " + pkg.getCodePath()+ " but expected at " + known.codePathString+ "; ignoring.");}} else {// throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION,//         "Application package " + pkg.getPackageName()//         + " not found; ignoring.");}}
}

注释掉  INSTALL_FAILED_INVALID_INSTALL_LOCATION 异常。

同时,修改selinux权限: untrusted_app_all 增加 execute 权限:

#允许app读取/data/system目录文件 允许app 执行 data/app-libm目录下的可执行文件
allow untrusted_app_all system_data_file:file { open read execute};

相关文章:

Android 源码集成可卸载 APP

android系统包含三类APP: 1、可自由卸载APP安装在 /data/app目录下。 2、系统APP放在 /system/app目录。 3、特权APP放在 /system/priv-app目录。 系统编译后,打包前, /data分区不起作用,因此系统打包前,可以先将APP全部拷贝到 /…...

cJSON-轻量级解析模块、字符串的神——编织STM32C8T6与阿里云信息传递的纽带

编写方向:本人就不泛泛的编写一篇什么一文学会cJSON了,没什么突出点,也就我水水字数,你们看来看去也不懂,本人是从上阿里云传信息接触的cJSON的,我就此写一篇针对性的文章,希望对大家有用&#…...

【Git】Clone

当git clone失败时,出现 RPC failed; curl 92 HTTP/2 stream 0 was not closed cleanly: CANCEL (err 8) 错误,可能由于网络连接不稳定或仓库太大导致的。 可以尝试以下几种方法来解决这个问题: 增加 Git 的缓冲区大小: git confi…...

web开发 之 HTML、CSS、JavaScript、以及JavaScript的高级框架Vue(学习版2)

一、前言 接下来就是来解决这些问题 二、 Ajax 1.ajax javscript是网页三剑客之一&#xff0c;空用来控制网页的行为的 xml是一种标记语言&#xff0c;是用来存储数据的 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-…...

【课程学习】信号检测与估计II

b站 文章目录 1-概述 1-概述 线性、正交、平稳、高斯 研究线性模型&#xff0c;采用正交化方法&#xff0c;假设信号平稳&#xff0c;考虑信号的统计特性是高斯的。 本学期考虑&#xff0c;非线性、非正交、非平稳、非高斯。 阵列处理 1980-1990 MUSIC 稀疏性 2006-2012 LASS 时…...

【深度学习|PyTorch】基于 PyTorch 搭建 U-Net 深度学习语义分割模型——附代码及其解释!

【深度学习|PyTorch】基于 PyTorch 搭建 U-Net 深度学习语义分割模型——附代码及其解释&#xff01; 【深度学习|PyTorch】基于 PyTorch 搭建 U-Net 深度学习语义分割模型——附代码及其解释&#xff01; 论文地址&#xff1a; https://arxiv.org/abs/1505.04597 代码地址&a…...

DPDK基础入门(十):虚拟化

I/O虚拟化 全虚拟化&#xff1a;宿主机截获客户机对I/O设备的访问请求&#xff0c;然后通过软件模拟真实的硬件。这种方式对客户机而言非常透明&#xff0c;无需考虑底层硬件的情况&#xff0c;不需要修改操作系统。 半虚拟化&#xff1a;通过前端驱动/后端驱动模拟实现I/O虚拟…...

OpenCV_图像旋转超详细讲解

图像转置 transpose(src, dst); transpose()可以实现像素下标的x和y轴坐标进行对调&#xff1a;dst(i,j)src(j,i)&#xff0c;接口形式 transpose(InputArray src, // 输入图像OutputArray dst, // 输出 ) 图像翻转 flip(src, dst, 1); flip()函数可以实现对图像的水平翻转…...

关于 OceanBase 4.x 中被truncate的 table 不再支持进回收站的原因

近期&#xff0c;OceanBase的问答社区中收到了不少用户的询问&#xff0c;关于OceanBase 3.x版本支持被truncate的table进入回收站的功能&#xff0c;为何在升级到4.x版本后不再支持了&#xff1f;为了解答大家的疑惑&#xff0c;我们将通过这篇文章来浅析 OceanBase在4.x版本中…...

Numpy索引详解(数值索引,列表索引,布尔索引)

数值索引 数值索引类似列表索引操作使用[]&#xff0c;参数为下标&#xff0c;[0,len-1),高维数组的索引使用多个[]连用分别代表一维索引&#xff0c;二维索引... import numpy as np import torchnp.random.seed(1) data1 np.arange(5) data2 np.arange(15).reshape(3,5) …...

大数据新视界 --大数据大厂之MongoDB与大数据:灵活文档数据库的应用场景

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...

三年 Sparker 都不一定知道的算子内幕

一、如何在 mapPartitions 中释放资源 mapPartitions是一种对每个分区进行操作的转换操作&#xff0c;于常用的map操作类似&#xff0c;但它处理的是整个分区而不是单个元素。mapPartitions的应用场景适合处理需要在每个分区内批量处理数据的场景&#xff0c;通常用于优化性能…...

PG表空间

目录标题 PG表空间PostgreSQL表空间的最佳实践是什么&#xff1f;如何在PostgreSQL中创建和管理自定义表空间&#xff1f;PostgreSQL表空间对数据库性能的具体影响有哪些&#xff1f;在PostgreSQL中&#xff0c;如何迁移数据到不同的表空间以优化存储布局&#xff1f;PostgreSQ…...

谷粒商城のElasticsearch

文章目录 前言一、前置知识1、Elasticsearch 的结构2、倒排索引 (Inverted Index)2.1、 索引阶段2.2、查询阶段 二、环境准备1、安装Es2、安装Kibana3、安装 ik 分词器 三、项目整合1、引入依赖2、整合业务2.1、创建索引、文档、构建查询语句2.2、整合业务代码 后记 前言 本篇介…...

排队免单模式小程序开发

开发一个排队免单模式的小程序涉及多个方面&#xff0c;包括需求分析、界面设计、后端开发、数据库设计以及测试上线等。下面我将详细介绍每个步骤的概要&#xff1a; 1.需求分析 明确目标&#xff1a;首先确定小程序的核心功能&#xff0c;即排队免单模式的具体实现方式。例如…...

从OracleCloudWorld和财报看Oracle的转变

2024年9月9-12日Oracle Cloud World在美国拉斯维加斯盛大开幕 押注AI和云 Oracle 创始人Larry Ellison做了对Oracle战略和未来愿景的主旨演讲&#xff0c;在演讲中Larry将AI技术和云战略推到了前所未有的高度&#xff0c;从新的Oracle 23c改名到Oracle23ai&#xff0c;到Oracl…...

搭建 PHP

快速搭建 PHP 环境指南 PHP 是一种广泛用于 Web 开发的后端脚本语言&#xff0c;因其灵活性和易用性而受到开发者的青睐。无论是开发个人项目还是企业级应用&#xff0c;PHP 环境的搭建都是一个不可忽视的基础步骤。本指南将带您快速学习如何在不同平台上搭建 PHP 环境&#x…...

kubernetes技术详解,带你深入了解k8s

目录 一、Kubernetes简介 1.1 容器编排应用 1.2 Kubernetes简介 1.3 k8s的设计架构 1.3.1 k8s各个组件的用途 1.3.2 k8s各组件之间的调用关系 1.3.3 k8s的常用名词概念 1.3.4 k8s的分层结构 二、k8s集群环境搭建 2.1 k8s中容器的管理方式 2.2 k8s环境部署 2.2.1 禁用…...

Gateway学习笔记

目录 介绍&#xff1a; 核心概念 依赖 路由 断言 基本的断言工厂 自定义断言 过滤器 路由过滤器 过滤器工厂 自定义路由过滤器 全局过滤器 其他 过滤器执行顺序 前置后置&#xff08;&#xff1f;&#xff09; 跨域问题 yaml 解决 配置类解决 介绍&#x…...

创造增强叙事的互动:Allison Crank的沉浸式体验设计理念

在沉浸式技术日新月异的今天,如何通过用户交互增强叙事,而非分散注意力,成为了设计师们共同面临的挑战。作为用户体验设计师和研究员,Allison Crank以其独特的视角和丰富的经验,为我们揭示了这一领域的核心原则与实践方法。 叙事与互动的和谐共生 Allison Crank强调,互…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

C++.OpenGL (10/64)基础光照(Basic Lighting)

基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问&#xff1a;构建自定义开发环境 引言 临时运维一个古董项目&#xff0c;无文档&#xff0c;无环境&#xff0c;无交接人&#xff0c;俗称三无。 运行设备的环境老&#xff0c;本地环境版本高&#xff0c;ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)

macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 &#x1f37a; 最新版brew安装慢到怀疑人生&#xff1f;别怕&#xff0c;教你轻松起飞&#xff01; 最近Homebrew更新至最新版&#xff0c;每次执行 brew 命令时都会自动从官方地址 https://formulae.…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧

上周三&#xff0c;HubSpot宣布已构建与ChatGPT的深度集成&#xff0c;这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋&#xff0c;但同时也存在一些关于数据安全的担忧。 许多网络声音声称&#xff0c;这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...

MyBatis中关于缓存的理解

MyBatis缓存 MyBatis系统当中默认定义两级缓存&#xff1a;一级缓存、二级缓存 默认情况下&#xff0c;只有一级缓存开启&#xff08;sqlSession级别的缓存&#xff09;二级缓存需要手动开启配置&#xff0c;需要局域namespace级别的缓存 一级缓存&#xff08;本地缓存&#…...