欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android app 内部在线升级

程序员文章站 2022-03-30 10:19:01
app在线更新是一个比较常见需求,新版本发布时,进入app,会弹出更新提示框,第一时间更新新版本app。在线更新分为以下几个步骤:1.请求api2.检查版本3.下载最新版本apk4.安装apk下载apk如下:// mUpgradeAddress:下载apk的地址,size: apk的大小 private void downloadAPK(String mUpgradeAddress,int size) { try { UR....

app在线更新是一个比较常见需求,新版本发布时,进入app,会弹出更新提示框,第一时间更新新版本app。在线更新分为以下几个步骤: 

1.请求api

2.检查版本

3.下载最新版本apk

4.安装apk

下载apk如下:

// mUpgradeAddress:下载apk的地址,size: apk的大小 
private void downloadAPK(String mUpgradeAddress,int size) {
        try {
       
            URL url = new URL(mUpgradeAddress);
            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
            if (200 != httpURLConnection.getResponseCode()) {
                mHandler.sendEmptyMessage(NETWORK_FAIL);
                return;
            }
            int fileSize = size;
            InputStream inputStream = httpURLConnection.getInputStream();
            BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(mInstallPath));//mInstallPath:存储路径

            byte[] buffer = new byte[1024 * 50];
            int len;
            double readFileLen = 0;
            int lastProgress = 0;

            while (-1 != (len = inputStream.read(buffer))) {
                bufferedOutputStream.write(buffer, 0, len);
                bufferedOutputStream.flush();
                readFileLen += len;
                mDownloadProgress = (int) (readFileLen / fileSize * 100);

                if (mDownloadProgress > lastProgress) {
                    // 这里是显示进度条下载进度,handler更新进度
                    Message msg = new Message();
                    msg.what = PROGRESS;
                    msg.arg1 = mDownloadProgress;
                    mHandler.sendMessage(msg);
                    lastProgress = mDownloadProgress;
                }
            }
            bufferedOutputStream.close();
            inputStream.close();
            httpURLConnection.disconnect();

            mHandler.sendEmptyMessage(INSTALL_APK);//下载完成,调用安装 这里我是通过handler来通知安装 也可以直接调用安装方法
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

安装apk如下:

 private void processApk() {
    // mInstallPath:下载完成保存apk的路径
        try {
            File file = new File(String.valueOf(mInstallPath));
            Intent install = new Intent();
            install.setAction(Intent.ACTION_VIEW);
            install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            install.addCategory(Intent.CATEGORY_DEFAULT);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {//7.0之后需要添加FileProvider
                 String APP_FILE_PROVIDER_AUTH = BuildConfig.APPLICATION_ID + ".fileprovider";
                Uri apkUri = FileProvider.getUriForFile(context, APP_FILE_PROVIDER_AUTH, file);
                install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                install.setDataAndType(apkUri, "application/vnd.android.package-archive");
            } else {
                install.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
            }
            context.startActivity(install);

        }  catch (Exception e) {
            LOG.error("UpgradeClient: install apk,  "+e.getMessage(), e);
        }
    }

到这里就去点击安装自动安装了。

怎么去创建FileProvider?

首先去Manifest.xml注册

 <provider
            android:name="android.support.v4.content.FileProvider"//如果是androidX,请用androidX的FildeProvider
            android:authorities="${APP_FILE_PROVIDER_AUTH}"
            tools:replace="android:authorities"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/filepaths" />
 </provider>

//APP_FILE_PROVIDER_AUTH :这个参数是我在build.gradle里面创建的如下:
 applicationId = System.getenv("APPLICATION_ID") as String ?: "com.xxx.xxx"
 def appFileProviderAuth = applicationId + (".fileprovider")
 manifestPlaceholders = [
                APP_FILE_PROVIDER_AUTH: appFileProviderAuth,
        ]
注:如果不想写这么麻烦的同学可以简化
@xml/filepaths
<?xml version="1.0" encoding="utf-8"?>
<Path>
    <external-path path="" name="download"/>
</Path>

如果想让进度条在手机工具栏里面显示进度条,可以写一个service和前台通知就可以了。

一个菜鸟的记录,如果不明白也可以随时留言。

本文地址:https://blog.csdn.net/why_111/article/details/107211511