Android 定制限制安装功能
文章目录
- Android 定制限制安装功能
- 一、服务端拦截:PackageManagerService 核心层
- 文件路径
- 1.1 依赖导入(已存在,无需新增)
- 1.2 代码修改
- 1.3 行号对照
- 1.4 拦截效果
- 二、UI 入口拦截:PackageInstaller 安装向导入口
- 文件路径
- 2.1 依赖导入(已存在,无需新增)
- 2.2 代码修改
- 2.3 行号对照
- 2.4 拦截效果
- 三、字符串资源
- 文件路径
- 四、修改清单总览
- 五、双保险拦截流程
Android 定制限制安装功能
功能:当系统属性
persist.sys.stb.is3rdNotAllowInstall = true时,禁止所有第三方 APP 安装操作。
拦截策略:UI 入口 + PMS 服务端双保险,覆盖点击 APK 安装、pm install、Session API、ADB等所有路径。
一、服务端拦截:PackageManagerService 核心层
文件路径
frameworks/base/services/core/java/com/android/server/pm/InstallingSession.java1.1 依赖导入(已存在,无需新增)
// InstallingSession.javaimportandroid.os.SystemProperties;// line 45importandroid.util.Slog;// line 511.2 代码修改
修改位置:handleStartCopy(InstallRequest request)方法开头,APEX 判断之后、getMinimalPackageInfo之前。
修改前(原生 AOSP):
privatevoidhandleStartCopy(InstallRequestrequest){if((mInstallFlags&PackageManager.INSTALL_APEX)!=0){mRet=INSTALL_SUCCEEDED;return;}PackageInfoLitepkgLite=PackageManagerServiceUtils.getMinimalPackageInfo(mPm.mContext,mPackageLite,mOriginInfo.mResolvedPath,mInstallFlags,mPackageAbiOverride);修改后(新增限制安装拦截):
privatevoidhandleStartCopy(InstallRequestrequest){if((mInstallFlags&PackageManager.INSTALL_APEX)!=0){mRet=INSTALL_SUCCEEDED;return;}// +++ add by stb: 限制安装开关,打开后禁止所有第三方 APP 安装booleannotAllowInstall=SystemProperties.getBoolean("persist.sys.stb.is3rdNotAllowInstall",false);Slog.v(TAG,"===notAllowInstall===="+notAllowInstall);if(notAllowInstall){mRet=PackageManager.INSTALL_FAILED_PRE_APPROVAL_NOT_AVAILABLE;return;}// +++PackageInfoLitepkgLite=PackageManagerServiceUtils.getMinimalPackageInfo(mPm.mContext,mPackageLite,mOriginInfo.mResolvedPath,mInstallFlags,mPackageAbiOverride);1.3 行号对照
| 行号 | 内容 |
|---|---|
| 247 | private void handleStartCopy(InstallRequest request) { |
| 248-251 | APEX 安装豁免(原生逻辑,不受限制) |
| 252 | boolean notAllowInstall = SystemProperties.getBoolean(...) |
| 253 | Slog.v(TAG, "===notAllowInstall====" + notAllowInstall); |
| 254-257 | if (notAllowInstall) { mRet = ...; return; } |
| 258+ | 原生流程继续 |
1.4 拦截效果
- 读取属性
persist.sys.stb.is3rdNotAllowInstall,默认false。 - 为
true时,设置mRet = INSTALL_FAILED_PRE_APPROVAL_NOT_AVAILABLE并return,在收集 PackageInfo 之前终止安装。 - 覆盖路径:
pm install、PackageInstaller Session API、ADB install 等所有走 PMS 的安装。 - APEX 安装不受限:
INSTALL_APEX分支在属性检查之前 return。
二、UI 入口拦截:PackageInstaller 安装向导入口
文件路径
frameworks/base/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java2.1 依赖导入(已存在,无需新增)
// InstallStart.javaimportandroid.os.SystemProperties;// line 39importandroid.widget.Toast;// line 452.2 代码修改
修改位置:onCreate流程末尾,startActivity(nextActivity)调用处。
修改前(原生 AOSP):
if(nextActivity!=null){try{startActivity(nextActivity);}catch(SecurityExceptione){Intentresult=newIntent();result.putExtra(Intent.EXTRA_INSTALL_RESULT,PackageManager.INSTALL_FAILED_INVALID_URI);setResult(RESULT_FIRST_USER,result);}}finish();修改后(新增限制安装拦截):
if(nextActivity!=null){// +++ add by stb: 限制安装开关,打开后禁止外部应用手动安装if("true".equals(SystemProperties.get("persist.sys.stb.is3rdNotAllowInstall","false"))){Toast.makeText(InstallStart.this,R.string.installation_not_allowed,Toast.LENGTH_LONG).show();}else{try{startActivity(nextActivity);}catch(SecurityExceptione){Intentresult=newIntent();result.putExtra(Intent.EXTRA_INSTALL_RESULT,PackageManager.INSTALL_FAILED_INVALID_URI);setResult(RESULT_FIRST_USER,result);}}// +++}finish();2.3 行号对照
| 行号 | 内容 |
|---|---|
| 242 | if (nextActivity != null) { |
| 243 | if ("true".equals(SystemProperties.get("persist.sys.skg.is3rdNotAllowInstall", "false"))) { |
| 244 | Toast.makeText(...).show(); |
| 245 | } else { |
| 246-253 | 原生startActivity+ SecurityException 处理(移入 else 分支) |
| 256 | finish(); |
2.4 拦截效果
- 读取属性
persist.sys.stb.is3rdNotAllowInstall,默认"false"。 - 为
"true"时,弹出 Toast 提示,不调用startActivity(nextActivity),安装向导(PackageInstallerActivity/InstallStaging)不会启动。 - 随后
finish()结束当前 Activity。 - 覆盖路径:文件管理器、浏览器等点击 APK 触发的
ACTION_INSTALL_PACKAGE/ACTION_VIEWintent。
三、字符串资源
文件路径
frameworks/base/packages/PackageInstaller/res/values/strings.xml frameworks/base/packages/PackageInstaller/res/values-zh-rCN/strings.xmlvalues/strings.xml(line 364,英文):
<stringname="installation_not_allowed">Manual installation is not allowed for external applications!</string>values-zh-rCN/strings.xml(line 132,中文):
<stringname="installation_not_allowed">外部应用,禁止手动安装!</string>四、修改清单总览
| # | 文件 | 类型 | 说明 |
|---|---|---|---|
| 1 | frameworks/base/services/core/java/com/android/server/pm/InstallingSession.java | Java | handleStartCopy新增属性判断,返回INSTALL_FAILED_PRE_APPROVAL_NOT_AVAILABLE |
| 2 | frameworks/base/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java | Java | onCreate末尾包裹startActivity,限制时弹 Toast 不启动向导 |
| 3 | frameworks/base/packages/PackageInstaller/res/values/strings.xml | 资源 | 新增installation_not_allowed英文文案 |
| 4 | frameworks/base/packages/PackageInstaller/res/values-zh-rCN/strings.xml | 资源 | 新增installation_not_allowed中文文案 |
五、双保险拦截流程
安装请求 │ ├──► [路径A] 点击 APK (Intent) │ │ │ ▼ │ InstallStart.java (UI 入口) │ 读取 persist.sys.stb.is3rdNotAllowInstall │ ├─ true ─► 弹 Toast "外部应用,禁止手动安装!" + finish() │ └─ false ─► startActivity(安装向导) ──► PMS │ └──► [路径B] pm install / ADB / Session API │ ▼ InstallingSession.handleStartCopy (PMS 服务端) 读取 persist.sys.stb.is3rdNotAllowInstall ├─ true ─► mRet = INSTALL_FAILED_PRE_APPROVAL_NOT_AVAILABLE + return └─ false ─► 继续原生安装流程两处均只读
persist.sys.stb.is3rdNotAllowInstall单一属性,状态由 stbSettings 的开关写入,无需额外通信。
如果对你有帮助,就一键三连呗(关注+点赞+收藏),我会持续更新更多干货~~
