自动更新检测,结合网上资料编写

本文介绍了一个基于Android的应用自动更新机制实现方案,包括版本检查、更新提示、后台下载及安装流程。通过解析服务器上的XML配置文件来获取最新的版本信息,并在启动时自动检查更新。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.util.Log;
import android.util.Xml;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.view.WindowManager;
import android.view.animation.AlphaAnimation;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import org.json.JSONArray;
import org.json.JSONObject;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;

public class MainActivity extends AppCompatActivity {
    //常量定义
    public static final int UNKNOWN_ERROR = 99;
    public static final int GET_INFO_SUCCESS = 100;
    public static final int SERVER_ERROR = 101;
    public static final int SERVER_URL_ERROR = 102;
    public static final int PROTOCOL_ERROR = 103;
    public static final int IO_ERROR = 104;
    public static final int XML_PARSER_ERROR = 105;
    public static final int DOWN_ERROR = 106;
    public static final String TAG = "SplashActivity";

    //获取的服务器端的更新信息
    UpdateInfo updateinfo;
    //下载进度条
    private ProgressDialog pBar;
    //显示版本号的tv控件
    private TextView tv_splash_version;

    //布局控件
    private RelativeLayout r1_splash;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityManager.getInstance().addActivity(this);//将当前Activity加入到管理器,用于退出使用
        setContentView(R.layout.activity_main);
        //设置全屏模式
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        r1_splash = (RelativeLayout)findViewById(R.id.r1_splash);
        tv_splash_version = (TextView)findViewById(R.id.tv_splash_version);
        tv_splash_version.setText("版本号:" + getVersion());

        //显示渐进动画
        AlphaAnimation aa = new AlphaAnimation(0.3f, 1.0f);
        aa.setDuration(2000);
        r1_splash.startAnimation(aa);

        //检查更新
        new Thread(new checkUpdate()) {
        }.start();
    }

    @Override
    protected void onResume() {
        /**
         * 设置为横屏
         */
        if(getRequestedOrientation()!= ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE){
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        }
        super.onResume();
    }

    //获取当前应用程序的版本号
    private String getVersion() {
        String version = "";

        //获取系统包管理器
        PackageManager pm = this.getPackageManager();
        try {
            PackageInfo info = pm.getPackageInfo(getPackageName(), 0);
            version = info.versionName;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return version;
    }

    /**
     * 消息处理器
     */
    private Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case GET_INFO_SUCCESS:
                    String serverVersion = updateinfo.getVersion();
                    String currentVersion = getVersion();
                    if (currentVersion.equals(serverVersion)) {
                        Log.i(TAG, "版本号相同无需升级,直接进入主界面");
                        LoginMain();
                    }else {
                        Log.i(TAG, "版本号不同需升级,显示升级对话框");
                        showUpdateDialog();
                    }
                    break;
                case SERVER_ERROR:
                    Toast.makeText(getApplicationContext(), "服务器内部异常", Toast.LENGTH_SHORT).show();
                    LoginMain();
                    break;
                case SERVER_URL_ERROR:
                    Toast.makeText(getApplicationContext(), "服务器路径错误", Toast.LENGTH_SHORT).show();
                    LoginMain();
                    break;
                case PROTOCOL_ERROR:
                    Toast.makeText(getApplicationContext(), "协议错误", Toast.LENGTH_SHORT).show();
                    LoginMain();
                    break;
                case XML_PARSER_ERROR:
                    Toast.makeText(getApplicationContext(), "XML解析错误", Toast.LENGTH_SHORT).show();
                    LoginMain();
                    break;
                case IO_ERROR:
                    Toast.makeText(getApplicationContext(), "I/O错误", Toast.LENGTH_SHORT).show();
                    LoginMain();
                    break;
                case UNKNOWN_ERROR:
                    Toast.makeText(getApplicationContext(), "未知错误", Toast.LENGTH_SHORT).show();
                    LoginMain();
                    break;
                case DOWN_ERROR:
                    Toast.makeText(getApplicationContext(), "下载失败", Toast.LENGTH_SHORT).show();
                    LoginMain();
                    break;
            }
        }
    };

    /**
     * 检查更新
     */
    private class checkUpdate implements Runnable {
        public void run() {
            long startTime = System.currentTimeMillis();
            long endTime = startTime;
            Message msg = Message.obtain();
            try {
                //获取服务器更新地址
                String serverurl = getResources().getString(R.string.serverurl);
                URL url = new URL(serverurl);
                HttpURLConnection conn = (HttpURLConnection)url.openConnection();
                conn.setRequestMethod("GET");
                conn.setConnectTimeout(5000);
                int code = conn.getResponseCode();
                if (code == 200) {
                    //success
                    InputStream is = conn.getInputStream();
                    //解析出更新信息
                    updateinfo = UpdateInfoParser.getUpdateInfo(is);
                    endTime = System.currentTimeMillis();
                    long time = endTime - startTime;
                    if (time < 2000) {
                        try {
                            Thread.sleep(2000 - time);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

                    msg.what = GET_INFO_SUCCESS;
                    handler.sendMessage(msg);
                } else {
                    //服务器错误
                    msg.what = SERVER_ERROR;
                    handler.sendMessage(msg);
                    endTime = System.currentTimeMillis();
                    long time = endTime - startTime;
                    if (time < 2000) {
                        try {
                            Thread.sleep(2000 - time);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }

            } catch (MalformedURLException e) {
                msg.what = SERVER_URL_ERROR;
                handler.sendMessage(msg);
                e.printStackTrace();
            } catch (ProtocolException e) {
                msg.what = PROTOCOL_ERROR;
                handler.sendMessage(msg);
                e.printStackTrace();
            } catch (IOException e) {
                msg.what = IO_ERROR;
                handler.sendMessage(msg);
                e.printStackTrace();
            } catch (XmlPullParserException e) {
                msg.what = XML_PARSER_ERROR;
                handler.sendMessage(msg);
                e.printStackTrace();
            } catch (Exception e) {
                msg.what = UNKNOWN_ERROR;
                handler.sendMessage(msg);
                e.printStackTrace();
            }

        }
    }
    /**
     * 显示升级提示对话框
     */
    protected void showUpdateDialog() {
        //创建对话框构造器
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        //设置对话框图标
        //builder.setIcon(getResources().getDrawable(R.drawable.notification));
        //设置对话框标题
        builder.setTitle("升级提示");
        //设置更新信息为对话框提示内容
        builder.setMessage(updateinfo.getDesc());
        //设置升级按钮及响应事件
        builder.setPositiveButton("升级", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                downLoadApk();
            }
        });
        //设置取消按钮及响应事件
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {

            }
        });

        //创建并显示对话框
        builder.create().show();
    }

    public static File getFileFromServer(String path, ProgressDialog pd) throws Exception{
        //如果相等的话表示当前的sdcard挂载在手机上并且是可用的
        if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
            URL url = new URL(path);
            HttpURLConnection conn =  (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(5000);
            //获取到文件的大小
            pd.setMax(conn.getContentLength());
            InputStream is = conn.getInputStream();
            File file = new File(Environment.getExternalStorageDirectory(), "update.apk");
            FileOutputStream fos = new FileOutputStream(file);
            BufferedInputStream bis = new BufferedInputStream(is);
            byte[] buffer = new byte[1024];
            int len ;
            int total=0;
            while((len =bis.read(buffer))!=-1){
                fos.write(buffer, 0, len);
                total+= len;
                //获取当前下载量
                pd.setProgress(total);
            }
            fos.close();
            bis.close();
            is.close();
            return file;
        }
        else{
            return null;
        }
    }

    /*
 * 从服务器中下载APK
 */
    protected void downLoadApk() {
        final ProgressDialog pd;    //进度条对话框
        pd = new  ProgressDialog(this);
        pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        pd.setMessage("正在下载更新");
        pd.show();
        new Thread(){
            @Override
            public void run() {
                try {
                    File file = getFileFromServer(updateinfo.getApkurl(), pd);
                    sleep(3000);
                    installApk(file);
                    pd.dismiss(); //结束掉进度条对话框
                } catch (Exception e) {
                    Message msg = new Message();
                    msg.what = DOWN_ERROR;
                    handler.sendMessage(msg);
                    e.printStackTrace();
                }
            }}.start();
    }

    //安装apk
    protected void installApk(File file) {
        Intent intent = new Intent();
        //执行动作
        intent.setAction(Intent.ACTION_VIEW);
        //执行的数据类型
        intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
        startActivity(intent);
    }

    /*
 * 进入程序的主界面
 */
    private void LoginMain(){
        Intent intent = new Intent(this,Login.class);
        startActivity(intent);
        //结束掉当前的activity
        this.finish();
    }
}



/**
 * Created by cangyun on 2016-09-21.
 */
public class UpdateInfo {

    //服务器端版本号
    private String version;

    //服务器端升级提示
    private String desc;

    //服务器端apk下载地址
    private String apkurl;

    public String getVersion() {
        return version;
    }

    public void setVersion(String version) {
        this.version = version;
    }
    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public String getApkurl() {
        return apkurl;
    }

    public void setApkurl(String apkurl) {
        this.apkurl = apkurl;
    }
}



import android.util.Xml;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.io.InputStream;
/**
 * Created by cangyun on 2016-09-21.
 */
public class UpdateInfoParser {
    /**
     *解析一个utf-8格式的xml输入流,返回一个UpdateInfo对象
     * XmlPullParser解析bug参考解决:http://blog.youkuaiyun.com/nxh_love/article/details/7109762
     * @param is
     * @return UpdateInfo对象
     * @throws XmlPullParserException
     * @throws IOException
     */
    public static UpdateInfo getUpdateInfo(InputStream is) throws XmlPullParserException, IOException {
        UpdateInfo info = new UpdateInfo();

        //获取一个pull解析的实例
        XmlPullParser parser = Xml.newPullParser();

        //解析xml
        parser.setInput(is, "UTF-8");
        parser.nextTag();
        int type = parser.getEventType();
        while (parser.nextTag() == XmlPullParser.START_TAG) {
            String tag = parser.getName();
            String text = parser.nextText();
            if (parser.getEventType() != XmlPullParser.END_TAG) {
                parser.nextTag();
            }
            if (tag.equals("ver")) {
                info.setVersion(text);
            } else if (tag.equals("desc")) {
                info.setDesc(text);
            } else if (tag.equals("apkurl")) {
                info.setApkurl(text);
            }
        }

        return info;
    }
}


update.xml


<?xml version="1.0" encoding="utf-8"?>
<info>
    <version>1.1</version>
    <apkurl>http://www.xxxxxx.com:8080/xx/xx-debug.apk</apkurl>
    <desc>检测到最新版本,请及时更新!</desc>
</info>


AndroidManifest

android:versionName="1.1"
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值