联网更新App

2018-09-27  本文已影响3人  GeekGray

阅读原文

联网更新应用

把图给贴上,先把逻辑整得明明白白!

image

1. 判断是否有网络

  这里的联网更新应用操作在SplashActivity(渲染/欢迎界面)中执行,只针对该功能做笔记,而不涉及其他类似于冷启动优化等的知识摘录!

在SplashActivity中定义好需要用到的变量。

private static final int TO_MAIN = 1;//是否进入MainActivity

private static final int DOWNLOAD_VERSION_SUCCESS = 2;//解析版本数据成功

private static final int DOWNLOAD_APK_FAIL = 3;//下载失败

private static final int DOWNLOAD_APK_SUCCESS = 4;//下载成功

private boolean connect;//是否联网的标志

private long startTime;//系统当前时间

private UpdateInfo updateInfo;//json数据对应的更新信息bean类对象

private ProgressDialog dialog;//初始化水平进度条的dialog

private File apkFile;

private Handler handler = new Handler()

首先判断是否有网络

public boolean isConnect()
    {
        boolean connected = false;

        ConnectivityManager manager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = manager.getActiveNetworkInfo();
        if (networkInfo != null)
        {
            connected = networkInfo.isConnected();
        }
        return connected;
    }

toMain()

如果联网失败则进入主界面,这里SplashActivity涉及到动画的操作,所以获取一下当前系统时间,通过handle发送延迟消息

 private void toMain()
    {
        long currentTime = System.currentTimeMillis();
        long delayTime = 3000 - (currentTime - startTime);
        if (delayTime < 0)
        {
            delayTime = 0;
        }


        handler.sendEmptyMessageDelayed(TO_MAIN, delayTime);
    }

2. 联网获取效应数据

如果获取效应数据失败,进入到主界面,如果获取响应数据成功,则判断当前app版本与服务器版本是否一致。
综合1,2两步具体代码如下:

//联网请求更新的地址
public static final String URL_UPDATE = BASE_URL + "update.json";

    /**
     * 联网更新应用
     */
    private void updateApkFile()
    {
        //获取系统当前时间
        startTime = System.currentTimeMillis();

        //1.判断手机是否可以联网
        boolean connect = isConnect();
        if (!connect)
        {//没有移动网络
            UIUtils.toast("当前没有移动数据网络", false);
            toMain();
        }
        else
        {//有移动网络
            //联网获取服务器的最新版本数据
            AsyncHttpClient client = new AsyncHttpClient();
            String url = AppNetConfig.UPDATE;
            client.post(url, new AsyncHttpResponseHandler()
            {
                @Override
                public void onSuccess(String content)
                {
                    //解析json数据
                    updateInfo = JSON.parseObject(content, UpdateInfo.class);
                    handler.sendEmptyMessage(DOWNLOAD_VERSION_SUCCESS);
                }

                @Override
                public void onFailure(Throwable error, String content)
                {
                    UIUtils.toast("联网请求数据失败", false);
                    toMain();
                }
            });

        }
    }

3. 判断两个版本是否一致

如果版本号一致则进入主界面,若不一致则显示提示下载的Dialog

                    //获取当前应用的版本信息
                    String version = getVersion();
                    //更新页面显示的版本信息
                    tvWelcomeVersion.setText(version);
                    //比较服务器获取的最新的版本跟本应用的版本是否一致

 if (version.equals(updateInfo.version))//版本一致则进入主界面
                    {
                        UIUtils.toast("当前应用已经是最新版本", false);
                        toMain();
                    }
                    else//版本不一致,new一个Dialog提示,点击确定则下载服务器应用数据,取消则进入主界面
                    {
                        new AlertDialog.Builder(SplashActivity.this)
                                .setTitle("下载最新版本")
                                .setMessage(updateInfo.desc)
                                .setPositiveButton("确定", new DialogInterface.OnClickListener()
                                {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which)
                                    {
                                        //下载服务器保存的应用数据
                                        downloadApk();
                                    }
                                })
                                .setNegativeButton("取消", new DialogInterface.OnClickListener()
                                {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which)
                                    {
                                        toMain();
                                    }
                                })
                                .show();
                    }

获取当前版本号

    /**
     * 当前版本号
     *
     * @return
     */
    private String getVersion()
    {
        String version = "未知版本";
        PackageManager manager = getPackageManager();
        try
        {
            PackageInfo packageInfo = manager.getPackageInfo(getPackageName(), 0);
            version = packageInfo.versionName;
        }
        catch (PackageManager.NameNotFoundException e)
        {
            //e.printStackTrace(); //如果找不到对应的应用包信息, 就返回"未知版本"
        }
        return version;
    }

4. 是否要下载最新版

若不下载则进入主界面,如果下载,则启动分线程下载

downloadApk()

这里使用的是HttpURLConnection联网操作和文件的输入输出流,当然也可以使用常用的联网框架!

    /**
     * 下载APk
     */
    private void downloadApk()
    {
        //初始化水平进度条的dialog
        dialog = new ProgressDialog(this);
        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        dialog.setCancelable(false);
        dialog.show();
        //初始化数据要保持的位置
        File filesDir;
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
        {
            filesDir = this.getExternalFilesDir("");
        }
        else
        {
            filesDir = this.getFilesDir();
        }
        apkFile = new File(filesDir, "update.apk");

        //启动一个分线程联网下载数据:
        new Thread()
        {
            public void run()
            {
                String path = updateInfo.apkUrl;
                InputStream is = null;
                FileOutputStream fos = null;
                HttpURLConnection conn = null;
                try
                {
                    URL url = new URL(path);
                    conn = (HttpURLConnection) url.openConnection();

                    conn.setRequestMethod("GET");
                    conn.setConnectTimeout(5000);
                    conn.setReadTimeout(5000);

                    conn.connect();

                    if (conn.getResponseCode() == 200)
                    {
                        dialog.setMax(conn.getContentLength());//设置dialog的最大值
                        is = conn.getInputStream();
                        fos = new FileOutputStream(apkFile);

                        byte[] buffer = new byte[1024];
                        int len;
                        while ((len = is.read(buffer)) != -1)
                        {
                            //更新dialog的进度
                            dialog.incrementProgressBy(len);
                            fos.write(buffer, 0, len);

                            SystemClock.sleep(1);
                        }

                        handler.sendEmptyMessage(DOWNLOAD_APK_SUCCESS);

                    }
                    else
                    {
                        handler.sendEmptyMessage(DOWNLOAD_APK_FAIL);

                    }

                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
                finally
                {
                    if (conn != null)
                    {
                        conn.disconnect();
                    }
                    if (is != null)
                    {
                        try
                        {
                            is.close();
                        }
                        catch (IOException e)
                        {
                            e.printStackTrace();
                        }
                    }
                    if (fos != null)
                    {
                        try
                        {
                            fos.close();
                        }
                        catch (IOException e)
                        {
                            e.printStackTrace();
                        }
                    }
                }


            }
        }.start();


    }

5.是否下载成功

若下载成功则安装apk

    /**
     * 安装Apk
     */
    private void installApk()
    {
        Intent intent = new Intent("android.intent.action.INSTALL_PACKAGE");
        intent.setData(Uri.parse("file:" + apkFile.getAbsolutePath()));
        startActivity(intent);
    }

6. 在handle中处理发送过来的消息

private Handler handler = new Handler()
    {
        @Override
        public void handleMessage(Message msg)
        {
            switch (msg.what)
            {
                case TO_MAIN:
                    finish();
                    startActivity(new Intent(SplashActivity.this, MainActivity.class));
                    break;

                case DOWNLOAD_VERSION_SUCCESS:
                    //获取当前应用的版本信息
                    String version = getVersion();
                    //更新页面显示的版本信息
                    tvWelcomeVersion.setText(version);
                    //比较服务器获取的最新的版本跟本应用的版本是否一致
                    if (version.equals(updateInfo.version))//版本一致则进入主界面
                    {
                        UIUtils.toast("当前应用已经是最新版本", false);
                        toMain();
                    }
                    else//版本不一致,new一个Dialog提示,点击确定则下载服务器应用数据,取消则进入主界面
                    {
                        new AlertDialog.Builder(SplashActivity.this)
                                .setTitle("下载最新版本")
                                .setMessage(updateInfo.desc)
                                .setPositiveButton("确定", new DialogInterface.OnClickListener()
                                {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which)
                                    {
                                        //下载服务器保存的应用数据
                                        downloadApk();
                                    }
                                })
                                .setNegativeButton("取消", new DialogInterface.OnClickListener()
                                {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which)
                                    {
                                        toMain();
                                    }
                                })
                                .show();
                    }

                    break;

                case DOWNLOAD_APK_FAIL:
                    UIUtils.toast("联网下载数据失败", false);
                    toMain();
                    break;

                case DOWNLOAD_APK_SUCCESS:
                    UIUtils.toast("下载应用数据成功", false);
                    dialog.dismiss();//隐藏当前的Dialog
                    installApk();//安装下载好的应用
                    finish();//结束当前的welcomeActivity的显示
                    break;
            }

        }
    };

7. 消息移除

  @Override
    protected void onDestroy()
    {
        //把所有的消息和回调移除
        handler.removeCallbacksAndMessages(null);
        super.onDestroy();
        ButterKnife.unbind(this);
    }
上一篇下一篇

猜你喜欢

热点阅读