Android程序如何實現自動更新

Android程序如何實現自動更新

這是個人第一編原創文章,最近公司在招移動端開發的人,但收效甚微。因而我決定發揮一下個人我的魅力,但願在此拋下一塊磚,能引像你的一塊玉。廢話很少說,現有兩個坑,安卓開發工程師、網頁開發工程師,工做地點:佛山市順德區龍江鎮西溪工業區雄塑科技大廈二樓,公司網站:www.longjoe.com,有意者請直接我郵件到183701846#qq.com(#換@),介紹完職位立刻進入正題。java

需求:

  1. 啓動時或定時鏈接服務器檢查更新
  2. 有新程序才下載更新包APK
  3. 不根據版本號進行更新,MD5不同就更新

設計:

發送當前程序計算得的MD5發送給服務器,服務器對比當前更新包MD5與入參MD5判斷是否要更新,若是要更新就返回新的MD5及新程序,不用更新就只返回當前MD5。android

源代碼:服務器

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安裝部分也須要聲明相應的權限
  • 使用時也須要考慮線程問題
  • 並且有更新時,是否要提問用戶更新,仍是直接更新
相關文章
相關標籤/搜索