Android 11 禁止从SD卡上安装第三方应用
1.Android 11 -- 强制清理app后台,关于权限引发的问题2.Android 11 (MTK)状态栏图标反色-->跟随当前应用变化代码流程3.Android 11 --关于Toast的异常4.Android 11 -- 关于dialog和悬浮窗导致SystemUI状态栏下拉频繁闪烁(窗口焦点问题)5.Android 11 下拉菜单长按WiFi图标SystemUI ANR6.Android 11 sim卡来电不弹出悬浮通知,默认来电默认全屏7.Android Bluetooth 蓝牙开发/蓝牙协议 小结8.Android11 —— 自定义添加一个System Services9.Android系统——AOSP相关-->随记10.Android11 , Launcher3 切换阿拉伯语,最近应用(后台)不能滑动11.Android 底层问题日志记录12.Android 11 -- app 服务保活13.Android11 - 添加自定义服务注意事项14.Android 11 导航栏添加一个虚拟按钮--问题合集15.Android 11--设置第三方Launcher并默认 与 如何预置apk16.Android11 系统修改 AOSP输入法的默认输入键盘布局17.Settings里面切换不同Launcher的代码流程18.关于Android`系统默认屏保`19.关于Android 11 Settings添加新的选项界面的细节20.Android 11 自由窗口模式 || 全屏模式启动app21.强制app横屏显示或者竖屏显示(动态)
22.Android 11 禁止从SD卡上安装第三方应用
23.实体物理音量键替换为home键24.AMS- kill Launcher进程的代码流程25.Android 11 recovery恢复出厂设置保留某些文件26.Android 11 禁用 adb root (userdebug版本)27.Android11 应用默认获取通知使用权限(可以获取系统所有通知信息)28.Android 11 UsbDebug 关于adb RSA 认证29.Android 11 NavigationBar && Status Bar 如果改变背景颜色30.Anroid 11 关于NotificationManager && NotificationManagerService -- 衍生到权限管理31.Android13 控制设置界面 双栏显示或单栏显示32.Android 13 大屏显示时关于SystemUI和Launcher3问题33.Android 系统适配无源码app34.Android 11 关于app的权限重置35.Android 11.0 关于app进程保活36.Android 11 关于按键拦截/按键事件处理分享37.Android R Settings关于屏保/PowerManagerService欺骗系统不让其进入休眠状态38.Android13 关于SystemUI更新/Nav Bar add volume button&&other button39.Android 13 移植EthernetSettings/Ethernet更新40.Anrdoir 13 关于设置静态IP后,突然断电,在上电开机卡动画41.Android T(13) The app is granted permissions by default42.Android T 关于屏幕旋转 (一)43.Android T about screen rotation(二)44.Android 13 about launcher3 (1)45.Android T don't abort background activity starts46.Android T adout replace bootanimation47.Launcher start App WINDOWING_MODE_FREEFORM48.Android 11 About SleepToken / (Settings)Screen timeout49.Settings.System数据监听/prop&SystemProperties数据监听禁止安装第三方应用
找到负责安装app的类:
./frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
修改日志变量,打印日志,顺着日志看流程:
public static final boolean DEBUG_INSTALL = true;
05-28 09:12:12.462 4123 4184 I PackageManager: init_copy: InstallParams{6d90a79 file=/data/app/vmdl366151461.tmp}
05-28 09:12:12.463 4123 4184 I PackageManager: startCopy UserHandle{0}: InstallParams{6d90a79 file=/data/app/vmdl366151461.tmp}
05-28 09:12:12.549 4123 4184 I PackageManager: Integrity check passed for file:///data/app/vmdl366151461.tmp
05-28 09:12:14.880 4123 4184 D PackageManager: /data/app/vmdl366151461.tmp already staged; skipping copy
05-28 09:12:14.881 4123 4184 D PackageManager: installPackageLI: path=/data/app/vmdl366151461.tmp
05-28 09:12:15.023 4123 4184 D PackageManager: Renaming /data/app/vmdl366151461.tmp to /data/app/~~2rk1hOBIh8fnqGdBKDN00Q==/sogo.app-EhY7mM0vfr2P2-UgsmKeFg==
05-28 09:12:15.043 4123 4184 D PackageManager: installNewPackageLI: Package{549c800 sogo.app}
05-28 09:12:15.053 4123 4184 D PackageManager: New package installed in /data/app/~~2rk1hOBIh8fnqGdBKDN00Q==/sogo.app-EhY7mM0vfr2P2-UgsmKeFg==
05-28 09:12:15.059 4123 4184 I PackageManager: Package sogo.app(10132) checking android.permission.ACCESS_COARSE_LOCATION: BasePermission{77b6d9d android.permission.ACCESS_COARSE_LOCATION}
05-28 09:12:15.059 4123 4184 I PackageManager: Package sogo.app(10132) checking android.permission.ACCESS_FINE_LOCATION: BasePermission{aa173c8 android.permission.ACCESS_FINE_LOCATION}
05-28 09:12:15.060 4123 4184 I PackageManager: Package sogo.app(10132) checking android.permission.NFC: BasePermission{4c4e26c android.permission.NFC}
05-28 09:12:15.060 4123 4184 I PackageManager: Package sogo.app(10132) checking android.permission.CAMERA: BasePermission{c0382df android.permission.CAMERA}
05-28 09:12:15.060 4123 4184 I PackageManager: Package sogo.app(10132) checking android.permission.INTERNET: BasePermission{14c986f android.permission.INTERNET}
05-28 09:12:15.060 4123 4184 I PackageManager: Package sogo.app(10132) checking android.permission.ACCESS_NETWORK_STATE: BasePermission{9e8869b android.permission.ACCESS_NETWORK_STATE}
05-28 09:12:15.060 4123 4184 I PackageManager: Package sogo.app(10132) checking android.permission.ACCESS_WIFI_STATE: BasePermission{44ae386 android.permission.ACCESS_WIFI_STATE}
05-28 09:12:15.060 4123 4184 I PackageManager: Package sogo.app(10132) checking android.permission.USE_BIOMETRIC: BasePermission{7620b96 android.permission.USE_BIOMETRIC}
05-28 09:12:15.060 4123 4184 I PackageManager: Package sogo.app(10132) checking android.permission.USE_FINGERPRINT: BasePermission{a2eeab1 android.permission.USE_FINGERPRINT}
05-28 09:12:15.060 4123 4184 I PackageManager: Package sogo.app(10132) checking com.google.android.c2dm.permission.RECEIVE: BasePermission{d8f1227 com.google.android.c2dm.permission.RECEIVE}
05-28 09:12:15.060 4123 4184 I PackageManager: Package sogo.app(10132) checking android.permission.FOREGROUND_SERVICE: BasePermission{9d4af4e android.permission.FOREGROUND_SERVICE}
05-28 09:12:15.060 4123 4184 I PackageManager: Package sogo.app(10132) checking com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE: BasePermission{9250b50 com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE}
05-28 09:12:15.060 4123 4184 I PackageManager: Package sogo.app(10132) checking android.permission.RECEIVE_BOOT_COMPLETED: BasePermission{50725a android.permission.RECEIVE_BOOT_COMPLETED}
05-28 09:12:16.440 4123 4184 V PackageManager: restoreAndPostInstall userId=0 package=Package{549c800 sogo.app}
05-28 09:12:16.440 4123 4184 V PackageManager: + starting restore round-trip 1
05-28 09:12:16.441 4123 4184 V PackageManager: token 1 to BM for possible restore for user 0
05-28 09:12:16.443 4123 4184 V PackageManager: BM finishing package install for 1
05-28 09:12:16.443 4123 4184 V PackageManager: Handling post-install for 1
试了adb安装和 sd安装,发现两者的日志打印时差不多的都走了 preparePackageLI()函数,这个函数也做了很多关于app是否能安装的检查。
@GuardedBy("mInstallLock")
private PrepareResult preparePackageLI(InstallArgs args, PackageInstalledInfo res)
throws PrepareFailure {
...
if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
// Sanity check
if (instantApp && onExternal) {
Slog.i(TAG, "Incompatible ephemeral install; external=" + onExternal);
throw new PrepareFailure(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
}
// Retrieve PackageSettings and parse package
//检索PackageSettings并解析包
@ParseFlags final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
| PackageParser.PARSE_ENFORCE_CODE
| (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
ParsedPackage parsedPackage;
try (PackageParser2 pp = new PackageParser2(mSeparateProcesses, false, mMetrics, null,
mPackageParserCallback)) {
parsedPackage = pp.parsePackage(tmpPackageFile, parseFlags, false);
AndroidPackageUtils.validatePackageDexMetadata(parsedPackage);
} catch (PackageParserException e) {
throw new PrepareFailure("Failed parse during installPackageLI", e);
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
// Instant apps have several additional install-time checks.
//即时应用程序还有几个额外的安装时间检查。
if (instantApp) {
if (parsedPackage.getTargetSdkVersion() < Build.VERSION_CODES.O) {
Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName()
+ " does not target at least O");
throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID,
"Instant app package must target at least O");
}
if (parsedPackage.getSharedUserId() != null) {
Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName()
+ " may not declare sharedUserId.");
throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID,
"Instant app package may not declare a sharedUserId");
}
}
if (parsedPackage.isStaticSharedLibrary()) {
// Static shared libraries have synthetic package names
renameStaticSharedLibraryPackage(parsedPackage);
// No static shared libs on external storage
if (onExternal) {
Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
throw new PrepareFailure(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
"Packages declaring static-shared libs cannot be updated");
}
}
//add start
boolean vito_can_install = true;
if (parsedPackage.getPackageName() != null) {
vito_can_install = false;
}
if (!vito_can_install) {
throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID,
"Package " + parsedPackage.getPackageName() + " ,this app are not allow installs.");
}
//add end
String pkgName = res.name = parsedPackage.getPackageName();
if (parsedPackage.isTestOnly()) {
if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
throw new PrepareFailure(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
}
}
...
}
//加了这段代码后打印的日志:
05-28 10:01:37.498 523 566 I PackageManager: init_copy: InstallParams{ac01ca6 file=/data/app/vmdl2059354562.tmp}
05-28 10:01:37.498 523 566 I PackageManager: startCopy UserHandle{0}: InstallParams{ac01ca6 file=/data/app/vmdl2059354562.tmp}
05-28 10:01:37.605 523 566 I PackageManager: Integrity check passed for file:///data/app/vmdl2059354562.tmp
05-28 10:01:39.872 523 566 D PackageManager: /data/app/vmdl2059354562.tmp already staged; skipping copy
05-28 10:01:39.873 523 566 D PackageManager: installPackageLI: path=/data/app/vmdl2059354562.tmp
05-28 10:01:39.895 523 566 W PackageManager: Package sogo.app ,this app are not allow installs.
05-28 10:01:39.955 523 566 V PackageManager: restoreAndPostInstall userId=0 package=null
05-28 10:01:39.955 523 566 V PackageManager: + starting restore round-trip 1
05-28 10:01:39.955 523 566 V PackageManager: No restore - queue post-install for 1
05-28 10:01:39.955 523 566 V PackageManager: Handling post-install for 1
这个功能禁止从SD卡上安装第三方应用,可以搞个白名单,安装写进白名单的app,其它的不让!!!
另外一个角度:
./frameworks/base/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
//禁止从SD卡上安装第三方应用
private void checkIfAllowedAndInitiateInstall() {
// Check for install apps user restriction first.
final int installAppsRestrictionSource = mUserManager.getUserRestrictionSource(
UserManager.DISALLOW_INSTALL_APPS, Process.myUserHandle());
if ((installAppsRestrictionSource & UserManager.RESTRICTION_SOURCE_SYSTEM) != 0) {
showDialogInner(DLG_INSTALL_APPS_RESTRICTED_FOR_USER);
return;
} else if (installAppsRestrictionSource != UserManager.RESTRICTION_NOT_SET) {
startActivity(new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS));
finish();
return;
}
//add start
boolean vito_can_install =true;
Log.e(TAG, "vito_can_install false ="+ mPkgInfo.applicationInfo.packageName);
if(mPkgInfo.applicationInfo.packageName != null){
vito_can_install = false;
}
if(!vito_can_install){
Log.w(TAG, "vito_can_install "+vito_can_install);
setPmResult(PackageManager.INSTALL_FAILED_INVALID_APK);
Toast.makeText(this, "install_failed", Toast.LENGTH_LONG).show();
finish();
return;
}
//add end
...
}
禁止卸载apk
frameworks\base\services\core\java\com\android\server\pm\DeletePackageHelper.java
public int deletePackageX(String packageName, long versionCode, int userId, int deleteFlags,
boolean removedBySystem) {
final PackageRemovedInfo info = new PackageRemovedInfo(mPm);
final boolean res;
mCustomerManager = (SunmiCustomerManager) mPm.mContext.getSystemService("sunmi_customer");
final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
? UserHandle.USER_ALL : userId;
//检查用户removeForUser 是否有权限删除该应用,这里做文章
if (mPm.isPackageDeviceAdmin(packageName, removeUser)) {
Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
}
...
分类:
Android
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 【.NET】调用本地 Deepseek 模型
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库