Android Studio App开发之网络通信中使用POST方式调用HTTP接口实现应用更新功能(附源码 超详细必看)

news2025/7/18 8:19:21

运行有问题或需要源码请点赞关注收藏后评论区留言~~~

一、POST方式调用HTTP接口

POST方式把接口地址与请求报文分开,允许使用自定义的报文格式,由此扩大了该方式的应用场景。POST请求与GET请求主要有三处编码差异

1:在调用setRequestMethod方法时  请求方式填POST而非GET

2:POST方式务必调用setDoOutput方法并设置true,表示准备让连接执行输出操作

3:连接成功之后,要向连接对象的输出流写入请求报文的字节数据

接下来通过一个实例,演示如何在App开发中发送POST请求来更新应用版本。

此处要搭建HTTP服务器,过程省略不表,读者可自行上网查询

完成服务器搭建之后,通过电脑浏览器访问Web服务的默认首页,可以在命令行查找电脑的无线网址,如果能够正常打开网页,就表示在笔记本电脑上搭建好了HTTP服务器  效果如下

可自行在下拉框中选择要更新的应用

连接真机测试效果更好

 

 

 

 代码如下

Java类

package com.example.chapter14;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.example.chapter14.bean.PackageInfo;
import com.example.chapter14.constant.ApkConstant;
import com.example.chapter14.task.CheckUpdateTask;
import com.example.chapter14.task.req.CheckUpdateReq;
import com.example.chapter14.task.resp.CheckUpdateResp;
import com.google.gson.Gson;

public class HttpPostActivity extends AppCompatActivity implements CheckUpdateTask.OnCheckUpdateListener {
    private static final String TAG = "HttpPostActivity";
    private Spinner sp_app_name; // 应用名称的下拉框
    private ImageView iv_app;
    private TextView tv_app_result;
    private boolean isFirstSelect = true; // 是否首次选择

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_http_post);
        iv_app = findViewById(R.id.iv_app);
        tv_app_result = findViewById(R.id.tv_app_result);
        initAppSpinner(); // 初始化应用名称的下拉框
    }

    // 初始化应用名称的下拉框
    private void initAppSpinner() {
        ArrayAdapter<String> apkNameAdapter = new ArrayAdapter<String>(this,
                R.layout.item_select, ApkConstant.NAME_ARRAY);
        sp_app_name = findViewById(R.id.sp_app_name);
        sp_app_name.setPrompt("请选择要更新的应用");
        sp_app_name.setAdapter(apkNameAdapter);
        sp_app_name.setOnItemSelectedListener(new AppNameSelectedListener());
        sp_app_name.setSelection(0);
    }

    class AppNameSelectedListener implements AdapterView.OnItemSelectedListener {
        public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
            if (isFirstSelect) { // 刚打开页面时不需要执行下载动作
                isFirstSelect = false;
                return;
            }
            queryAppInfo(arg2); // 查询应用的详细信息
        }

        public void onNothingSelected(AdapterView<?> arg0) {}
    }

    // 查询应用的详细信息
    private void queryAppInfo(int pos) {
        iv_app.setImageResource(ApkConstant.ICON_ARRAY[pos]); // 设置图像视图的资源图片
        CheckUpdateReq req = new CheckUpdateReq(); // 创建检查更新的请求对象
        req.package_list.add(new PackageInfo(ApkConstant.PACKAGE_ARRAY[pos]));
        String content = new Gson().toJson(req); // 把检查更新的请求对象转换为json字符串
        CheckUpdateTask task = new CheckUpdateTask(); // 创建一个检查应用更新的异步任务
        task.setCheckUpdateListener(this); // 设置应用更新检查的监听器
        task.execute(content); // 把应用更新检查任务加入到处理队列
    }

    // 在结束应用更新检查时触发
    @Override
    public void finishCheckUpdate(String resp) {
        if (TextUtils.isEmpty(resp)) {
            Toast.makeText(this, "应用检查更新失败", Toast.LENGTH_SHORT).show();
            return;
        }
        // 把JSON串转换为对应结构的实体对象
        CheckUpdateResp checkResp = new Gson().fromJson(resp, CheckUpdateResp.class);
        if (checkResp!=null && checkResp.package_list!=null && checkResp.package_list.size()>0) {
            PackageInfo info = checkResp.package_list.get(0);
            String desc = String.format("应用检查更新结果如下:\n应用名称:%s\n应用包名:%s\n最新版本:%s\n下载地址:%s",
                    info.app_name, info.package_name, info.new_version, info.download_url);
            tv_app_result.setText(desc); // 显示当前选中应用的检查更新结果
        }
    }

}

APK类

package com.example.chapter14.constant;

import com.example.chapter14.R;

public class ApkConstant {
    public static String[] NAME_ARRAY = {
            "爱奇艺", "酷狗音乐", "美图秀秀", "微信", "淘宝", "QQ"
    };
    public static String[] PACKAGE_ARRAY = {
            "com.qiyi.video", "com.kugou.android", "com.mt.mtxx.mtxx",
            "com.tencent.mm", "com.taobao.taobao", "com.tencent.mobileqq"
    };
    public static int[] ICON_ARRAY = {
            R.drawable.icon_aiqiyi, R.drawable.icon_kugou, R.drawable.icon_meitu,
            R.drawable.icon_weixin, R.drawable.icon_taobao, R.drawable.icon_qq
    };
    public static String[] URL_ARRAY = {
            "https://3g.lenovomm.com/w3g/yydownload/com.qiyi.video/60020",
            "https://3g.lenovomm.com/w3g/yydownload/com.kugou.android/60020",
            "https://3g.lenovomm.com/w3g/yydownload/com.mt.mtxx.mtxx/60020",
            "https://3g.lenovomm.com/w3g/yydownload/com.tencent.mm/60020",
            "https://3g.lenovomm.com/w3g/yydownload/com.taobao.taobao/60020",
            "https://3g.lenovomm.com/w3g/yydownload/com.tencent.mobileqq/60020"
    };

}

bean类

package com.example.chapter14.bean;

public class PackageInfo {
    public String app_name; // 应用名称
    public String package_name; // 应用包名
    public String download_url; // 下载地址
    public String new_version; // 新版本号

    public PackageInfo() {
        app_name = "";
        package_name = "";
        download_url = "";
        new_version = "";
    }

    public PackageInfo(String package_name) {
        this.package_name = package_name;
    }

}

XML文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="5dp" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="40dp" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="请选择要更新的应用:"
            android:textColor="@color/black"
            android:textSize="17sp" />

        <Spinner
            android:id="@+id/sp_app_name"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:spinnerMode="dialog" />
    </LinearLayout>

    <ImageView
        android:id="@+id/iv_app"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:scaleType="fitCenter" />

    <TextView
        android:id="@+id/tv_app_result"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="@color/black"
        android:textSize="17sp" />

</LinearLayout>

创作不易 觉得有帮助请点赞关注收藏~~~ 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/8194.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Kafka 消息队列 ( 一 ) 基本概念

0.MQ(message queue) 消息中间件 生活中的问题 : 快递员 给 你 送东西, 你必须 在家等着, (效率低) 可以 把东西 放 指定 的 地方(菜鸟驿站) , 你自己去取 , 指定 的地点(菜鸟驿站) 就是 MQ 消息队列中间件 0.1.开发中的问题 0.1.1.异步问题 0.1.2.业务解耦 0.1.3.流量削…

2. 信息在计算机中存储的格式

目录 一、信息存储&#xff1a; 1. 空间大小定义 2. 不同进制的转换方法 3. 各种数据类型所占字节数 4. 字节顺序 5. 字符串存储 6. 代码的二进制表示 7. 布尔代数运算 8. 逻辑运算 9. 移位运算 二、 整数表示 1. 有符号与无符号表示 1.1 表示范围 1.2 补码编码的…

C语言日记 35 拷贝构造函数

书P132&#xff1a; 拷贝构造函数的作用是 用已存在的对象初始化另一对象&#xff0c;两对象类类型应一样 在这里我们可以看到&#xff0c; 他对被拷贝的对象的要求只有“已存在的对象&#xff0c;两对象类类型一样”&#xff0c;也就是说他这里也没有说我们不能跨区域&…

使用 Spring Cloud Loadbalancer 实现客户端负载均衡

使用 Spring Cloud Loadbalancer 实现客户端负载均衡 作者&#xff1a;Grey 原文地址&#xff1a; 博客园&#xff1a;使用 Spring Cloud Loadbalancer 实现客户端负载均衡 CSDN&#xff1a;使用 Spring Cloud Loadbalancer 实现客户端负载均衡 背景 在Spring Cloud G 版…

为什么 think-cell 图表中的标签显示为白色矩形?

有些标签的背景错误地变成白色&#xff0c;或显示幻灯片背景。当前版本的 PowerPoint 不会出现此问题。 •使用 PowerPoint 2007 打开 .ppt 文件并单击标签内部时&#xff0c;将显示正确的标签背景&#xff0c;但是在保存后重新打开该文件时&#xff0c;会返回不正确…

分布式系统的 38 个知识点

天天说分布式分布式&#xff0c;那么我们是否知道什么是分布式&#xff0c;分布式会遇到什么问题&#xff0c;有哪些理论支撑&#xff0c;有哪些经典的应对方案&#xff0c;业界是如何设计并保证分布式系统的高可用呢&#xff1f; 1. 架构设计 这一节将从一些经典的开源系统架…

5G无线技术基础自学系列 | 物理随机接入信道

素材来源&#xff1a;《5G无线网络优化实践》 一边学习一边整理内容&#xff0c;并与大家分享&#xff0c;侵权即删&#xff0c;谢谢支持&#xff01; 附上汇总贴&#xff1a;5G无线技术基础自学系列 | 汇总_COCOgsta的博客-CSDN博客 PRACH信道用于传输前导Preamble序列。gNB…

逆向-破零64位版本

// 排版有点乱&#xff0c;没有图片直观。 #include <stdio.h> #include <stdlib.h> #include <string.h> int f_14a2(int *va, int vb) { /*14a2: f3 0f 1e fa endbr64 14a6: 55 push %rbp 14a7:…

[附源码]java毕业设计基于Web的美食网站的设计与实现

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【背景渐变】 —— 就算没接触过也能 一遍学会哦

前期回顾 ​回顾 前期 把你喜欢css动画嵌入到浏览器中 —— css动画 项目_0.活在风浪里的博客-CSDN博客常用酷炫动画999合集&#xff0c;代码直接复制可用&#xff0c;总用你想找的&#xff0c;快来抱走吧&#xff0c;三连&#xff0c;停&#xff01;听鹅说&#xff0c;下…

2009年408大题总结

2009年408大题第41题第42题第43题第44题第45题第46题第47题第41题 这个最容易想到的方法就是举反例&#xff0c;但是我们可以分析一下&#xff0c;每一次都取最短的路径&#xff0c;实际上就是贪心策略的应用——每次都是最优&#xff0c;但是最终的结果却一般不是最优&#xf…

第十一节:抽象类和接口【java】

目录 &#x1f947;1. 抽象类 &#x1f4d8;1.1 抽象类概念 &#x1f4d2;1.2 抽象类语法 &#x1f4d7; 1.3 抽象类特性 &#x1f3f9;2. 接口 &#x1f4d9;2.1 接口的概念 &#x1f4d5;2.2 语法规则 &#x1f4d2;2.3 接口使用 &#x1f50e;2.3.1USB接口例子 &a…

【Google Colab】使用手册、教程;使用 Google Colab 免费使用 python 服务器

Colaboratory 是一个 Google 研究项目&#xff0c;旨在帮助传播机器学习培训和研究成果。它是一个 Jupyter 笔记本环境&#xff0c;不需要进行任何设置就可以使用&#xff0c;并且完全在云端运行。Colaboratory 笔记本存储在 Google 云端硬盘中&#xff0c;并且可以共享&#x…

超详细图解kafka生产消费流程

目录&#xff1a; 一条消息在kafka是如何生产的&#xff1f; 一条消息在kafka是如何存储的&#xff1f; 一条消息在kafka是如何消费的&#xff1f; Kafka为什么高性能&#xff1f; Kafka为什么高可用&#xff1f; 一&#xff0e;一条消息在kafka是如何存储的&#xff1f; …

【前端】Vue+Element UI案例:通用后台管理系统-登陆不同用户显示不同菜单、动态添加路由

文章目录目标代码0.动态地显示菜单&#xff1a;store1.动态注册路由2.解决刷新后摆平问题总代码本篇修改的代码文件tab.js参考视频&#xff1a; VUE项目&#xff0c;VUE项目实战&#xff0c;vue后台管理系统&#xff0c;前端面试&#xff0c;前端面试项目案例链接【前端】VueEl…

spring-IOC理论推导P3

1.新建一个项目。名字叫做spring-study 2.导包 <dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.3.23</version></dependency></dependencies&…

solr-7.7.3 搭建

solr-7.7.3 搭建 solr-7.7.3 搭建 文章目录solr-7.7.3 搭建一、前期准备安裝规划(一)资料下载(二)上传文件二、安裝(一)创建新用户(二)安装solr1.solr安装包解压到/opt/module2.将解压文件名修改为solr3.修改配置文件(三)分发文件&#xff08;四&#xff09;开启solr&#xff…

YOLOv5量化调优

目录 一、背景 二、模型调优 2.1 基准选取 2.1.1 官方精度数据 2.1.2 fp32bmodel的精度 2.1.3 int8bmodel精度数据 2.2 多图量化 2.3 预处理对齐&lmdb 2.4 网络图优化 2.4.1 per_channel优化 2.4.2 accuracy_opt优化 2.4.3 conv_group优化 2.4.4 总结 2.5 混…

python中使用xlrd、xlwt操作excel表格详解

最近遇到一个情景&#xff0c;就是定期生成并发送服务器使用情况报表&#xff0c;按照不同维度统计&#xff0c;涉及python对excel的操作&#xff0c;上网搜罗了一番&#xff0c;大多大同小异&#xff0c;而且不太能满足需求&#xff0c;不过经过一番对源码的"研究"&…

移动电源出口美国和欧盟需要做什么?

手机的普遍使用也带动了充电宝的发展&#xff0c;现在是智能的时代&#xff0c;手机现在是我们每个人永远不会忘记带的东西&#xff0c;当然耗电量也是很大的。所以充电宝在这时就有很大的用处了。移动电源是一种集供电和充电功能于一体的便携式充电器&#xff0c;一般由锂离子…