Android程序如何实现自动更新

Android程序如何实现自动更新

这是我的第一编原创文章,最近公司在招移动端开发的人,但收效甚微。于是我决定发挥一下我的个人魅力,希望在此抛下一块砖,能引像你的一块玉。废话不多说,现有两个坑,安卓开发工程师、网页开发工程师,工作地点:佛山市顺德区龙江镇西溪工业区雄塑科技大厦二楼,公司网站:www.longjoe.com,有意者请直接我邮件到183701846#qq.com(#换@),介绍完职位马上进入正题。

需求:

  1. 启动时或定时连接服务器检查更新
  2. 有新程序才下载更新包APK
  3. 不根据版本号进行更新,MD5不一样就更新

设计:

发送当前程序计算得的MD5发送给服务器,服务器对比当前更新包MD5与入参MD5判断是否要更新,如果要更新就返回新的MD5及新程序,不用更新就只返回当前MD5。

源代码:

package com.longjoe.apkhelper;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * Created by xlz on 2016/7/5.
 * 安装更新包
 */

public abstract class ApkHelper {
    private Context context;

    public void AutoUpdate(Context context){
        this.context = context;

        File file = getApk();
        if (file == null) {
            return;
        }
        //2.安装
        install(file);
    }
    //私有install apk方法
    private boolean install(File filename) {
        // 先判断手机是否有root权限
        if (hasRootPerssion()) {
            // 有root权限,利用静默安装实现
            return clientInstall(filename.toString());
        } else {
            installApk(filename);
            return true;
        }
    }

    private static boolean hasRootPerssion() {
        PrintWriter PrintWriter = null;
        Process process = null;
        try {
            process = Runtime.getRuntime().exec("su");
            PrintWriter = new PrintWriter(process.getOutputStream());
            PrintWriter.flush();
            PrintWriter.close();
            int value = process.waitFor();
            return returnResult(value);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (process != null) {
                process.destroy();
            }
        }
        return false;
    }

    //意图安装  程序开始
    private void installApk(File filename) {
        chmod("777", filename.toString());
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        Uri uri = Uri.fromFile(filename);
        intent.setDataAndType(uri, "application/vnd.android.package-archive");
        context.startActivity(intent);
        android.os.Process.killProcess(android.os.Process.myPid());
    }

    private void chmod(String permission, String path) {
        try {
            String command = "chmod " + permission + " " + path;
            Runtime runtime = Runtime.getRuntime();
            runtime.exec(command);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //意图安装  程序结束

    /**
     * 静默安装
     */
    private static boolean clientInstall(String apkPath) {
        PrintWriter PrintWriter = null;
        Process process = null;
        try {
            process = Runtime.getRuntime().exec("su");
            PrintWriter = new PrintWriter(process.getOutputStream());
            PrintWriter.println("chmod 777 " + apkPath);
            PrintWriter.println("export LD_LIBRARY_PATH=/vendor/lib:/system/lib");
            PrintWriter.println("pm install -r " + apkPath);
//          PrintWriter.println("exit");
            PrintWriter.flush();
            PrintWriter.close();
            int value = process.waitFor();
            return returnResult(value);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (process != null) {
                process.destroy();
            }
        }
        return false;
    }

    private static boolean returnResult(int value) {
        // 代表成功
        if (value == 0) {
            return true;
        } else if (value == 1) { // 失败
            return false;
        } else { // 未知情况
            return false;
        }
    }
    //检查更新,更新完之后返回文件名
    protected abstract File getApk();
}

待填坑:

  • 为了兼容不同传输协议,所以访问服务器部分做成了抽象方法
  • APK安装部分也需要声明相应的权限
  • 使用时也需要考虑线程问题
  • 而且有更新时,是否要提问用户更新,还是直接更新
posted @ 2016-07-18 08:53  格琳(Green)  阅读(374)  评论(0)    收藏  举报