APP版本升级与服务器交互

2023-10-26

踏入程序媛旅程已经快一年了,学生生涯也即将结束,正式踏入工作岗位。万事开头难,只能多问多记,久病成医,遇到的问题多了自己的技术也会有所提高。博客也一年了,之前一直想写博,然后各种拖延,到现在才开始,希望自己能坚持。
项目中加了一个APP版本升级功能。之前写的版本升级是由第三方蒲公英版本更新来做。这次由于后台并没有给相应接口(比较坑),然后让我这只菜鸟自己去写服务端接口(真是恐慌呀!),经过各种debug,总算over。


目录

IIS

iis是Internet Information Services的缩写,意为互联网信息服务,是由微软公司提供的基于运行Microsoft Windows的互联网基本服务。IIS是一种Web(网页)服务组件,其中包括Web服务器、FTP服务器、NNTP服务器和SMTP服务器,分别用于网页浏览、文件传输、新闻服务和邮件发送等方面,它使得在网络(包括互联网和局域网)上发布信息成了一件很容易的事。

IIS配置

因为只是app的版本升级,需要将apk放在服务器中然后供客户下载,IIS里的MIME里默认是不支持的。如果没有配置MIME时,直接输入网址要下载APK文件时,会提示找不到此文件。这里教你如何配置IIS的MIME设置,使其可以支持APK文件的下载。。所以本文只涉及到.apk和.json。
打开IIS管理器(快捷方式:inetmgr),找到项目的网站
这里写图片描述
双击之后会在右边看到该网站的所有功能配置,我们选择并点击进入“MIME类型”,在右侧选择“添加”
这里写图片描述
之后在弹出的添加窗口里的文件扩展名输入:.apk
在MIME类型输入:application/vnd.android.package-archive
按确定。
这里写图片描述
点击确定之后会在MIME类型中看到.apk;IIS支持.json文件也是同样的步骤
这里写图片描述
这样需要的IIS就配置完成了,在浏览器中就可以访问到自己写的json文件和apk了。

写json文件

由于只是app的版本更新不需要数据库与代码逻辑。在IIS管理器中找到自己项目的网站,右键“浏览”,进入到项目的接口文件中,随便新建一个文件夹,在这里叫“update”,里面放入你的apk,再新建一个以.json为后缀名的文本
这里写图片描述
然后在update.json文本中写json(按照json格式,看bejson能校验通过吗)
内容可以自己随意添加。其中downloadURL的value值是存放的.apk的路径,当然localhost要用IP地址代替“http://x.x.x.:端口号/路径”

代码块

{
"versionName":"1.0",
"versionDes":"更新描述",
"versionCode":"1",
"downloadURL":"http://x.x.x.x:port/uploadeapp/app-release.apk"
}

Android端

访问网络解析json

URL url = new URL(update的路径);
                    //打开url
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                    //请求超时
                    connection.setConnectTimeout(5000);
                    //读取超时
                    connection.setReadTimeout(5000);
                    //获取请求成功响应码
                    if (connection.getResponseCode() == 200) {
                        InputStream is = connection.getInputStream();
                        String json = StreamUtil.streamtoString(is);
                        JSONObject jsonObject = new JSONObject(json);
                        mVersionName = jsonObject.getString("versionName");
                        mVersionDes = jsonObject.getString("versionDes");
                        mVersionCode = jsonObject.getString("versionCode");
                        mDownloadURL = jsonObject.getString("downloadURL");
                        if (Integer.parseInt(mVersionCode) > mVersionsCode) {
                             downloadAPK();

                        } else {
                           //根据需求自己处理

                        }
 if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                final String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + "phoneGuardian.apk";
                pBar = new ProgressDialog(WelcomeActivity.this);
     pBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
                pBar.setCancelable(false);
                pBar.setTitle("正在下载...");
                pBar.setMessage("请稍候...");
                pBar.setProgress(0);
                pBar.show();
                new Thread() {
                    public void run() {
                        try {
                            URL url = new URL(mDownloadURL);
                            HttpURLConnection con = (HttpURLConnection) url.openConnection();
                            con.setReadTimeout(5000);
                            con.setConnectTimeout(5000);
                            con.setRequestProperty("Charset", "UTF-8");
                            con.setRequestMethod("GET");
                            if (con.getResponseCode() == 200) {
                                int length = con.getContentLength();// 获取文件大小
                                InputStream is = con.getInputStream();
                                pBar.setMax(length); // 设置进度条的总长度
                                FileOutputStream fileOutputStream = null;
                                if (is != null) {
                                    //对apk进行保存
                                    result = new File(path);
                                    if (!result.exists()) {
                                        result.createNewFile();
                                    }
                                    fileOutputStream = new FileOutputStream(result);
                                    byte[] buf = new byte[1024];
                                    int ch;
                                    int process = 0;
                                    while ((ch = is.read(buf)) != -1) {
                                        fileOutputStream.write(buf, 0, ch);
                                        process += ch;
                                        pBar.setProgress(process); // 实时更新进度了
                                    }
                                }
                                if (fileOutputStream != null) {
                                    fileOutputStream.flush();
                                    fileOutputStream.close();
                                }
                                //apk下载完成,安装apk
                                Toast.makeText(WelcomeActivity.this, "下载成功", Toast.LENGTH_SHORT).show();
                                pBar.dismiss();
                                File file = result;//apk路径
                                installapk(file);

                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }

                }.start();

遇到的bug

动态权限

在Android 6.0 中,有些权限属于 Protected Permission,这类权限只在 AndroidManifest.xml中声明是无法真正获取到的,还需要再代码中动态获取,使权限许可弹出对话框,用户点击“允许”后,方可真正获得此权限。
我在向SD卡总存入apk时,出现bug。之前知道Android6.0需要动态添加权限,但是项目没有遇到问题也就没在意。

java.io.FileNotFoundException: /storage/emulated/0/phoneGuardian.apk (Permission deny)

解决方法
动态添加权限

int permission = ActivityCompat.chacekSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission!=PackageManager.PERMISSION_GRANTED){
     //没有权限              ActivityCompat.requestPermissions(RuntimeActivity.this,PERMISSIONS_STORAGE,REQUEST_EXTERNAL_STROAGE);
}

FileUriExposedException

下载玩apk进行Intent安装apk,出现bug,catche之后

android.os.FileUriExposedException: file:///storage/emulated/0/xx

因为我也是第一次遇到,所以搜了一下,这里不说具体的解决方法了,看连接
解决FileUriExposedException方法

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

APP版本升级与服务器交互 的相关文章

随机推荐

  • kettle进阶之database join

    前言 这并不是一篇入门教学 且不是一篇高阶教学 仅仅针对kettle的database join 那么问题来了 kettle的database join是什么 简而言之 不同库之间sql语句传值 个人自定义 如有不当 请海涵 案例1 一条数
  • SQL Server 集合处理

    UNION ALL 返回两个结果集中所有的行 返回结果集中会存在重复行 UNION 返回两个结果集中去重的行 返回结果集中无重复行 INTERSECT 返回两个结果集都有的行 返回结果集中无重复行 EXCEPT 返回第一个结果集中有而第二个
  • vuex与生命周期的关系

    vue与生命周期的关系 问题呈现 获取到数据同时保存到vuex中 2 计算属性获取vuex中的值 3 循环输出 4 出现错误 问题解析 如果单独输出item questionSimpleInfo是可以输出整个对象的 但是输出其中某一个字段的
  • 论文阅读-Thinking in Frequency: Face Forgery Detection by Mining Frequency-aware Clues(F3Net基于频率感知线索的人脸)

    一 论文信息 题目 Thinking in Frequency Face Forgery Detection by Mining Frequency aware Clues 基于频率感知线索的人脸伪造检测 作者团队 会议 ECCV 2020
  • Markdown矩阵及公式语法编辑

    Markdown矩阵及公式语法编辑 详见链接 https cloud tencent com developer article 1402840
  • 9. xaml ComboBox控件

    1 运行图像 2 运行源码 a Xaml源码
  • C++中虚函数、虚指针和虚表详解

    关于虚函数的背景知识 用virtual关键字申明的函数叫做虚函数 虚函数肯定是类的成员函数 存在虚函数的类都有一个一维的虚函数表叫做虚表 每一个类的对象都有一个指向虚表开始的虚指针 虚表是和类对应的 虚表指针是和对象对应的 多态性是一个接口
  • Windows CMD 输出文本到文件,不加换行符

    gt test txt set p Hello
  • 共筑安全创新生态,持安科技加入麒麟软件安全生态联盟

    近日 麒麟软件安全生态联盟第二季度工作会议成功举行 零信任办公安全领域明星企业持安科技受邀参会 并参与授牌环节成为麒麟软件安全生态联盟会员单位 麒麟软件安全生态联盟授牌仪式 会上 联盟成员单位围绕操作系统安全事件与漏洞发展趋势 行业应用对操
  • Beego v2.0 编译后无法运行问题

    问题 beego版本 v2 0 1 通过bee pack be GOOS linux 打包后运行可执行程序报错 如下 panic err go command required not found exec go executable fi
  • Vue+Element-ui Table 列求和

    Vue Element ui Table 列求和 Vue代码 求和getSummaries 效果图 Vue代码
  • [GameFramework分析] Log(日志)

    文章目录 使用 分析 Unity脚本 Log LogScriptingDefineSymbols ScriptingDefineSymbols DefaultLogHelper 框架类 GameFrameworkLogLevel GameF
  • graylog日志分析管理系统入门教程

    日志分析系统可以实时收集 分析 监控日志并报警 当然也可以非实时的分析日志 splunk是功能强大且用起来最省心的 但是要收费 免费版有每天500M的限制 超过500M的日志就没法处理了 ELK系统是最常见的 缺点是配置麻烦一些 比较重量级
  • MySQL之InnoDB引擎(一)

    1 InnoDB介绍 InnoDB是一个通用的存储引擎 同时具备高可靠性与高性能的特性 除非用户指定存储引擎的类型 否则其作为MySQL Server的默认存储引擎 使用InnoDB存储引擎的优势包括如下几点 DML操作符合ACID模型 使
  • 编码技巧——事务提交后执行

    日常开发中 一些诸如 先读后写 先写A再写B 先写A再执行B 的场景 一般都会用到事务 这里的事务指的是本地事务 如果涉及RPC 一般我们通过异步补偿来保证最终一致性 本篇例举2个使用事务 先写A再执行B 的场景 1 订单场景 1 处理支付
  • MeshTextPro 自动换行和自动缩放问题

    如果启用了autosize MeshTextPro会优先显示完一个单词之后才会进行换行 当此时如果一个单词过于场的话 MeshTextPro会对其进行缩放 直至当前行可以显示完整单词之后 在进行换行处理 如果需要自动缩放 但是又想其填满一行
  • 一文读懂元宇宙--元宇宙含义

    元宇宙是 虚实融合的世界 包含模拟现实的虚拟世界 创新的虚拟世界 现实世界 也是元宇宙的一部分 虚拟和现实世界的融合 将高于 超越单一的虚拟或者现实世界 虚实融合的世界 图片来源于德勤 元宇宙的四层含义 图片来源于德勤 1 1 模拟现实的虚
  • 神经网络(三)—— 神经元多输出

    本系列为慕课网 深度学习之神经网络 CNN RNN GAN 算法原理 实战 视频笔记 希望自己能通过分享笔记的形式更好的掌握该部分内容 往期回顾 神经网络 一 机器学习 深度学习简介 神经网络 二 神经元 Logistic回归模型 多分类的
  • 优化算法 - RMSProp算法

    文章目录 RMSProp算法 1 算法 2 从零开始实现 3 简洁实现 4 小结 RMSProp算法 1 算法 import math import torch from d2l import torch as d2l d2l set fi
  • APP版本升级与服务器交互

    踏入程序媛旅程已经快一年了 学生生涯也即将结束 正式踏入工作岗位 万事开头难 只能多问多记 久病成医 遇到的问题多了自己的技术也会有所提高 博客也一年了 之前一直想写博 然后各种拖延 到现在才开始 希望自己能坚持 项目中加了一个APP版本升