关于安卓自动升级的一些思路

通过接口,返回新版本的版本号以及新版本下载地址,通过Downloadmangeri下载更新。

1.UpdateActivity(实现下载功能的主代码)

package com.tolly.parking;

import android.app.DownloadManager;
import android.app.ProgressDialog;
import android.content.*;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import com.tolly.parking.entity.UpdateInfo;
import com.tolly.parking.enumeration.FunctionListEnum;
import com.tolly.parking.serviceImpl.UpdateServicelmpl.UpdateServicelmpl;
import com.tolly.parking.util.DeviceInfoUtil;
import com.tolly.parking.vo.UpdateVO;
import org.codehaus.jackson.map.ObjectMapper;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.Callable;

import static com.tolly.parking.enumeration.CommandEnum.DOWN_ERROR;
import static com.tolly.parking.enumeration.CommandEnum.GET_UNDATAINFO_ERROR;
import static com.tolly.parking.enumeration.CommandEnum.UPDATA_CLIENT;
import static com.tolly.parking.util.JsonTransitionObjectUtil.objectMapper;


/**
 * Created by zyy on 2017/7/19.
 */
public class UpdateActivity extends AppCompatActivity {
    private String versionName;
    private int versionCode;
    MyReceiver receiver = new MyReceiver();
    public static final String BROADCAST_ACTION =
            "com.example.android.threadsample.BROADCAST";
    public static final String EXTENDED_DATA_STATUS =
            "com.example.android.threadsample.STATUS";
    private LocalBroadcastManager mLocalBroadcastManager;
    //服务器中APK下载地址
    private String updateurl;
    private Context context;
    //自动更新的实现类
    private UpdateServicelmpl UpdateService;

    public final Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Bundle bundle = msg.getData();
            switch (msg.arg1) {
                case UPDATA_CLIENT:
                    //处理服务器返回的结果
                    handleUpdateClientResult(bundle);
                    break;
//                case GET_UNDATAINFO_ERROR:
//                    //服务器超时
//                    Toast.makeText(getApplicationContext(), "获取服务器更新信息失败", Toast.LENGTH_SHORT).show();
//                    LoginMain();
//                    break;
//                case  DOWN_ERROR:
//                    //下载apk失败
//                    Toast.makeText(getApplicationContext(), "下载新版本失败",  Toast.LENGTH_SHORT).show();
//                    LoginMain();
//                    break;
            }
        }
    };

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //获得APP版本名称和版本号
        versionName = DeviceInfoUtil.getAppVersionName(getApplicationContext());
        versionCode = DeviceInfoUtil.getAppVersionCode(getApplicationContext());
//        Log.i("测试:", "versionName:"+versionName+",versionCode:"+versionCode);

        //更新接口
        UpdateService = new UpdateServicelmpl(handler);
        UpdateVO updatevo = new UpdateVO();
        try {
            UpdateService.UpdateClient(updatevo);
        } catch (Exception e) {
            e.printStackTrace();
        }
        regist();

    }

    /**
     * 处理服务器返回的APP版本号
     * @param bundle
     */
    private void handleUpdateClientResult(Bundle bundle){
        String json = bundle.getString(FunctionListEnum.UpdateClient.toString());
        ObjectMapper objectMapper = new ObjectMapper();
        if (null != json && !"".equals(json)){
            try {
                UpdateVO updatevo = objectMapper.readValue(json,UpdateVO.class);
                if (null != updatevo){
                    int serverversioncode = updatevo.getServerVersionCode();
                    updateurl = updatevo.getUrl();
//                    if ( !"".equals(serverversioncode)){
                        if (versionCode 

2.更新接口

package com.tolly.parking.service.updateService;

import com.tolly.parking.vo.UpdateVO;

/**
 * 更新接口
 * Created by zyy on 2017/7/24.
 */
public interface UpdateService {

    /**
     *更新接口
     * @param updatevo
     * @throws Exception
     */
    void UpdateClient(UpdateVO updatevo) throws Exception;
}

3.接口的实现

代码中的url是接口的地址
package com.tolly.parking.serviceImpl.UpdateServicelmpl;

import android.os.Handler;
import com.tolly.parking.Common.Constant;
import com.tolly.parking.entity.UserUser;
import com.tolly.parking.enumeration.CommandEnum;
import com.tolly.parking.enumeration.ContentTypeEnum;
import com.tolly.parking.enumeration.FunctionListEnum;
import com.tolly.parking.service.updateService.UpdateService;
import com.tolly.parking.util.FunctionUtil;
import com.tolly.parking.util.InstanceServiceUtil;
import com.tolly.parking.util.ServerDataExchangeUtil;
import com.tolly.parking.vo.UpdateVO;

import java.util.HashMap;
import java.util.Map;

/**
 * 更新接口的实现
 * Created by zyy on 2017/7/24.
 */
public class UpdateServicelmpl implements UpdateService{
    private Handler handler;

    private ServerDataExchangeUtil serverDataExchangeUtil;

    public UpdateServicelmpl(Handler handler) {
        this.handler = handler;
        init();

    }

    /**
     * 初始化
     */
    private void init() {
        try {
            serverDataExchangeUtil = new ServerDataExchangeUtil();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void UpdateClient(UpdateVO updatevo) throws Exception {
        String url= Constant.UPDATEURL;
        if(null != url && !"".equals(url)) {
            String mac = Constant.MAC;
            url = "http://" + url + FunctionUtil.getFunctionList(FunctionListEnum.UpdateClient.toString());
            Map mapPara = new HashMap<>();
            mapPara.put("mac", mac);
            //创个userUser, 使之有token
            InstanceServiceUtil.writeMap(UserUser.class.toString(), new UserUser());
            serverDataExchangeUtil.handler = handler;
            serverDataExchangeUtil.PostValue(CommandEnum.UPDATA_CLIENT, FunctionListEnum.UpdateClient.toString(), url, mapPara,ContentTypeEnum.Text.getContentType());
        }
    }
}

4.服务器接口

接口返回的是新版本的版本号以及版本下载地址
package com.example.demo;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
import java.util.Map;

/**
 * Created by JJH on 2017/7/27.
 */
@RestController
@RequestMapping("/bang")
public class DemoController {
    private Logger logger = LoggerFactory.getLogger(this.getClass());


    @PostMapping("/getVersion")
    public UpdateVO getVersionByMac(String mac){
        logger.info("请求查询版本号接收的到参数为:" + mac);
        // ==================  根据mac查询version的逻辑程序(一般入service服务类,也可以直接写)=====
        UpdateVO updateVO = new UpdateVO();
        APKcode apkcode = new APKcode();
        Map map = apkcode.readAPK();
        Object obj = map.get("versionCode");
        int serverVersionCode = 0;
        if(null != obj) {
            serverVersionCode = Integer.parseInt(obj.toString());
        }
        updateVO.setServerVersionCode(serverVersionCode);
        updateVO.setUrl("F:\\app-debug.apk");
        return updateVO;
        // ====================end===================
    }
}


class UpdateVO{
    private int serverVersionCode;
    private String url;

    public int getServerVersionCode() {
        return serverVersionCode;
    }

    public void setServerVersionCode(int serverVersionCode) {
        this.serverVersionCode = serverVersionCode;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
}

5.实体

package com.tolly.parking.vo;

/**
 * 更新时服务器版本号VO
 * Created by zyy on 2017/7/25.
 */
public class UpdateVO {
    //服务器中APP版本号
    private int serverVersionCode;
    private String url;

    public int getServerVersionCode() {
        return serverVersionCode;
    }

    public void setServerVersionCode(int serverVersionCode) {
        this.serverVersionCode = serverVersionCode;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
}

6.从服务器获取APK版本号

这个代码是网上查找的,自己修改运行。需要下载架包
AXmlResourceParser.jar

package com.example.demo;

import org.apkinfo.api.util.AXmlResourceParser;
import org.apkinfo.api.util.TypedValue;
import org.apkinfo.api.util.XmlPullParser;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 * Created by zyy on 2017/8/1.
 */


public class APKcode {
//    public static void main(String[] args) {
//        Map map = readAPK();
//        System.out.println("package:"+map.get("package")+",versionCode:"+map.get("versionCode"));
//    }
    /**
     * 读取APK
     * @return
     */
    public static Map readAPK() {
        String apkUrl= "F:\\app-debug.apk";
        ZipFile zipFile;
        Map map = new HashMap();
        try {
            zipFile = new ZipFile(apkUrl);
            Enumeration enumeration = zipFile.entries();
            ZipEntry zipEntry = null;
            while (enumeration.hasMoreElements()) {
                zipEntry = (ZipEntry) enumeration.nextElement();
                if (zipEntry.isDirectory()) {

                } else {
                    if ("androidmanifest.xml".equals(zipEntry.getName().toLowerCase())) {
                        AXmlResourceParser parser = new AXmlResourceParser();
                        parser.open(zipFile.getInputStream(zipEntry));
                        while (true) {
                            int type = parser.next();
                            if (type == XmlPullParser.END_DOCUMENT) {
                                break;
                            }
                            String name = parser.getName();
                            if (null != name && name.toLowerCase().equals("manifest")) {
                                for (int i = 0; i != parser.getAttributeCount(); i++) {
                                    if ("package".equals(parser.getAttributeName(i))) {
                                        String packageName = getAttributeValue(parser, i);
                                        if (null == packageName) {
                                            packageName = "";
                                        }
                                        map.put("package", packageName);
                                    } else if ("versionCode".equals(parser.getAttributeName(i))) {
                                        String versionCode = getAttributeValue(parser, i);
                                        if (null == versionCode) {
                                            versionCode = "";
                                        }
                                        map.put("versionCode", versionCode);
                                    }
                                }
                                break;
                            }
                        }
                    }

                }
            }
            zipFile.close();
        } catch (Exception e) {
            map.put("code", "fail");
            map.put("error", "读取apk失败");
        }
        return map;
    }

    private static String getAttributeValue(AXmlResourceParser parser, int index) {
        int type = parser.getAttributeValueType(index);
        int data = parser.getAttributeValueData(index);
        if (type == TypedValue.TYPE_STRING) {
            return parser.getAttributeValue(index);
        }
        if (type == TypedValue.TYPE_ATTRIBUTE) {
            return String.format("?%s%08X", getPackage(data), data);
        }
        if (type == TypedValue.TYPE_REFERENCE) {
            return String.format("@%s%08X", getPackage(data), data);
        }
        if (type == TypedValue.TYPE_FLOAT) {
            return String.valueOf(Float.intBitsToFloat(data));
        }
        if (type == TypedValue.TYPE_INT_HEX) {
            return String.format("0x%08X", data);
        }
        if (type == TypedValue.TYPE_INT_BOOLEAN) {
            return data != 0 ? "true" : "false";
        }
        if (type == TypedValue.TYPE_DIMENSION) {
            return Float.toString(complexToFloat(data)) + DIMENSION_UNITS[data & TypedValue.COMPLEX_UNIT_MASK];
        }
        if (type == TypedValue.TYPE_FRACTION) {
            return Float.toString(complexToFloat(data)) + FRACTION_UNITS[data & TypedValue.COMPLEX_UNIT_MASK];
        }
        if (type >= TypedValue.TYPE_FIRST_COLOR_INT && type <= TypedValue.TYPE_LAST_COLOR_INT) {
            return String.format("#%08X", data);
        }
        if (type >= TypedValue.TYPE_FIRST_INT && type <= TypedValue.TYPE_LAST_INT) {
            return String.valueOf(data);
        }
        return String.format("<0x%X, type 0x%02X>", data, type);
    }

    private static String getPackage(int id) {
        if (id >>> 24 == 1) {
            return "android:";
        }
        return "";
    }

    public static float complexToFloat(int complex) {
        return (float) (complex & 0xFFFFFF00) * RADIX_MULTS[(complex >> 4) & 3];
    }

    private static final float RADIX_MULTS[] = { 0.00390625F, 3.051758E-005F, 1.192093E-007F, 4.656613E-010F };
    private static final String DIMENSION_UNITS[] = { "px", "dip", "sp", "pt", "in", "mm", "", "" };
    private static final String FRACTION_UNITS[] = { "%", "%p", "", "", "", "", "", "" };
}





你可能感兴趣的:(关于安卓自动升级的一些思路)