Android开发版本更新和强制更新效果

news2024/9/29 7:22:37
Android开发版本更新和强制更新效果

版本更新基本每个app都有,这里加多个强制更新效果

一、思路:

用okhttp下载接口返回的apk下载地址,这样有进度条

二、效果图:

在这里插入图片描述在这里插入图片描述

Android开发教程实战案例源码分享-版本更新和强制更新效果

三、关键代码:
// 联系:893151960
public class UpdateActivity extends AppCompatActivity {
    private Context mContext;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_update);
        mContext = this;
        // 关键注意点:DownloadUtil中的installApp中的“com.cong.myupdateappdemo.FileProvider”要和清单中的android:authorities="com.cong.myupdateappdemo.FileProvider"一模一样
        // 这里换成你要下载的apk链接
        String apkUrl = "https://xxx.oss-cn-hangzhou.aliyuncs.com/xxx.apk";
        String updateMsg = "修复已知bug,提高用户体验";
        findViewById(R.id.btn_update).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                updateLayoutDialog(mContext, updateMsg,false, new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        requestPermission(mContext, new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                final Dialog dialog = forceUploadDialog(mContext);
                                ProgressBar pb = (ProgressBar)(dialog.getWindow()).findViewById(R.id.pr_download_value);
                                DownloadUtil.INSTANCE.versionUpdate((Activity) mContext, apkUrl, new Function1<Integer, Unit>() {
                                    @Override
                                    public Unit invoke(Integer integer) {
                                        if (integer == -1 || integer == 100) dialog.dismiss();
                                        if (integer > -1) pb.setProgress(integer);
                                        return null;
                                    }
                                });
                            }
                        }, checkSDK33(mContext) ? new String[]{
                                Manifest.permission.READ_MEDIA_IMAGES
                        } : new String[]{
                                Manifest.permission.READ_EXTERNAL_STORAGE,
                                Manifest.permission.WRITE_EXTERNAL_STORAGE
                        });
                    }
                });
            }
        });

        findViewById(R.id.btn_update_force).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                updateLayoutDialog(mContext, updateMsg,true, new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        requestPermission(mContext, new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                final Dialog dialog = forceUploadDialog(mContext);
                                ProgressBar pb = (ProgressBar)(dialog.getWindow()).findViewById(R.id.pr_download_value);
                                DownloadUtil.INSTANCE.versionUpdate((Activity) mContext, apkUrl, new Function1<Integer, Unit>() {
                                    @Override
                                    public Unit invoke(Integer integer) {
                                        if (integer == -1 || integer == 100) dialog.dismiss();
                                        if (integer > -1) pb.setProgress(integer);
                                        return null;
                                    }
                                });
                            }
                        },  checkSDK33(mContext) ? new String[]{
                                Manifest.permission.READ_MEDIA_IMAGES
                        } : new String[]{
                                Manifest.permission.READ_EXTERNAL_STORAGE,
                                Manifest.permission.WRITE_EXTERNAL_STORAGE
                        });
                    }
                });
            }
        });
    }



    public static boolean checkSDK33(Context context) {
        ApplicationInfo applicationInfo = context.getApplicationInfo();
        return Build.VERSION.SDK_INT >= 33
                && applicationInfo != null
                && applicationInfo.targetSdkVersion >= 33;
    }

    public static void requestPermission(final Context context, final View.OnClickListener successListener, String... permissions) {
        if (PermissionCheckUtil.checkPermissions(context,permissions)){
            if (null != successListener) {
                successListener.onClick(null);
            }
        } else {
            PermissionAppUtils.INSTANCE.requestPermission(context, permissions, new Consumer<Boolean>() {
                @Override
                public void accept(Boolean aBoolean) throws Throwable {
                    if (aBoolean){
                        if (null != successListener) {
                            successListener.onClick(null);
                        }
                    }
                }
            });
        }

    }

    public static AlertDialog forceUploadDialog(final Context context) {
        final AlertDialog dialog = getAlertDialog(context);
        dialog.show();
        Window window = dialog.getWindow();
        window.setGravity(Gravity.CENTER);
        window.setContentView(R.layout.dialog_force_upload_progress);
        View view = window.findViewById(R.id.cl_download_app);
        return dialog;

    }


    public void updateLayoutDialog(Context context, String msg,boolean isForce, final View.OnClickListener listener) {
        final AlertDialog dialog = getAlertDialog(context);
        dialog.show();

        Window window = dialog.getWindow();
        window.setGravity(Gravity.CENTER);
        window.setContentView(R.layout.dialog_update1);
        TextView tvMsg = (TextView) window.findViewById(R.id.tv_message);
        if (tvMsg != null) {
            tvMsg.setText(msg);
        }
        if (isForce){
            window.findViewById(R.id.btn_cancel).setVisibility(View.GONE);
        }
        window.findViewById(R.id.btn_cancel).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
            }
        });
        window.findViewById(R.id.btn_ok).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
                if (listener != null) {
                    listener.onClick(v);
                }
            }
        });
    }

    public static AlertDialog getAlertDialog(Context context) {
        return new AlertDialog.Builder(context, R.style.mydialog).setCancelable(false).create();
    }
}
四、项目demo源码结构图

在这里插入图片描述
有问题或者需要完整源码的私信我

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

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

相关文章

建筑师设计师必备的14个AI工具

从制作复杂的设计到可视化突破性的建筑创新&#xff0c;建筑领域一直与技术紧密交织。随着我们深入数字时代&#xff0c;建筑师和设计师利用尖端人工智能 (AI) 工具的力量来革新他们的工艺也就不足为奇了。但是&#xff0c;随着市场上 AI 工具的大量出现&#xff0c;哪些工具真…

Pymsql 插入数据时报错 Unkown column xxxx in field list

如图 从文字来看&#xff0c;它是说我们表里没有“247dxxxxxxx”这个字段&#xff0c;但问题是我建表的时候本来就没建这个字段&#xff0c;这一串字符是我要插入到“id”这个字段里的内容&#xff0c;它怎么就把它当成字段了呢&#xff1f; 后来发现是在传入参数的时候&#…

Java 发布jar包到maven中央仓库(2024年9月保姆级教程)

文章目录 前言一、账号准备1. 注册登录账号2. 新建命名空间3. 验证命名空间4. 生成令牌5. 为 maven 设置令牌二、GPG准备1. 下载GPG2. 发布证书2.1 新建证书2.2 发布证书到服务器2.3 验证发布三、发布jar包到中央仓库1. 编辑项目pom文件2. 打包上传3. 发布jar包4. 搜索我们的ja…

分片上传和断点续传

今天介绍两个概念&#xff1a; 1、分片上传 分片上传&#xff0c;就是将所要上传的文件&#xff0c;按照一定的大小&#xff0c;将整个文件分隔成多个数据块来进行分别上传&#xff0c;上传完之后再由服务端对所有上传的文件进行汇总整合成原始的文件。 2、断点续传 断点续…

C语言课程设计题目三:图书管理系统设计

题目三&#xff1a;图书管理系统设计 图书管理信息包括&#xff1a;图书名称、图书编号、单价、作者、存在状态、借书人姓名、性别、学号等。 主要功能&#xff1a; 新进图书基本信息的输入。图书基本信息的查询。对撤销图书信息的删除。为借书人办理注册。办理借书手续。办理…

数据流处理技术与Flink框架

一数据流 数据流定义&#xff1a; 数据流&#xff08;Data Stream&#xff09;是指数据以连续不断的方式到达和处理的序列。在现实世界中&#xff0c;许多数据来源都是以流的形式存在&#xff0c;比如&#xff1a; 1. 用户行为&#xff1a;用户在网站上的点击流、移动应用中…

微软 Win11 RP 226x1.4247(KB5043145)预览版发布!

系统之家于9月25日发出最新报道&#xff0c;微软面向Release Preview频道的用户发布了Win11的KB5043145更新。系统更新后版本号提升为22621.4247和22631.4247。此次更新新增多项功能&#xff0c;例如用户播放媒体时&#xff0c;媒体控件会显示在锁屏中央的下部。以下跟随小编看…

LeetCode2207解题思路

题目描述 字符串中最多数目的子序列 解题思路&#xff1a; 题目要求我们找到在 text 中 找到最多可组成 pattern 的字符串个数&#xff0c;并且允许在 text 的任意位置插入 pattern 中一个字符&#xff0c;也就是说我们只需要考虑 text 中的 pattern 含有的字符即可。例如示例…

【React】组件基础使用

1. react组件 在react中&#xff0c;组件就是首字母大写的函数&#xff0c;内部存放了组件的逻辑、UI&#xff0c;渲染组件只需要把组件当成标签书写。 使用组件有两种方式&#xff1a;自闭和 、成对标签 function App() {// 定义组件function Component() {return <div&…

从入门到入土:计算机视觉CV学习路线图

在当今这个被数据和图像淹没的世界&#xff0c;计算机视觉&#xff08;CV&#xff09;正如一位聪明绝顶的魔术师&#xff0c;能够从无数的图像中提取出有意义的信息。对于那些初入这个领域的新人&#xff0c;学习计算机视觉既是一场冒险&#xff0c;也是一场盛宴。让我作为一位…

安科瑞诚邀您参加2024年CDCE国际数据中心及云计算展

展会邀请 安科瑞&#xff08;Acrel&#xff09;诚挚邀请您和您的公司代表参观我们在2024年CDCE国际数据中心及云计算展上的展位。 安科瑞&#xff08;Acrel&#xff09;是一家集研发、生产、销售和服务于一体的企业&#xff0c;成立于2003年并于2012年在创业板上市&#xff0…

探索机器人快换盘技术的未来之路:智能化与协作的革新

在当今快速发展的科技时代&#xff0c;机器人已成为众多领域不可或缺的得力助手。其中&#xff0c;机器人快换盘技术作为提升机器人灵活性和应用广度的重要技术&#xff0c;正经历着前所未有的变革与创新。下面请随我们一起深入探讨这一技术的未来发展趋势。 一、人工智能&…

建投数据获得安防工程企业设计施工维护能力证书(壹级)

近日&#xff0c;经中国安全防范产品行业协会审核&#xff0c;建投数据顺利获得安防工程企业设计施工维护能力证书&#xff08;壹级&#xff09;。 安防工程企业设计施工维护资质是对企业安防工程设计、施工、维护等领域专业能力的综合认证&#xff0c;是衡量企业规模、工程业绩…

阿里云百炼SFT微调实践

1. 场景识别 用户进行SFT前需要对应用场景进行识别和分析&#xff0c;一般进行模型微调的诉求是希望提升对应业务场景的能力&#xff0c;用户需要明确哪些能力是需要进行重点提升的。 场景划分上来讲&#xff0c;以垂类场景进行划分可分为教育、医疗、金融、法律、电商、旅游、…

IP地址的打卡路径是什么?

众多周知&#xff0c;IP地址使我们浏览网站的“必需品”&#xff0c;他会在我们进行网络活动时起到通关文牒一般的作用。那么&#xff0c;放我们进行网络活动时&#xff0c;我们的“通关文牒”上面会在哪些地点留下痕迹&#xff0c;IP地址的流转路径是什么&#xff1f; 第一关…

2024国庆节有哪些必囤的好物产品?一文了解那些入手不亏的国庆好物

国庆假期即将来临。对于追求品质生活的朋友们来说&#xff0c;这无疑是一个不容错过的购物机会。那么&#xff0c;在这个国庆&#xff0c;哪些好物值得你重点关注呢&#xff1f;我特地整理了一份推荐清单&#xff0c;这些产品不仅经过我的亲身体验&#xff0c;更以其卓越的实用…

建投数据自主研发相关系统获得欧拉操作系统及华为鲲鹏技术认证书

近日&#xff0c;经欧拉生态创新中心和华为技术有限公司测评&#xff0c;建投数据自主研发的投资项目管理系统、全面风险管理信息系统、商业不动产业务系统&#xff0c;完成了基于欧拉操作系统openEuler 22.03、华为鲲鹏Kunpeng 920&#xff08;Taisha 200&#xff09;的兼容性…

快速创建第一个Spring Boot 项目

一、介绍 Spring Boot 是一个开源的 Java 基础框架&#xff0c;它基于 Spring 框架&#xff0c;用于创建独立、生产级别的基于 Spring 的应用程序&#xff0c;你可以“跑起来”&#xff08;run&#xff09;你的 Spring 应用程序。Spring Boot 让基于 Spring 的应用开发变得更容…

Spring Boot 3.x 配置 Spring Doc以及导入postman带图详解

一、pom.xml配置 <!-- API⽂档⽣成&#xff0c;基于swagger3 --><dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId><version>2.0.2</version></dependency>…

【简单介绍】DevOps是什么?

由于 DevOps 方法的广泛采用以及由此产生的快速产品交付和部署&#xff0c;许多部门已采用更敏捷的方法来开发生命周期。在满足市场速度和规模要求的同时&#xff0c;设计安全的软件一直是现代 IT 公司共同面临的问题。结果&#xff0c;超过 52% 的组织因为担心上市速度落后而放…