欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

android史上最简单修改源码让你的应用静默升级

程序员文章站 2024-02-26 22:45:34
...

事情是酱紫滴,我们公司做无人零售这一块的东西,对接了微信的刷脸支付功能,在比较顺利对照微信刷脸SDK完成功能开发之后,按照它的要求开始了对系统层面的改造工程。碰到了一个对我来说较为棘手的问题,因为微信需要使其提供的刷脸app有静默升级的功能,以便于以后刷脸app更新时这台无人零售的设备能自动进行升级。

虽然我知道静默升级酱紫是个流氓行为,但是对于无人零售来讲,你不可能让运维人员去各个地方手动点击升级吧,而且还不能让人看到安装界面,所以我就在网上各种寻找,但是真如各位大佬所说,“这些需求自己百度就行,百度一大堆”。没错,百度的确是一大堆,但特么全是你抄我我抄你,抄来抄去自己都没验证就当做是自己成果了,现在百度想搜索个有效的答案真的跟淘宝看评价买东西一样困难了,因为都是假的。。。于是我就在想,如何能最简单化的实现静默升级功能,因为如果自己大改源码的话真的太麻烦了,写代码的时候都不会报错,编译之后才会报错,而且还不方便看。

好了,废话不多说,开始进入正题:

首先声明一下前提吧,看网上很多博主说的都不是太详细,所以给很多刚接触源码的新人造成很多不便。这套定制的ROM我首先是内置了微信刷脸app为系统app的,然后就可以开始对源码进行改造了,我一共进行了6个地方的改动,当然真正实现效果的是最后3个步骤,但是我不确定前面的步骤会不会对最终结果造成影响,我也懒得去验证了,反正现在静默升级的效果是达到了。

1.增加权限

修改/frameworks/base/core/res/AndroidManifest.xml:

--- a/frameworks/base/core/res/AndroidManifest.xml
+++ b/frameworks/base/core/res/AndroidManifest.xml

@@ -2451,6 +2451,10 @@
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.INSTALL_PACKAGES"
         android:protectionLevel="signature|privileged" />
+    <permission android:name="android.permission.HIDE_INSTALL_PACKAGES"
+        android:protectionLevel="normal" />
+    <permission android:name="android.permission.HIDE_UNINSTALL_PACKAGES"
+        android:protectionLevel="normal" />

 

2. 在IPackManger.Stub中添加权限判断

--- a/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

@@ -11704,7 +11704,13 @@ public class PackageManagerService extends IPackageManager.Stub {
     public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
             int installFlags, String installerPackageName, int userId) {
         android.util.SeempLog.record(90);
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
+        //mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
+        if(mContext.checkCallingPermission(android.Manifest.permission.HIDE_INSTALL_PACKAGES) == PackageManager.PERMISSION_GRANTED) {
+            Slog.i(TAG, "installerPackageName: checkCallingPermission "+installerPackageName);
+        } else {
+            Slog.i(TAG, "installerPackageName: checkCallingPermission PERMISSION_DENIED"+PackageManager.PERMISSION_DENIED);
+            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
+        }

3. 添加自定义app到白名单

修改/packages/apps/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java:

--//    if (!requestFromUnknownSource) {
++      if (pkgName.equals("你需要静默升级的应用包名") || !requestFromUnknownSource) {
          initiateInstall();
          return;
        }

 

4. 针对特定app执行静默安装升级(静默升级无需手动点击安装,但是弹窗仍然存在。)
修改/packages/apps/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java修改:

--        startInstallConfirm();
++        if(pkgName.equals("com.android.test")){/*这句替换成要静默安装的apk的包名就可以了*/
++            Log.i("==test==", "application upgrade sliently");
++            startInstall();
++        } else {
++            startInstallConfirm();
++        }  

 

5. 去掉安装app时的弹窗
修改/packages/apps/PackageInstaller/AndroidManifest.xml:

<application android:label="@string/app_name"
<activity android:name=".PackageInstallerActivity"
                android:configChanges="orientation|keyboardHidden|screenSize"
                android:excludeFromRecents="true"
--              android:theme="@android :style/Theme.Holo.DialogWhenLarge">
++              android:theme="@android :style/Theme.Trunslucent.NoTitleBar">

...

 

6. 隐藏安装页面

修改/packages/apps/PackageInstaller/res/layout/op_progress.xml:

直接在最顶层view里添加android:visibility="gone"进行全部页面的隐藏

 

--------------------------------我是分割线--------------------------------------

自此,静默升级功能已经实现,最终效果是点击新版本的apk进行安装,不会弹出任何安装页面,过一段很短的时间之后,新版本的app已经安装成功!!!

如果小伙伴有啥疑问,可以跟我交流互相学习,我也是刚入源码这个坑。我不确定这个方法实现起来是否够优雅,但是却是改动最小然后效果也达到了了的。俗话说,不论黑猫白猫能抓得住老鼠的就是好猫嘛~