三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

Android 定制限制安装功能

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 installSession APIADB等所有路径。


一、服务端拦截:PackageManagerService 核心层

文件路径

frameworks/base/services/core/java/com/android/server/pm/InstallingSession.java

1.1 依赖导入(已存在,无需新增)

// InstallingSession.javaimportandroid.os.SystemProperties;// line 45importandroid.util.Slog;// line 51

1.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 行号对照

行号内容
247private void handleStartCopy(InstallRequest request) {
248-251APEX 安装豁免(原生逻辑,不受限制)
252boolean notAllowInstall = SystemProperties.getBoolean(...)
253Slog.v(TAG, "===notAllowInstall====" + notAllowInstall);
254-257if (notAllowInstall) { mRet = ...; return; }
258+原生流程继续

1.4 拦截效果

  • 读取属性persist.sys.stb.is3rdNotAllowInstall,默认false
  • true时,设置mRet = INSTALL_FAILED_PRE_APPROVAL_NOT_AVAILABLEreturn,在收集 PackageInfo 之前终止安装。
  • 覆盖路径:pm install、PackageInstaller Session API、ADB install 等所有走 PMS 的安装。
  • APEX 安装不受限INSTALL_APEX分支在属性检查之前 return。

二、UI 入口拦截:PackageInstaller 安装向导入口

文件路径

frameworks/base/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java

2.1 依赖导入(已存在,无需新增)

// InstallStart.javaimportandroid.os.SystemProperties;// line 39importandroid.widget.Toast;// line 45

2.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 行号对照

行号内容
242if (nextActivity != null) {
243if ("true".equals(SystemProperties.get("persist.sys.skg.is3rdNotAllowInstall", "false"))) {
244Toast.makeText(...).show();
245} else {
246-253原生startActivity+ SecurityException 处理(移入 else 分支)
256finish();

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.xml

values/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>

四、修改清单总览

#文件类型说明
1frameworks/base/services/core/java/com/android/server/pm/InstallingSession.javaJavahandleStartCopy新增属性判断,返回INSTALL_FAILED_PRE_APPROVAL_NOT_AVAILABLE
2frameworks/base/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.javaJavaonCreate末尾包裹startActivity,限制时弹 Toast 不启动向导
3frameworks/base/packages/PackageInstaller/res/values/strings.xml资源新增installation_not_allowed英文文案
4frameworks/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 的开关写入,无需额外通信。

如果对你有帮助,就一键三连呗(关注+点赞+收藏),我会持续更新更多干货~~

← 返回列表