Android 自动更新

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

内容简介: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);
    }

复制代码

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


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

查看所有标签

猜你喜欢:

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

The Art of UNIX Programming

The Art of UNIX Programming

Eric S. Raymond / Addison-Wesley / 2003-10-3 / USD 54.99

Writing better software: 30 years of UNIX development wisdom In this book, five years in the making, the author encapsulates three decades of unwritten, hard-won software engineering wisdom. Raymond b......一起来看看 《The Art of UNIX Programming》 这本书的介绍吧!

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具