1. 程式人生 > >android 實現app內部檢測最新版本 自動升級到最新版本

android 實現app內部檢測最新版本 自動升級到最新版本

app現在基本都有版本更新這個功能,實現起來也很簡單

截圖效果:


1. 獲取當前app的版本號

/**
     * 獲取版本號
     *
     * @throws PackageManager.NameNotFoundException
     */
    public static String getVersionName(Context context) throws PackageManager.NameNotFoundException {
        // 獲取packagemanager的例項
        PackageManager packageManager = context.getPackageManager();
        // getPackageName()是你當前類的包名,0代表是獲取版本資訊
        PackageInfo packInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
        String version = packInfo.versionName;
        return version;
    }
2.根據版本號名稱判斷版本高低
  /**
     * 版本號比較
     *0代表相等,1代表version1大於version2,-1代表version1小於version2
     * @param version1
     * @param version2
     * @return
     */
    public static int compareVersion(String version1, String version2) {
        if (version1.equals(version2)) {
            return 0;
        }
        String[] version1Array = version1.split("\\.");
        String[] version2Array = version2.split("\\.");
        int index = 0;
        // 獲取最小長度值
        int minLen = Math.min(version1Array.length, version2Array.length);
        int diff = 0;
        // 迴圈判斷每位的大小
        while (index < minLen
                && (diff = Integer.parseInt(version1Array[index])
                - Integer.parseInt(version2Array[index])) == 0) {
            index++;
        }
        if (diff == 0) {
            // 如果位數不一致,比較多餘位數
            for (int i = index; i < version1Array.length; i++) {
                if (Integer.parseInt(version1Array[i]) > 0) {
                    return 1;
                }
            }

            for (int i = index; i < version2Array.length; i++) {
                if (Integer.parseInt(version2Array[i]) > 0) {
                    return -1;
                }
            }
            return 0;
        } else {
            return diff > 0 ? 1 : -1;
        }
    }
3.從伺服器獲取最新版本號
/**
     * 從伺服器獲取版本最新的版本資訊
     */
    private void getVersionInfoFromServer(){
        //模擬從伺服器獲取資訊  模擬更新王者榮耀
        versionInfoBean = new VersionInfoBean("1.1.1","http://dlied5.myapp.com/myapp/1104466820/sgame/2017_com.tencent.tmgp.sgame_h162_1.33.1.8_9c4c7f.apk","1.修復若干bug\n\n2.新增圖片編輯功能"
        ,getExternalCacheDir()+"/1.1.1.jpg");
        SharedPreferences sharedPreferences = getSharedPreferences("data",MODE_PRIVATE);
        sharedPreferences.edit().putString("url",versionInfoBean.getDownloadUrl()).commit();
        sharedPreferences.edit().putString("path",versionInfoBean.getPath()).commit();//getExternalCacheDir獲取到的路徑 為系統為app分配的記憶體 解除安裝app後 該目錄下的資源也會刪除
        //比較版本資訊
        try {
            int result = Utils.compareVersion(Utils.getVersionName(this),versionInfoBean.getVersionName());
            if(result==-1){//不是最新版本
                showDialog();
            }else{
                Toast.makeText(MainActivity.this,"已經是最新版本",Toast.LENGTH_SHORT).show();
            }
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }

    }

4.彈出dialog提示更新
 private  void showDialog(){
        final Dialog dialog = new Dialog(MainActivity.this);
        LayoutInflater inflater = (LayoutInflater)MainActivity.this
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        TextView version,content;
        Button    left,right;
        View view = inflater.inflate(R.layout.version_update,null,false);
        version = (TextView)view.findViewById(R.id.version);
        content = (TextView)view.findViewById(R.id.content);
        left = (Button)view.findViewById(R.id.left);
        right = (Button)view.findViewById(R.id.right);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            content.setText(Html.fromHtml(versionInfoBean.getDesc(),Html.FROM_HTML_MODE_LEGACY));
        }else{
            content.setText(Html.fromHtml(versionInfoBean.getDesc()));
        }
        content.setMovementMethod(LinkMovementMethod.getInstance());
        version.setText("版本號:"+versionInfoBean.getVersionName());
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        left.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                dialog.dismiss();
            }
        });
        right.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                dialog.dismiss();
                    downloadNewVersionFromServer();

            }
        });
        dialog.setContentView(view);
        dialog.setCancelable(false);
        Window dialogWindow = dialog.getWindow();
        dialogWindow.setGravity(Gravity.CENTER);
        //dialogWindow.setWindowAnimations(R.style.ActionSheetDialogAnimation);
        WindowManager.LayoutParams lp = dialogWindow.getAttributes();
        WindowManager wm = (WindowManager)
                getSystemService(Context.WINDOW_SERVICE);
        lp.width =wm.getDefaultDisplay().getWidth()/10*9;
        dialogWindow.setAttributes(lp);
        dialog.show();
    }

5.啟動service後臺下載
 /**
     * 啟動服務後臺下載
     */
    private void downloadNewVersionFromServer(){
        if(new File(versionInfoBean.getPath()).exists()){
            new File(versionInfoBean.getPath()).delete();
        }
        Toast.makeText(MainActivity.this,"開始下載...",Toast.LENGTH_SHORT).show();
            LoadingService.startUploadImg(this);
    }

6.定義廣播接受者接受下載狀態

宣告變數isLoading表示下載狀態

/**
     * 定義廣播接收者 接受下載狀態
     */
    public class MyReceive extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
           if("android.intent.action.loading_over".equals(action)){
                isLoading = false;
            }else if("android.intent.action.loading".equals(action)){
                isLoading = true;
            }
        }
    }
7.創造service
public class LoadingService extends IntentService {
    private HttpUtils httpUtils;
    NotificationManager nm;
    private String url,path;
    private SharedPreferences sharedPreferences;
    public LoadingService(String name) {
        super(name);
    }
    public LoadingService() {
        super("MyService");

    }


    public static void startUploadImg(Context context)
    {
        Intent intent = new Intent(context, LoadingService.class);
        context.startService(intent);
    }



    public void onCreate() {
        super.onCreate();
        httpUtils = new HttpUtils();
        httpUtils.configCurrentHttpCacheExpiry(0);
        nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        sharedPreferences = getSharedPreferences("data",MODE_PRIVATE);
    }



    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        updateApk();
    }




//開始下載apk  網路請求使用的是xutils框架
    private void updateApk(){
        url = sharedPreferences.getString("url","");
        path = sharedPreferences.getString("path","");

        httpUtils.download(url,
                path , new RequestCallBack<File>() {
                    @Override
                    public void onLoading(final long total, final long current,
                                          boolean isUploading) {
                        createNotification(total,current);
                        sendBroadcast(new Intent().setAction("android.intent.action.loading"));//傳送正在下載的廣播
                        super.onLoading(total, current, isUploading);
                    }

                    @Override
                    public void onSuccess(ResponseInfo<File> arg0) {
                        nm.cancel(R.layout.notification_item);
                        Toast.makeText(LoadingService.this,"下載成功...",Toast.LENGTH_SHORT).show();
                        installApk();//下載成功 開啟安裝介面
                        stopSelf();//結束服務
                        sendBroadcast(new Intent().setAction("android.intent.action.loading_over"));//傳送下載結束的廣播
                    }

                    @Override
                    public void onFailure(HttpException arg0, String arg1) {
                        Toast.makeText(LoadingService.this,"下載失敗...",Toast.LENGTH_SHORT).show();
                        sendBroadcast(new Intent().setAction("android.intent.action.loading_over"));//傳送下載結束的廣播
                        nm.cancel(R.layout.notification_item);
                        stopSelf();
                    }
                });
    }
    /**
     * 安裝下載的新版本
     */
    protected void installApk() {
        Intent intent = new Intent();
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        File file = new File(path);
        Uri uri = Uri.fromFile(file);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setDataAndType(uri, "application/vnd.android.package-archive");
        this.startActivity(intent);
    }
//傳送通知 實時更新通知欄下載進度
    private void createNotification(final long total, final long current){
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
        builder.setSmallIcon(R.mipmap.ic_launcher);//必須要設定這個屬性,否則不顯示
        RemoteViews contentView = new RemoteViews(this.getPackageName(),R.layout.notification_item);
        contentView.setProgressBar(R.id.progress, (int)total, (int)current, false);
        builder.setOngoing(true);//設定左右滑動不能刪除
        Notification notification  = builder.build();
        notification.contentView = contentView;
        nm.notify(R.layout.notification_item,notification);//傳送通知
    }
ok 大功告成 demo地址:點選開啟連結