Android 自动更新

栏目: IOS · Android · 发布时间: 5年前

内容简介:1、查询线上版本号,然后拿本地版本号与之对比。2、若线上版本号比本地版本号大,则下载线上版本号。3、把下载好的版本号安装,并替换当前旧版本根据上面的需求我们可以知道,需要用到的权限应该有网络权限、本地文件写入权限,本地文件读取权限。使用网络权限去获取线上的版本号,然后下载保存到本地,安装的时候再去本地取来。另外8.0上google把未知应用的安装权限的管理放到了每个app上,每个app都有允许安装未知应用的设置开关,所以这里也需要权限1.先判断8.0以上的需要检测是否有权限,有的直接去检测版本更新,没有去申

一、需求分析

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

复制代码

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


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

《数据结构》算法实现及解析

《数据结构》算法实现及解析

高一凡 / 西安电子科技大学出版社 / 2002-10-1 / 35.0

《数据结构算法实现及解析》配有光盘,光盘中包括书中所有程序及用标准C语言改写的程序。所有程序均在计算机上运行通过。《数据结构算法实现及解析》适用于使用教科书的大中专学生和自学者。书中的基本操作函数也可供从事计算机工程与应用工作的科技人员参考和采用。一起来看看 《《数据结构》算法实现及解析》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具