Android實戰系列(一)---版本更新

1、在啓動頁面裏,在啓動登錄頁面的同時,使用handler延遲0.2發送一個更新的廣播(確保登錄頁面啓動起來了啥)
LauncherGuide.java

AbsUI.startUI(context, LoginUI.class);
 handler.postDelayed(new Runnable() {

                    @Override
                    public void run() {
                        EventBus.getDefault().post(new Stype(Constant.LOGIN_Urage));
                    }
                }, 200);

2、Constant.LOGIN_Urage,被Login.java註冊了

Login{
...
onCreate(){
EventBus.getDefault().register(this);
}
...
 @Subscribe
    public void onEventMainThread(Stype ev) {
    ...
       if (ev.getMsg() == Constant.LOGIN_Urage) {
            checkVersion();
        } 
     ...
    }
}

如果使用onEventMainThread作爲訂閱函數,那麼不論事件是在哪個線程中發佈出來的,onEventMainThread都會在UI線程中執行.繼續往下看:版本更新的工具類。

UpgradeBean bean = new UpgradeBean();
        bean.setTypeID("1");    
        callBackHandler=new AsyncCallBackHandler(ui,showText,isShowDialog,null) {

            @Override
            public void mySuccess(int arg0, Header[] arg1, String result) {
                Log.e(TAG, "onPostExecute():result:" + result);
                // 調用接口
                if (adapter != null) {
                    // 完成接口
                    adapter.onQueryCompleted(result);
                    // 設置新版本
                    setNewVersion(adapter.getVersionNO());
                    //設置文件大小
                    setSize(adapter.getSize());
                    // 遠程下載地址
                    setDownloadRemoteUri( adapter.getDownloadRemoteUri() );
                    Log.i(TAG, "adapter.getVersionNO()"+adapter.getVersionNO());
                    boolean bUpgrade = isUpgrade(appInfo.getVersionName()+"."+appInfo.getVersionCode(),adapter.getVersionNO());

                    // 更新事件接口
                    adapter.onUpgrade(bUpgrade, appInfo.getVersionName(),adapter.getVersionNO(), getDownloadRemoteUri(), getDownloadLocalPath(),getSize());
                }

            }

            @Override
            public void myFailure(int arg0, Header[] arg1, String arg2, Throwable arg3) {
                Toast.makeText(ui, "網絡異常", Toast.LENGTH_SHORT).show();

            }
        };

        try {
            AsyncHttpUtil.post(context, queryUri, bean, "application/json", callBackHandler);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

實際上是調用後臺的版本更新的接口,使用AsyncHttpUtil封裝的一步http網絡post請求。

UpgradeBean會傳遞apk類型後臺

public class UpgradeBean {

    private String typeID ;//APP類型1安卓2IOS

    public String getTypeID() {
        return typeID;
    }

    public void setTypeID(String typeID) {
        this.typeID = typeID;
    }
}

Adapter是個接口

public interface Adapter {
        // 請求完成
        abstract void onQueryCompleted(String result);
        // http錯誤
        abstract void onHttpFailed(Error error, java.lang.Exception exception, int responseCode, byte[] out);
        // 獲取最新版本號
        abstract String getVersionNO();
        //文件大小
        abstract String getSize();
        // 更新事件
        abstract void onUpgrade(boolean upgrade, String oldVersion, String newVersion, String downloadRemoteUri, String downloadLocalPath,String size);
        // 獲取下載地址
        abstract String getDownloadRemoteUri();
        void onHttpFailed(java.lang.Error error, Exception exception,
                int responseCode, byte[] out);
    }

重點關心於是否更新,更新的實現,先看下服務端返回的數據結構

public class UpgradeMessageBean {
    private String msg;
    private int statu;
    private UpgradeMessage model;
    public class UpgradeMessage{
        private String VersionLink; 
        private String  VersionNo;//    V1.1.0.0
    }
public void onUpgrade(boolean upgrade, String oldVersion, String newVersion, String downloadRemoteUri, String downloadLocalPath,String size) {
                if (upgrade) {//比較手機和接口返回的版本

                    UpgradeNotificationBean notificationBean = new UpgradeNotificationBean();
                    notificationBean.setTitle(context.getResources().getString(R.string.app_name));

                    notificationBean.setOldVersion(oldVersion);
                    notificationBean.setNewVersion(newVersion);
                    notificationBean.setDownloadRemoteUri(downloadRemoteUri);
                    notificationBean.setDownloadLocalPath(downloadLocalPath);
                    notificationBean.setSize(size);
                    UpgradeDialog upgradeDialogF = new UpgradeDialog(ui);//這裏的ui不能改爲context,必須爲界面
                    upgradeDialogF.setTitle("版本更新");
                    upgradeDialogF.setContent(context.getResources().getString(R.string.app_name)+"新版發佈(v"+newVersion+")");


                    upgradeDialogF.setTaskBean(taskBean);
                    upgradeDialogF.setNotificationBean(notificationBean);
                    if (!ui.isFinishing()) {
                        upgradeDialogF.show();
                    }else {
                        Log.i(TAG, "ui.isFinishing()="+ui.isFinishing());
                    }

                }else{
                }
            }

upgradeDialogF對話框彈出後(版本不一致),有確定取消兩個按鈕

    btn_upgrade_sure.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                if (notificationBean != null) {
                    if (new NetworkState(context).isConnected() == false) {
                        Toast.makeText(context, "無網絡連接", Toast.LENGTH_SHORT).show();
                        return;
                    }
                    if (!UpgradeTaskUtil.isCanDownload) {
                        Toast.makeText(context, "沒有存儲卡,不能下載新版本", Toast.LENGTH_SHORT).show();
                        UpgradeDialog.this.dismiss();
                        return;
                    }
                    // 下載並且更新應用
                    UpgradeTask task = new UpgradeTask((android.support.v4.app.FragmentActivity)context);
                    if (notificationBean != null) {
                        task.setTitle( notificationBean.getTitle() );
                        task.setDownloadRemoteUri(notificationBean.getDownloadRemoteUri());
                        task.setDownloadLocalPath(notificationBean.getDownloadLocalPath());
                        task.download();
                    }
                    // 關閉自身窗口
                    UpgradeDialog.this.dismiss();
                }else{
                    Log.e(TAG, "notificationBean == null");
                }
            }
        });

        //下次再說
        btn_upgrade_cancle.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                EventBus.getDefault().post(new Stype(Constant.LOGIN_UI));
                UpgradeDialog.this.dismiss();
            }
        });

取消的話會給LoginUI發個廣播,說哥們不更新直接登錄就好了。
確定下載的話
則:

    new Thread(){
            public void run(){

                try {
                    URL url = new URL(downloadRemoteUri);
                    HttpURLConnection connection = (HttpURLConnection)url.openConnection();             connection.setConnectTimeout(5*1000);               
                    Message msg = Message.obtain();
                    msg.arg1 = connection.getResponseCode();
                    msg.what = MSG_RESPONDECODE;
                    handler.sendMessage(msg);

                } catch (Exception e) {
                    Log.i(TAG, "url 不可用=="+downloadRemoteUri);
                    handler.sendEmptyMessage(MSG_NO_FILE);

                }
            }
        }.start();

如果url不可用(404)則發MSG_NO_FILE,可用則把網絡請求的的返回code保存起來,同時發送MSG_RESPONDECODE廣播,

if(msg.arg1==200){
                downloadManager
                    }

通過內置的DownloadManager下載。

總結:
1、在軟件啓動後發送版本更新的廣播,設定soap請求的參數。
2、對返回的版本號、url進行覈對,版本一致,不提示用戶下載,版本不一致,彈框提示用戶。
3、用戶決定下載,如果url正確可用(httpUrlconnect),則用Android內置的DownloadManager下載,否則提示文件不存在。(ACTION_PACKAGE_REPLACED、ACTION_DOWNLOAD_COMPLETE、ACTION_PACKAGE_ADDED)可以監聽

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章