zoukankan      html  css  js  c++  java
  • Android 第三方 APK 包的静默安装

    (原创,转载请注明出处! http://www.cnblogs.com/Martinium/articles/mirage_install.html )

        有一天,客户提出了这样一个需求。提供一定数目的 APK 包,要求预先安装到系统里,并且可以卸载。很显然,这些 APK 只能 install 到 /data/app/ 目录下,push 到 /system/app/ 是不能卸载的。

        大家心里肯定在想,如果能把这些 APKs 直接烧录到镜像文件里去就好了,最好是 data.img,烧录完成后一启动,那些APK就安静地躺在 /data/app/ 那里了。可惜这样行不通。源码编译出来的APK都是放在  /system/app/ 目录下的,这样用户那边又卸载不了。

        如果手头有 adb 工具,一切也好办,一条命令解决。

    find <dir> -name "*\.apk" -exec adb install {} \;

    <dir> 替换成自己的那些 APK 所在的目录。adb 需要环境变量 PATH 能搜索到,或者用 adb 的全路径。

        可是现在工厂批量生产,没有提供 adb 工具,或者某些客户先前禁止了 adb 打开的功能选项。于是选择从 SD 卡安装。待用户手动点击,一个一个地点击安装,确认,安装完成,这效率多低下啊!如果另外自己写一个 APK,头一次开机绑定一个 service,在 AndroidManifest.xml 里添加 permission,

    <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
    <uses-permission android:name="android.permission.DELETE_PACKAGES" />
    <uses-permission android:name="android.permission.CLEAR_APP_CACHE" />
    <uses-permission android:name="android.permission.CLEAR_APP_USER_DATA" />

    在第一次启动的时候安装,也就完事了。

    可客户又说了,不希望看到多余的 APK 喔,于是打算修改下 category ,将
    <category android:name="android.intent.category.LAUNCHER" />
    改成
    <category android:name="android.intent.category.DEFAULT" />
    客户说不行,在 Settings->Apps->ALL 下面仍然看得到。而且卸载不了。我知道自己写的这个APK必须有system权限才能悄悄的安装的,于是卸载不了。我想把这个 service 插入到某个系统 APK(如packages/app/PackageInstaller)来堵住他的口,心里更想着怎么揍他一顿。

    好吧,冷静,冷静,让我再想想其他办法。

    在 PC 上,是用adb (Android Debug Bridge,源码路径 system/core/adb/)命令安装;
    在 Android 设备上,可以用 pm (PackageManger ,源码路径 frameworks/base/cmds/pm/)命令呀!
    最终,我写了一个简单的脚本,取名 mirage_install.sh

    #!/system/bin/sh
    
    MARK=/data/local/FACTORY_RESET
    PKGS=/mnt/external_sd/mirage_package
    
    if [ ! -e $MARK ]; then
    echo "booting the first time, so pre-install some APKs."
    
    busybox find $PKGS -name "*\.apk" -exec sh /system/bin/pm install {} \;
    
    # NO NEED to delete these APKs since we keep a mark under data partition.
    # And the mark will be wiped out after doing factory reset, so you can install
    # these APKs again if files are still there. 
    # busybox rm -rf $PKGS
    
    touch $MARK
    echo "OK, installation complete."
    fi

        /mnt/external_sd/mirage_package 对应 SD 卡那些 APK 的文件夹,Android 分存储设备为 Internal Storage 和 External Storage,后者对应 SD。其中设置文件 /data/local/FACTORY_RESET 为标志位“是否是首次启动”。首次启动会检测路径是否存在并静默安装,以后启动的话无影响。除非通过恢复出厂设置(factory reset)来擦除这个脏位,清零后没有第三方应用了,于是又可以再次安装了,所以不用删除 SD 卡的那些包。
        这里用到了 busybox 工具,可以自己下载 busybox 源码编译生成,或者修改 frameworks/base/cmds/pm/src/com/android/commands/pm/Pm.java 文件,大概思路是:判断 路径 /mnt/external_sd/mirage_package 存在与否,然后调用文件里面的 install 函数安装。不过最好不要改动源码。

        接下来,我尝试在 init.rc 文件里添加这个 service 成功。

    service mirage_install /system/bin/sh /system/bin/mirage_install.sh
        user root
        group root
        disabled
        oneshot
    
    on property:init.svc.bootanim=stopped
        start mirage_install
    

    这个服务的名字叫 mirage_install,执行 sh /system/bin/mirage_install.sh 这个脚本。
    有关 Android Init Language 的讲解在源码 system/core/init/readme.txt 中,可以自己查看意思。
    这里 oneshot 表示 Do not restart the service when it exits.
    而且在ANDROID开机动画停止后(init.svc.bootanim=stopped)启动该项服务。尝试过其他条件,比如 dev.bootcomplete=1,也就是在 kernel 启动完成后,这样是不行的,有关的系统服务还没有起来,关于其他的 property,可以在控制台下用 getprop 查看, setprop 修改.

    注意给 mirage_install.sh 文件加执行权限 chmod a+x mirage_install.sh
    然后在 device/<company>/<product>/device.mk 文件里添加下面一行

    PRODUCT_COPY_FILES += \
    $(LOCAL_PATH)/system/bin/mirage_install.sh:system/bin/mirage_install.sh
    

    冒号左边对应 mirage_install.sh 文件的相对路径,根据自己放置的路径而定,这里的 LOCAL_PATH 就是 device.mk 所在的文件夹,右边固定为 system/bin/mirage_install.sh,表示将复制到 Android 设备上的 /system/bin/mirage_install.sh 路径下。

        重新编译 Android 工程,将 APK 包放到 SD 卡的 mirage_package 路径下,然后烧录生成的 *.img文件,看到了 APK 的静默安装,OK,大工告成!

  • 相关阅读:
    IP应用加速技术详解:如何提升动静混合站点的访问速率?
    阿里云PolarDB发布重大更新 支持Oracle等数据库一键迁移上云
    BigData NoSQL —— ApsaraDB HBase数据存储与分析平台概览
    洛谷P1457 城堡 The Castle
    洛谷P1461 海明码 Hamming Codes
    洛谷P1460 健康的荷斯坦奶牛 Healthy Holsteins
    洛谷P1459 三值的排序 Sorting a Three-Valued Sequence
    洛谷P1458 顺序的分数 Ordered Fractions
    洛谷P1218 [USACO1.5]特殊的质数肋骨 Superprime Rib
    洛谷P1215 [USACO1.4]母亲的牛奶 Mother's Milk
  • 原文地址:https://www.cnblogs.com/Martinium/p/mirage_install.html
Copyright © 2011-2022 走看看