Android——APP更新工具包封装_apk更新工具-程序员宅基地

技术标签: java  android  android studio  Android  

APP内置更新版本

APP热修复,请参考 APP热修复 该章节

简单三步走!!!

第一步复制工具类 UtilApp.java

package com.gsls.appinstall;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;

import androidx.core.content.FileProvider;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class UtilApp {

    /**
     * @param downloadUrl
     * @param savePath
     * @下载APK新版本
     */
    public static void downloadApp(final String downloadUrl, final String savePath) {

        new Thread() {
            public void run() {
                File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + savePath);//记得加扩展名
                file.getParentFile().mkdir();
                try {
                    file.createNewFile();
                    URL url2 = new URL(downloadUrl);
                    HttpURLConnection conn = (HttpURLConnection) url2.openConnection();
                    conn.connect();
                    if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
                        InputStream ips = conn.getInputStream();
                        FileOutputStream fops = new FileOutputStream(file);

                        byte[] buf = new byte[1024];
                        int read = ips.read(buf);
                        while (read != -1) {
                            fops.write(buf, 0, read);
                            fops.flush();
                            read = ips.read(buf);
                        }
                        fops.close();
                        ips.close();
                        conn.disconnect();
                    }
                } catch (Exception e) {
                }
            }
        }.start();

    }

     /**
     * 安装新的Apk
     * @param activity
     * @param apkPath 安装的apk路径
     */
    public static void installNewApk(Activity activity, String apkPath) {
        File apkfile = new File(apkPath);
        if (!apkfile.exists()) {
            return;
        }
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        //兼容android7.0以上版本
        Uri uri = Uri.fromFile(apkfile);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            //通过FileProvider创建一个content类型的Uri
            uri = FileProvider.getUriForFile(activity, "com.zuanuniverse.universe.fileprovider", apkfile);
            // 给目标应用一个临时授权
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        }
        intent.setDataAndType(uri, "application/vnd.android.package-archive");
        activity.startActivity(intent);
    }

}

第二步:使用案列

public class MainActivity extends AppCompatActivity {

    String url = "https://res.wx.qq.com/open/zh_CN/htmledition/res/dev/download/sdk/Gen_Signature_Android3b8804.apk";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //下载 url 上的 apk 并放在 手机根目录中 GT 文件夹下
                UtilApp.downloadApp(url, "GT/最新版APP.apk");
            }
        });

        findViewById(R.id.btn2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //安装 手机根目录中 GT 文件夹下的 最新版APP.apk
                UtilApp.installNewApk(MainActivity.this, "0/**具体app路径**/GT/最新版APP.apk");
            }
        });

    }

}

第三步:添加权限与xml

添加的权限:

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- 写入手机权限 -->
    <uses-permission android:name="android.permission.INTERNET" />  <!-- 网络权限 -->
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />  <!-- 读取手机权限 -->

添加数据共享

<application>
...
<!--数据共享-->
        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="自己包名.fileprovider"
            android:grantUriPermissions="true"
            android:exported="false">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>
...
</<application>

创建xml目录并创建 file_paths.xml.xml 文件

<paths>
    <external-path path="." name="external_storage_root" />
</paths>

总结:简洁明了,非常实用。

本章节源码网址:https://github.com/1079374315/AppInstall

APP热修复,请参考 APP热修复 该章节

点个关注点个赞呗(〃'▽'〃),关注博主最新发布库:GitHub - 1079374315/GT

美帝 框架,让创造变得如此简单!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_39799899/article/details/102470084

智能推荐

Spring入门到精通:第五章 JdbcTemplate:5.JdbcTemplate操作数据库-查询操作_jdbctemplate获取remarks为空-程序员宅基地

文章浏览阅读1.5w次。这一节我们来讲一下查询:(1)查询表有多少条记录;(2)查询某条数据;(3)查询所有记录;一、演示查询(1)在BookDao添加几个查询方法:/**查询表有多少条记录*/int selectCount();/**查询某条数据*/Book findOne(int id);/**查询所有记录*/List<Book> findAll();(2)在BookDaoImpl添加几个查询方法的实现:public int selectCount(.._jdbctemplate获取remarks为空

Ubuntu—root用户权限设置_ubuntu root权限-程序员宅基地

文章浏览阅读2.1w次,点赞16次,收藏67次。Ubuntu—root用户权限设置_ubuntu root权限

EVE-NG 隐藏没有镜像的模板_删除eve-ng中的镜像-程序员宅基地

文章浏览阅读795次。eve-ng 默认情况下,在添加node时,会列出所有的模板,这样用着很不方便。通过以下方式,可以使没有的设备模板不可见。如下图,这样用起来就方便多了。_删除eve-ng中的镜像

windows下如何在命令行里切换到任意目录_win11命令行目录跳转-程序员宅基地

文章浏览阅读4.6k次,点赞2次,收藏10次。切换到C盘中的某个文件夹,比如AppData,可以执行命令cd AppData;但如果想切换到D盘,输入cd d:是不行的;如果我们要切换盘符的目录,正确的用法是在cd 和路径中间 增加一个“/d”,如cd /d d:也可以不用cd指令,直接用输入盘符:,如执行e:可以切换到E盘。..._win11命令行目录跳转

Matlab如何下载安装科研绘图工具Gramm并绘图_matlab gramm包-程序员宅基地

文章浏览阅读2.6k次,点赞3次,收藏15次。Matlab如何下载安装科研绘图工具Gramm并绘图1.Gramm简介2.下载安装3.运行样例1.Gramm简介Gramm是一个强大的绘图工具箱,允许在Matlab中快速创建复杂的,出版质量的数字,并受到R的ggplot2库Hadley Wickham的启发。作为这一灵感的参考,gramm代表Matlab中的图形语法。用作科研绘图Gramm是一个不错的选择。Gramm是Matlab的一个数据可视化工具箱,允许从分组数据轻松灵活地生成发布质量的图。Matlab可以使用高级接口用于复杂数据分析:它通过表支_matlab gramm包

WPF 入门教程ScottPlot使用_wpf scottplot-程序员宅基地

文章浏览阅读9.4k次,点赞4次,收藏18次。ScottPlot是一个免费的开源交互式绘图库,适用于 .NET。它具有适用于 Windows 窗体、WPF、Avalonia 和 Eto 窗体的用户控件,它甚至可以在服务器环境或控制台应用程序中将绘图生成为图像文件。ScottPlot 面向 .NET Standard 2.0,因此它可以在 .NET Framework 和 .NET Core 应用程序中使用。ScottPlot 的 API 模仿Python 的Matplotlib,大多数绘图都可以用一行代码创建(使用可选参数来自定义样式)。交互式_wpf scottplot

随便推点

DNS域名解析服务_dns解析服务-程序员宅基地

文章浏览阅读904次。一、DNS系统1.1.DNS的含义DNS域名系统(Domain Name System缩写DNS,Domain Name被译为域名)是因特网的一项核心服务,它作为可以将域名和IP地址相互映射的一个分布式数据库,能够使人更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。1.1.1.DNS使用的协议及端口号DNS的默认端口为53。 DNS端口分为TCP和UDP。 TCP是用来做区域传送,多用于主从同步。 UDP是用来做DNS解析的。1.2.DNS系统的作用 正向解析:.._dns解析服务

Windows上搭建PHP开发环境_win php继承环境-程序员宅基地

文章浏览阅读1.4w次,点赞7次,收藏68次。Windows上搭建PHP开发环境前言运行环境&安装软件数据库 mysql 安装服务器 nginx 安装PHP 安装redis 配置phpMyAdmin 安装PhpStorm 安装结语前言作为一个不太全面发展的客户端程序员,基本没怎么写过服务器,就是以前闲暇时候写过点php和go,用WAMP或者宝塔搭建过运行环境,这次机缘巧合要同时搞服务器和客户端,因为用到了nginx,本来想继续用宝..._win php继承环境

Error: Failed to download metadata for repo ‘appstream‘: Cannot prepare internal mirrorlist: No URLs_error: failed to download metadata for repo 'appst-程序员宅基地

文章浏览阅读74次。Error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: No URLs_error: failed to download metadata for repo 'appstream': cannot prepare inte

Odoo 16-Spreadsheet使用_odoo spreadsheet-程序员宅基地

文章浏览阅读790次。Odoo 16-Spreadsheet使用_odoo spreadsheet

洛谷千题详解 | P1026 [NOIP2001 提高组] 统计单词个数【C++、Java语言】_洛谷p1026-程序员宅基地

文章浏览阅读826次,点赞9次,收藏9次。P1026 [NOIP2001 提高组] 统计单词个数【C++、Java语言】_洛谷p1026

【FPGA】Robei EDA常见问题解决 (4)——— 包含include文件和quartus综合的问题_quartus综合的文件能用define么-程序员宅基地

文章浏览阅读1.6k次。#悬崖的花,越芬芳越无偿每次用Robei EDA出问题的时候,我都会怀疑一下到底是我脑子傻了还是EDA脑残了;但是每次等我解决了这个问题,我又觉得是我学傻了才会有这种问题。妙啊~————————————正文的分割线——————————————在robei EDA 里添加了.v文件后,进行系统的 综合,robei 自动生成的代码里,是不包含我们平常在Verilog代码里的include格式。·include''sdram_para.v''robei 自动生成的代码不会有这个语句,如果直接拿robe_quartus综合的文件能用define么