Android 自动更新

Android 自动更新

Android小彩虹2021-07-18 15:51:15230A+A-

一、需求分析

1、查询线上版本号,然后拿本地版本号与之对比。2、若线上版本号比本地版本号大,则下载线上版本号。3、把下载好的版本号安装,并替换当前旧版本

二、权限

根据上面的需求我们可以知道,需要用到的权限应该有网络权限、本地文件写入权限,本地文件读取权限。使用网络权限去获取线上的版本号,然后下载保存到本地,安装的时候再去本地取来。另外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安装权限 

三、步骤

1.先判断8.0以上的需要检测是否有权限,有的直接去检测版本更新,没有去申请

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) {
                            }
                        }
                    }
                }
        );

3、去开启服务下载apk,然后安装

  /**
     * 下载文件: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的坑,就是不做特殊处理下载没有通知显示,那么看代码

 /**
     * 初始化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的坑了,前面以后给出权限解决

 /**
     * 安装软件
     *
     * @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);
    }

欧了,现在应该自动更新没问题可以解决了,如有问题欢迎指正,互相学习

点击这里复制本文地址 以上内容由权冠洲的博客整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!

支持Ctrl+Enter提交

联系我们| 本站介绍| 留言建议 | 交换友链 | 域名展示
本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除

权冠洲的博客 © All Rights Reserved.  Copyright quanguanzhou.top All Rights Reserved
苏公网安备 32030302000848号   苏ICP备20033101号-1

联系我们