Android 自動更新

1、需求分析android

一、查詢線上版本號,而後拿本地版本號與之對比。二、若線上版本號比本地版本號大,則下載線上版本號。三、把下載好的版本號安裝,並替換當前舊版本api

2、權限bash

根據上面的需求咱們能夠知道,須要用到的權限應該有網絡權限、本地文件寫入權限,本地文件讀取權限。使用網絡權限去獲取線上的版本號,而後下載保存到本地,安裝的時候再去本地取來。另外8.0上google把未知應用的安裝權限的管理放到了每一個app上,每一個app都有容許安裝未知應用的設置開關,因此這裏也須要權限網絡

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"> <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>---8.0安裝權限 複製代碼

3、步驟app

1.先判斷8.0以上的須要檢測是否有權限,有的直接去檢測版本更新,沒有去申請ide

if (!checkInstall()){
            if (conn) {
                this.checkUpdate(splashView);
            } else {
                Toast.makeText(this, "請檢查網絡~", Toast.LENGTH_LONG).show();
            }
        }
    
     /**
     * 若是想讓應用自動安裝下載的新版本apk,那麼必須打開應用的這個權限,否則是不會自動安裝的
     */
    public boolean checkInstall() {
        boolean haveInstallPermission;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            //先獲取是否有安裝未知來源應用的權限
            haveInstallPermission = getPackageManager().canRequestPackageInstalls();
            if (!haveInstallPermission) {//沒有權限
                android.support.v7.app.AlertDialog alertDialog = new android.support.v7.app.AlertDialog.Builder(this)
                        .setTitle("請開啓未知來源權限")
                        .setMessage("應用須要打開安裝未知來源應用權限,請去設置中開啓權限")
                        .setCancelable(false)
                        .setNegativeButton("取消",
                                new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        dialog.dismiss();
                                        Toast.makeText(WelcomeActivity.this, "您拒絕了權限,應用沒法正常使用!", Toast.LENGTH_SHORT).show();
                                        finish();
                                    }
                                })
                        .setPositiveButton("去設置", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                dialog.dismiss();
                                toInStallPermissionSettingActivity();
                            }
                        }).create();
                alertDialog.show();
                return true;
            }
        }

        return false;
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private void toInStallPermissionSettingActivity() {
        Uri packageURI = Uri.parse("package:" + getPackageName());
        //注意這個是8.0新API
        Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI);
        startActivityForResult(intent, REQUEST_CODE_INSTALL_PERMISSION);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode==RESULT_OK&&requestCode==REQUEST_CODE_INSTALL_PERMISSION){
            if (conn) {
                this.checkUpdate(splashView);
            } else {
                Toast.makeText(this, "請檢查網絡~", Toast.LENGTH_LONG).show();
            }
        }else {
            finish();
            Toast.makeText(WelcomeActivity.this, " 您拒絕了權限,應用沒法正常使用!", Toast.LENGTH_SHORT).show();
        }
    }
複製代碼

2網絡請求檢測更新學習

/**
     * 檢測軟件更新
     */
    public void checkUpdate(final View splashView) {
        // 建立okHttpClient對象
        OkHttpClient mOkHttpClient = new OkHttpClient();
        Request request = new Request.Builder().url(Urls.UPDATEXML).build();//http://ushevapp-10060464.cos.myqcloud.com/version.xml
        mOkHttpClient.newCall(request).enqueue(
                new okhttp3.Callback() {
                    @Override
                    public void onFailure(okhttp3.Call call, IOException e) {
                        Message msg = new Message();
                        msg.what = 0;
                        mmHandler.sendMessage(msg);
                        Log.d("h_bl", "失敗");
                    }

                    @Override
                    public void onResponse(okhttp3.Call call, okhttp3.Response response) throws IOException {
                        InputStream is = null;
                        byte[] buf = new byte[2048];
                        int len = 0;
                        String SDPath = Environment.getExternalStorageDirectory().getAbsolutePath();
                        try {
                            is = response.body().byteStream();
                            ParseXmlService pxs = new ParseXmlService();
                            stringStringHashMap = pxs.parseXml(is);
                            Message msg = new Message();
                            msg.what = 1;
                            mmHandler.sendMessage(msg);
                            Log.d("h_bl", "檢測軟件更新文件下載成功");
                        } catch (Exception e) {
                            Message msg = new Message();
                            msg.what = 0;
                            mmHandler.sendMessage(msg);
                            Log.d("h_bl", "文檢測軟件更新件下載失敗");
                        } finally {
                            try {
                                if (is != null) {
                                    is.close();
                                }
                            } catch (IOException e) {
                            }
                        }
                    }
                }
        );
複製代碼

三、去開啓服務下載apk,而後安裝ui

/**
     * 下載文件:Okhttp
     */
    private void loadFileByOkhttp() {
        initNotification();
        OkHttpClient mOkHttpClient = new OkHttpClient();
        Request request = new Request.Builder()
                .url(url)
//                .addHeader("Accept-Encoding", "identity")
                .build();

        mOkHttpClient.newCall(request).enqueue(
                new Callback() {
                    @Override
                    public void onFailure(okhttp3.Call call, IOException e) {
                        cancelNotification();
                        Log.d("h_bl", "新版本下載失敗");
                    }

                    @Override
                    public void onResponse(okhttp3.Call call, Response response) throws IOException {
                        InputStream is = null;
                        byte[] buf = new byte[2048];
                        int len = 0;
                        FileOutputStream fos = null;
                        try {
                            is = response.body().byteStream();
                            long total = response.body().contentLength();

                            File file = new File(destFileDir, destFileName);
                            fos = new FileOutputStream(file);
                            long sum = 0;
                            int progress = 0;
                            while ((len = is.read(buf)) != -1) {
                                fos.write(buf, 0, len);
                                sum += len;
                                progress = (int) (sum * 1.0f / total * 100);
                                updateNotification(progress);
                            }

                            if (progress == 100) {
                                cancelNotification();
                                installApk(file);

                            }
                            fos.flush();
                            Log.d("h_bl", "apk文件下載成功");
                        } catch (Exception e) {
                            e.printStackTrace();
                        } finally {
                            try {
                                if (is != null) {
                                    is.close();
                                }
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                            try {
                                if (fos != null) {
                                    fos.close();
                                }
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
        );
    }
複製代碼

另外這裏也有8·0的坑,就是不作特殊處理下載沒有通知顯示,那麼看代碼this

/**
     * 初始化Notification通知
     */

    public void initNotification() {
        destFileDir = getTempDirectoryPath();
        notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            builder = new NotificationCompat.Builder(mContext, PUSH_CHANNEL_ID);
            NotificationChannel channel = new NotificationChannel(PUSH_CHANNEL_ID, PUSH_CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
            channel.enableVibration(false);
            channel.setVibrationPattern(new long[]{0});
            channel.setSound(null, null);
            if (notificationManager != null) {
                notificationManager.createNotificationChannel(channel);
            }
            builder.setSmallIcon(R.mipmap.logo)
                    .setContentText("0%")
                    .setContentTitle("住保服務更新")
                    .setChannelId(PUSH_CHANNEL_ID);
        } else {
            builder = new NotificationCompat.Builder(mContext)
                    .setSmallIcon(R.mipmap.logo)
                    .setContentText("0%")
                    .setContentTitle("住保服務更新");
        }
        notificationManager.notify(NOTIFY_ID, builder.build());
    }
複製代碼

最後安裝apk,注意一些細節,更新的包須要和舊包有相同的簽名文件不然會安裝失敗,還有就是8.0的坑了,前面之後給出權限解決google

/**
     * 安裝軟件
     *
     * @param file
     */
    private void installApk(File file) {
        Uri uri = Uri.fromFile(file);
        Intent install = new Intent(Intent.ACTION_VIEW);
        install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        install.setDataAndType(uri, "application/vnd.android.package-archive");
        // 執行意圖進行安裝
        mContext.startActivity(install);
    }

複製代碼

歐了,如今應該自動更新沒問題能夠解決了,若有問題歡迎指正,互相學習

相關文章
相關標籤/搜索