Tag: update

  • Android 2.2系统在线升级的移植

    之前我们自己做过一个在线T卡升级的应用程序,设计思路是非常简单的,获取本地手机版本号,获取并解析服务器上json格式的最新信息,如果服务器上的版本号大于本地手机的版本号,则可以下载并md5验证升级包,然后调用系统函数升级即可。

    从Android 2.2开始,Google服务框架 GoogleServicesFramework.apk 包自带的系统更新处理了android.settings.SYSTEM_UPDATE_SETTINGS这个intent。我们自己做的手机,当然不可能用Google自带的在线升级。为了不修改 GoogleServicesFramework.apk,在Settings的AndroidManifest.xml文件,把 SYSTEM_UPDATE_SETTINGS,修改为别的名字,比如 SYSTEM_UPGRADE_SETTINGS。 还需要同步修改这个文件:

    Settings/res/xml/device_info_settings.xml
    今天发神经病,花了一大早上的时候反编译GoogleServicesFramework里的update,看看别人如何设计的,就几个文件:
    [deli@athena update]$ tree .
    .
    ├── Download.java
    ├── StateWatcher.java
    ├── SystemUpdateActivity.java
    ├── SystemUpdateInstallDialog.java
    ├── SystemUpdateService.java
    └── SystemUpdateVerifierTask.java

    搞出600多行代码,才发现跟GoogleServicesFramework这个包里的其他代码非常缠绵,只好作罢。 大概思路也弄明白了,跟我们一样,也是用Downloads.ByUri 这个组件下载文件,
    调用系统函数 RecoverySystem.installPackage(context, new File(filename)); 唯一的差别是没有网络连接的情况下,引导用户到设置的界面,比较人性化,很注重用户体验,我们直接跳出个对话框,没有网络连接,以后是要修改的。

    默认的,installPackage 这个函数只支持文件放在 /data或/cahce 目录,但是,一般一个系统升级包有70M,一般机器不能保证有那么大的空间,我们只好把文件放在 SD card里,修改installPackage 函数,让它支持 sdcard 目录:

    // from froyo, /sdcard ==> /mnt/sdcard
    } else if (filename.startsWith("/mnt/sdcard/")) {
        filename = "SDCARD:" + filename.substring(12);

    更新: 2011/7/23

    一些网友遇到这样的 error:

    FileNotFoundException: /cache/recovery/command (Permission denied)

    记得在AndroidManifest.xml加上权限

    <uses-permission android:name="android.permission.ACCESS_CACHE_FILESYSTEM" />
    <uses-permission android:name="android.permission.REBOOT" />

    进阶:C2DM

    使用 c2dm,给用户发push 通知消息,在状态栏提示有新版本可以更新啦。这部分的代码,可以参考大名鼎鼎的 CyanogenMod 的做法 CMUpdateNotify