1. 程式人生 > >關於Android 版本更新

關於Android 版本更新

版本更新是個老話題了,第三方框架也有許多,在這裡就不多做介紹了,給大家來點乾貨方便大家學習。本本主要是依據後臺提供的

versionCode和本地的versionCode進行比較,包含了強制升級和非強制升級兩種廢話不多說直接上乾貨了:

首先需要申明變數

private String BANBENHAO = "";//被忽略的版本號

private boolean isFirst;//判斷髮現新版本後是否是第一次彈出升級框

在資料獲取成功後進行呼叫方法

publicvoiddataOkIsUpgrade(){

final String versionCode = bean.versionCode

;//從網上獲取的版本號

String downLoadUrl = "";//下載地址

if (bean != null &&bean.downLoadUrl!= null) {

    downLoadUrl = bean.downLoadUrl;

}

final String mFinalDownloadUrl = downLoadUrl;

double serviceCode = Double.parseDouble(versionCode);

//

TDevice.getVersionCode()是獲取本地versionCode的方法

double code = TDevice.getVersionCode

();

//從網上獲取是否需強制升級 1代表強制升級,0 代表非強制升級

String isForceUpdate= "";

if (!bean.isForce.equals("")) {   

isForceUpdate = bean.isForce;

}

//從網上獲取的更新資訊內容

String updateInfo = "";

if (!bean.updateInfo.equals("")) {   

updateInfo = bean.updateInfo;

}

final String updateDes = updateInfo;

//儲存從網上獲取的serviceCode

SPHelper.getInst().saveString("serviceCode", versionCode);

//判斷是否忽略過版本  SPHelper是一個

SharedPreferences的工具類為了方便使用


BANBENHAO = SPHelper.getInst().getString("BANBENHAO");

if (!BANBENHAO.equals("")) {   

double SERVICECD = Double.parseDouble(BANBENHAO);   

if (SERVICECD < serviceCode) {      

 isFirst = true;   

} else {     

  isFirst = false;   

}   

SPHelper.getInst().saveBoolean("isFirst",isFirst);

} else {   

isFirst = true;  

 BANBENHAO =versionCode;   

SPHelper.getInst().saveBoolean("isFirst",isFirst);

}

//判斷髮現新版本後是否是第一次彈出升級框

isFirst = SPHelper.getInst().getBoolean("isFirst");

//判斷是否需要版本升級

if (code != serviceCode && code <serviceCode) {  

 SPHelper.getInst().saveString("downLoadUrl", downLoadUrl);   

if (isFirst||isForceUpdate.equals("1")) {      

 selfDialog =new SelfDialog(getContext(), R.style.dialog, updateDes);      

  selfDialog.show();      

 selfDialog.setYesOnclickListener("立即升級",new SelfDialog.onYesOnclickListener() {       

    @Override          

publicvoidonYesClick() {     

        new UpdateManager(getContext(),_mActivity,mFinalDownloadUrl);              

       selfDialog.dismiss();         

       }     

  });      

 //若強制升級顯示      

if(isForceUpdate.equals("1")) {      

     selfDialog.setNoOnclickListener("退出",new SelfDialog.onNoOnclickListener(){          

     @Override             

public voidonNoClick() {                 

       selfDialog.dismiss();             

       getActivity().finish();           

       }          

    });      

} else if (isForceUpdate.equals("0")) {     

      //若非強制升級時顯示          

selfDialog.setNoOnclickListener("忽略此次",new SelfDialog.onNoOnclickListener(){            

   @Override            

publicvoidonNoClick() {                 

   isFirst = false;                  

   SPHelper.getInst().saveBoolean("isFirst",isFirst);                

   //儲存到本地                 

BANBENHAO= versionCode;              

   SPHelper.getInst().saveString("updateDes",updateDes);                

   SPHelper.getInst().saveString("BANBENHAO",BANBENHAO);                  

   selfDialog.dismiss();               

 }          

 });      

 }  

 }

}

}

下面給大家來一個上面用到的自定義的dialog 

SelfDialog

//自定義dialog

public class SelfDialogextends Dialog {

    //確定文字和取消文字的顯示內容

privateString yesStr,noStr;

    private onNoOnclickListenernoOnclickListener;//取消按鈕被點選了的監聽器

privateonYesOnclickListener yesOnclickListener;//確定按鈕被點選了的監聽器

privateTextView selfMSG;

    private Buttonyes, no;

    private StringversonMSG;

    public SelfDialog(Contextcontext) {

        super(context);

    }

    public SelfDialog(Contextcontext,int themeResId) {

        super(context,themeResId);

    }

    public SelfDialog(Contextcontext,int themeResId ,String versonMSG) {

        super(context,themeResId);

        this.versonMSG=versonMSG;

    }

    /**

     * 設定取消按鈕的顯示內容和監聽

     *

     * @param str

*@param onNoOnclickListener

*/

public voidsetNoOnclickListener(String str, onNoOnclickListener onNoOnclickListener){

        no.setText(str);

        if (str!=null) {

            noStr = str;

        }

        this.noOnclickListener= onNoOnclickListener;

    }

    /**

     * 設定確定按鈕的顯示內容和監聽

     *

     * @param str

*@param onYesOnclickListener

*/

public voidsetYesOnclickListener(String str, onYesOnclickListeneronYesOnclickListener) {

        yes.setText(str);

        if (str!=null) {

            yesStr = str;

        }

        this.yesOnclickListener= onYesOnclickListener;

    }

    @Override

protected voidonCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.selfdialog);

        initView();

        setCancelable(false);

        //初始化介面控制元件的事件

initEvent();

    }

    private void initEvent() {

        //設定確定按鈕被點選後,向外界提供監聽

yes.setOnClickListener(newView.OnClickListener() {

            @Override

public voidonClick(View v) {

                if (yesOnclickListener!= null) {

                    yesOnclickListener.onYesClick();

                }

            }

        });

        //設定取消按鈕被點選後,向外界提供監聽

no.setOnClickListener(newView.OnClickListener() {

            @Override

public voidonClick(View v) {

                if (noOnclickListener!= null) {

                    noOnclickListener.onNoClick();

                }

            }

        });

    }

    private void initView() {

        selfMSG = ((TextView) findViewById(R.id.selfdg_mesg));

        yes =(Button) findViewById(R.id.selfdg_yes);

        no = (Button) findViewById(R.id.selfdg_no);

        selfMSG.setText(versonMSG);

    }

    /**

     * 設定確定按鈕和取消被點選的介面

     */

public interfaceonYesOnclickListener {

        public void onYesClick();

    }

    public interface onNoOnclickListener {

        public void onNoClick();

    }

}

SelfDialog的佈局

<?xml version="1.0"encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="match_parent"

android:gravity="center"

android:orientation="vertical">

    <LinearLayout

android:layout_width="250dp"

android:layout_height="wrap_content"

android:layout_marginLeft="27dip"

android:layout_marginRight="27dip"

android:background="@drawable/shape_dialog"

android:orientation="vertical">

        <TextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center"

android:layout_marginTop="18dip"

android:text="發現新版本請更新"

android:textColor="@color/Title_color"

android:textSize="20sp"/>

        <TextView

android:id="@+id/selfdg_mesg"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginLeft="26dp"

android:layout_marginRight="20dp"

android:layout_marginTop="18dip"

android:text="避免影響使用及時請更新"

android:textSize="14sp"/>

        <LinearLayout

android:layout_width="210dp"

android:layout_height="33dp"

android:layout_gravity="center|bottom"

android:layout_marginBottom="20dp"

android:layout_marginTop="23dp">

            <Button

android:id="@+id/selfdg_yes"

android:layout_width="0dp"

android:layout_height="match_parent"

android:layout_weight="1"

android:background="@drawable/shape_bottom"

android:text="確定"

android:paddingLeft="15dp"

android:paddingRight="15dp"

android:textColor="@color/white"

android:textSize="16sp"/>

            <View

android:layout_width="15dp"

android:layout_height="match_parent"/>

            <Button

android:id="@+id/selfdg_no"

android:layout_width="0dp"

android:layout_height="match_parent"

android:layout_weight="1"

android:background="@drawable/shap_gray_bottom"

android:text="取消"

android:paddingLeft="15dp"

android:paddingRight="15dp"

android:textColor="@color/white"

android:textSize="16sp"/>

        </LinearLayout>

    </LinearLayout>

</LinearLayout>

上面還用到了一個style其實很簡單為了方便就一遍給大家了

<style

name="dialog"

parent="@android:style/Theme.Dialog">

    <item name="android:windowFrame">@null</item>

    <item name="android:windowIsFloating">true</item>

    <item name="android:windowIsTranslucent">false</item>

    <item name="android:windowNoTitle">true</item>

    <item name="android:windowBackground">@android:color/transparent</item>

    <item name="android:backgroundDimEnabled">true</item>

</style>

再下來就是下載的工具了 下載完成後會彈出安裝頁面哦

public class UpdateManager {

    /* 下載中 */

private static final intDOWNLOAD = 1;

    /* 下載結束 */

private static final intDOWNLOAD_FINISH = 2;

    /* 下載儲存路徑 */

privateString mSavePath;

    /* 記錄進度條數量 */

private intprogress;

    /* 是否取消更新 */

private booleancancelUpdate = false;

    private Activityactivity;

    private ContextmContext;

    /* 更新進度條 */

privateProgressBar mProgress;

    private TextViewtv;

    private DialogmDownloadDialog;

    /**

     * 下載連結

     */

privateString path ="";

    /*檔名*/

privateString name ="";

    private HandlermHandler = newHandler(){

        public void handleMessage(Message msg) {

            switch (msg.what) {

                // 正在下載

caseDOWNLOAD:

                    // 設定進度條位置

mProgress.setProgress(progress);

                    tv.setText("已完成 : "+ progress+ "%");

                    break;

                case DOWNLOAD_FINISH:

                    // 安裝檔案

installApk();

                    break;

                default:

                    break;

            }

        } ;

    };

    public UpdateManager(Contextcontext, Activity activity ,String downLoadUrl) {

        this.mContext= context;

        this.activity= activity;

        this.path= downLoadUrl;

        if(!downLoadUrl.equals("")) {

            this.name= path.substring(path.lastIndexOf("/") +1);

        }

        showDownloadDialog();

    }

    /**

     * 下載對話方塊

     */

private voidshowDownloadDialog() {

        // 構造軟體下載對話方塊

mDownloadDialog= new Dialog(mContext, R.style.dialog);

        Builder builder = new Builder(mContext);

        // 給下載對話方塊增加進度條

finalLayoutInflaterinflater = LayoutInflater.from(mContext);

        View v = inflater.inflate(R.layout.softupdate_progress,null);

        mProgress = (ProgressBar) v.findViewById(R.id.update_progress);

        tv =(TextView) v.findViewById(R.id.xiazaijindu);

        builder.setView(v);

//        // 取消更新

//        builder.setNegativeButton("取消", new OnClickListener() {

//            @Override

//            public void onClick(DialogInterfacedialog, int which) {

//                dialog.dismiss();

//                // 設定取消狀態

//                cancelUpdate = true;

//            }

//        });

mDownloadDialog= builder.create();

        mDownloadDialog.setCancelable(false);

        mDownloadDialog.show();

        // 現在檔案

if(!path.equals("")) {

            downloadApk();

        }

    }

    /**

     * 下載apk檔案

     */

private voiddownloadApk() {

        // 啟動新執行緒下載軟體

newdownloadApkThread().start();

    }

    /**

     * 下載檔案執行緒

     */

private classdownloadApkThread extends Thread {

        @Override

public voidrun() {

            try {

                // 判斷SD卡是否存在,並且是否具有讀寫許可權

if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {

                    // 獲得儲存卡的路徑

String sdpath = Environment.getExternalStorageDirectory()+"/";

                    mSavePath= sdpath + "download";

                    URL url = newURL(path);

                    // 建立連線

HttpURLConnection conn = (HttpURLConnection)url.openConnection();

                    conn.connect();

                    // 獲取檔案大小

intlength = conn.getContentLength();

                    // 建立輸入流

InputStream is = conn.getInputStream();

                    File file = newFile(mSavePath);

                    // 判斷檔案目錄是否存在

if(!file.exists()) {

                        file.mkdir();

                    }

                    File apkFile = newFile(mSavePath,name);

                    FileOutputStream fos = newFileOutputStream(apkFile);

                    int count=0;

                    // 快取

bytebuf[] = newbyte[1024];

                    // 寫入到檔案中

do{

                        int numread = is.read(buf);

                        count += numread;

                        // 計算進度條位置

progress= (int) (((float)count / length) *100);

                        // 更新進度

mHandler.sendEmptyMessage(DOWNLOAD);

                        if (numread <= 0) {

                            // 下載完成

mHandler.sendEmptyMessage(DOWNLOAD_FINISH);

                            break;

                        }

                        // 寫入檔案

fos.write(buf,0,numread);

                    } while (!cancelUpdate);//點選取消就停止下載.

fos.close();

                    is.close();

                }

            } catch (MalformedURLExceptione) {

                e.printStackTrace();

            } catch (IOExceptione) {

                e.printStackTrace();

            }

            // 取消下載對話方塊顯示

mDownloadDialog.dismiss();

        }

    }

    ;

    /**

     * 安裝APK檔案

     */

private voidinstallApk() {

        File apkfile = new File(mSavePath, name);

        if (!apkfile.exists()){

            return;

        }

        // 通過Intent安裝APK檔案

Intent intent = new Intent(Intent.ACTION_VIEW);

   //補充******************************

//如果不加,最後安裝完成,點開啟,無法開啟新版本應用。

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

//補充分割線****************************************************

  intent.setDataAndType(Uri.fromFile(apkfile),

                "application/vnd.android.package-archive");

        mContext.startActivity(intent);

        activity.finish();

    }

}

再來就是下載進度條的佈局很簡單的

<?xml version="1.0"encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:gravity="center"

android:orientation="vertical">

    <LinearLayout

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:background="@drawable/shape_dialog"

android:orientation="vertical">

        <TextView

android:layout_marginTop="20dp"

android:gravity="center"

android:layout_marginLeft="27dip"

android:layout_marginRight="27dip"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="正在下載"/>

        <ProgressBar

android:layout_marginLeft="27dip"

android:layout_marginRight="27dip"

android:id="@+id/update_progress"

android:layout_marginTop="20dip"

style="?android:attr/progressBarStyleHorizontal"

android:layout_width="match_parent"

android:layout_height="wrap_content"/>

        <TextView

android:gravity="center"

android:layout_marginLeft="27dip"

android:layout_marginRight="27dip"

android:id="@+id/xiazaijindu"

android:layout_marginTop="20dip"

android:layout_marginBottom="10dp"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="0%"/>

    </LinearLayout>

</LinearLayout>

好了上面這些完成就可以在首頁載入資料是彈出升級提示框,具體的那些

drawable檔案都是些自定義的就不給大家了

如果在設定裡有檢查版本的話可以新增下面的程式碼

//獲取當前網路版本號

private double getServiceCode() {

    double serviceCode= Double.parseDouble(getInst().getString("serviceCode"));

    return serviceCode;

}

//判斷是否需要升級

private boolean isUpdate() {

    if (versionCode!= getServiceCode() && versionCode< getServiceCode()) {

        String URL = getInst().getString("downLoadUrl");

        if (!URL.equals("")) {

            final StringmDownLoadUrl = URL;

            String updateDes = SPHelper.getInst().getString("updateDes");

            selfDialog = new SelfDialog(getContext(), R.style.dialog, updateDes);

            selfDialog.show();

            selfDialog.setYesOnclickListener("立即升級",new SelfDialog.onYesOnclickListener(){

                @Override

public voidonYesClick() {

                    new UpdateManager(getContext(),_mActivity,mDownLoadUrl);

                    selfDialog.dismiss();

                }

            });

            selfDialog.setNoOnclickListener("取消",new SelfDialog.onNoOnclickListener(){

                @Override

public voidonNoClick() {

                    selfDialog.dismiss();

                }

            });

            return true;

        }

        return false;

    } else {

        Toast.makeText(getContext(), "已是最新版本無需更新", Toast.LENGTH_LONG).show();

        return false;

    }

}

點選檢查更新的按鈕執行

isUpdate()方法就好了,至於檢查更新是否有提示可以根據

//獲取是否忽略過版本更新

String banben =SPHelper.getInst().getString("BANBENHAO");

來判斷。好了如果本文對您有幫助記得點個贊哦,謝謝!!

以下為修改內容並製作成了module 新增依賴後可直接呼叫

例如:

VersionUpdatedUtils.isVersionUpdated(this,"3","","1","");

說明:傳入引數依次為上下文,版本號,下載連結,是否為強制升級(1 代表強制升級,0 代表非強制升級),更新資訊

在設定中需要點選事件時可新增以下程式碼

//判斷是否需要升級

private boolean isUpdate() {

    if (versionCode!= getServiceCode() && versionCode< getServiceCode()) {

        String URL = getInst().getString("downLoadUrl");

        if (!URL.equals(""))