android 下载应用 通知栏显示进度 下完之后点击安装 (很实用)

2023-05-16

先看效果图: 这是本人的习惯,先上图显示效果,看是否是想要的,再看代码。有图有真相大笑





代码:



Main:


package com.gem.hsx.appupdate;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class Main extends Activity {

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		Button btnok=(Button) findViewById(R.id.btnok);
		btnok.setOnClickListener(new BtnokOnClickListener());
	}

	private class BtnokOnClickListener implements OnClickListener 
	{

		@Override
		public void onClick(View v) {
			Intent updateIntent =new Intent(Main.this, UpdateService.class);
			updateIntent.putExtra("titleId",R.string.app_name);
			startService(updateIntent);

		}
	}
}


UpdateService:


package com.gem.hsx.appupdate;

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

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;

public class UpdateService extends Service{
	//标题
	private int titleId = 0;
	private final static int DOWNLOAD_COMPLETE = 0;
	private final static int DOWNLOAD_FAIL = 1; 
	//文件存储
	private File updateDir = null;
	private File updateFile = null;
	 
	//通知栏
	private NotificationManager updateNotificationManager = null;
	private Notification updateNotification = null;
	//通知栏跳转Intent
	private Intent updateIntent = null;
	private PendingIntent updatePendingIntent = null;
	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void onCreate() {
		
		super.onCreate();
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		//获取传值
	    titleId = intent.getIntExtra("titleId",0);
	    //创建文件
	    if(android.os.Environment.MEDIA_MOUNTED.equals(android.os.Environment.getExternalStorageState())){
	        updateDir = new File(Environment.getExternalStorageDirectory(),"app/download/");
	        updateFile = new File(updateDir.getPath(),getResources().getString(titleId)+".apk");
	    }
	 
	    this.updateNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
	    this.updateNotification = new Notification();
	 
	    //设置下载过程中,点击通知栏,回到主界面
	    updateIntent = new Intent(this, Main.class);
	    updatePendingIntent = PendingIntent.getActivity(this,0,updateIntent,0);
	    //设置通知栏显示内容
	    updateNotification.icon = R.drawable.ic_launcher;
	    updateNotification.tickerText = "开始下载";
	    updateNotification.setLatestEventInfo(this,"上海地铁","0%",updatePendingIntent);
	    //发出通知
	    updateNotificationManager.notify(0,updateNotification);
	 
	    //开启一个新的线程下载,如果使用Service同步下载,会导致ANR问题,Service本身也会阻塞
	    new Thread(new updateRunnable()).start();//这个是下载的重点,是下载的过程
	     
	    return super.onStartCommand(intent, flags, startId);
	}
	private Handler updateHandler = new  Handler(){
	    @Override
	    public void handleMessage(Message msg) {
	    	 switch(msg.what){
	            case DOWNLOAD_COMPLETE:
	            	updateNotification.flags|=updateNotification.FLAG_AUTO_CANCEL;
	                //点击安装PendingIntent
	                Uri uri = Uri.fromFile(updateFile);
	                Intent installIntent = new Intent(Intent.ACTION_VIEW);
	                installIntent.setDataAndType(uri, "application/vnd.android.package-archive");
	                updatePendingIntent = PendingIntent.getActivity(UpdateService.this, 0, installIntent, 0);
	                 
	                updateNotification.defaults = Notification.DEFAULT_SOUND;//铃声提醒 
	                updateNotification.setLatestEventInfo(UpdateService.this, "上海地铁", "下载完成,点击安装。", updatePendingIntent);
	                updateNotificationManager.notify(0, updateNotification);
	                 
	                //停止服务
	                stopService(updateIntent);
	            case DOWNLOAD_FAIL:
	                //下载失败
	                updateNotification.setLatestEventInfo(UpdateService.this, "上海地铁", "下载完成,点击安装。", updatePendingIntent);
	                updateNotificationManager.notify(0, updateNotification);
	            default:
	                stopService(updateIntent);
	        }  
	    }
	};
	
	
	class updateRunnable implements Runnable {
        Message message = updateHandler.obtainMessage();
        public void run() {
            message.what = DOWNLOAD_COMPLETE;
            try{
                //增加权限<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">;
                if(!updateDir.exists()){
                    updateDir.mkdirs();
                }
                if(!updateFile.exists()){
                    updateFile.createNewFile();
                }
                //下载函数,以QQ为例子
                //增加权限<uses-permission android:name="android.permission.INTERNET">;
                long downloadSize = downloadUpdateFile("http://softfile.3g.qq.com:8080/msoft/179/1105/10753/MobileQQ1.0(Android)_Build0198.apk",updateFile);
                if(downloadSize>0){
                    //下载成功
                    updateHandler.sendMessage(message);
                }
            }catch(Exception ex){
                ex.printStackTrace();
                message.what = DOWNLOAD_FAIL;
                //下载失败
                updateHandler.sendMessage(message);
            }
        }
    }
	
	
	
	public long downloadUpdateFile(String downloadUrl, File saveFile) throws Exception {
        //这样的下载代码很多,我就不做过多的说明
        int downloadCount = 0;
        int currentSize = 0;
        long totalSize = 0;
        int updateTotalSize = 0;
         
        HttpURLConnection httpConnection = null;
        InputStream is = null;
        FileOutputStream fos = null;
         
        try {
            URL url = new URL(downloadUrl);
            httpConnection = (HttpURLConnection)url.openConnection();
            httpConnection.setRequestProperty("User-Agent", "PacificHttpClient");
            if(currentSize > 0) {
                httpConnection.setRequestProperty("RANGE", "bytes=" + currentSize + "-");
            }
            httpConnection.setConnectTimeout(10000);
            httpConnection.setReadTimeout(20000);
            updateTotalSize = httpConnection.getContentLength();
            if (httpConnection.getResponseCode() == 404) {
                throw new Exception("fail!");
            }
            is = httpConnection.getInputStream();                   
            fos = new FileOutputStream(saveFile, false);
            byte buffer[] = new byte[4096];
            int readsize = 0;
            while((readsize = is.read(buffer)) > 0){
                fos.write(buffer, 0, readsize);
                totalSize += readsize;
                //为了防止频繁的通知导致应用吃紧,百分比增加10才通知一次
                if((downloadCount == 0)||(int) (totalSize*100/updateTotalSize)-10>downloadCount){ 
                    downloadCount += 10;
                    updateNotification.setLatestEventInfo(UpdateService.this, "正在下载", (int)totalSize*100/updateTotalSize+"%", updatePendingIntent);
                    updateNotificationManager.notify(0, updateNotification);
                }                        
            }
        } finally {
            if(httpConnection != null) {
                httpConnection.disconnect();
            }
            if(is != null) {
                is.close();
            }
            if(fos != null) {
                fos.close();
            }
        }
        return totalSize;
    }
		
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.gem.hsx.appupdate"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="15" />

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".Main"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name="UpdateService"
            android:label="@string/app_name" >
        </service>
    </application>

</manifest>





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

android 下载应用 通知栏显示进度 下完之后点击安装 (很实用) 的相关文章

  • Mysql数据库报错:Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DY

    1 问题描述 xff1a Row size too large gt 8126 Changing some columns to TEXT or BLOB or using ROW FORMAT 61 DYNAMIC or ROW FORM
  • AMD IOMMU与Linux (2) -- IVRS及AMD IOMMU硬件初始化

    介绍AMD IOMMU driver基于IVRS的硬件初始化情况 1 I O Virtualization ACPI table 2 drivers iommu amd init c 1 I O Virtualization ACPI ta
  • AMD IOMMU与Linux (3) -- DMA

    Linux中DMA会使用硬件IOMMU如AMD IOMMU INTEL VT D xff0c 也会使用软件的SWIOTLB 这篇梳理一下LINUX内核在有AMD IOMMU的情况下 xff0c 是如何做DMA的 xff0c 内容包括如下 1
  • AMD IOMMU与Linux (4) -- Domain, Group, Device

    1 domain的本质是一个页表 xff0c 1对1的关系 2 IOMMU DOMAIN UNMANAGED vs IOMMU DOMAIN DMA a IOMMU DOMAIN UNMANAGED DMA mappings managed
  • 第三篇:知其然,知其所以然-USB音频设备的开发过程

    最近 xff0c 有朋友正好在开发一个USB音频设备 xff0c 所以询问我一些USB音频设备开发方面的技术细节问题 xff1b 也和音响发烧友聊到USB音频设备的实现方式与其优缺点 xff1b 后来 xff0c 也和人谈到实现一个USB音
  • 第七篇:风起于青萍之末-电源管理请求案例分析(下)

    第五篇 风起于青萍之末 电源管理请求案例分析 上 http blog csdn net u013140088 article details 18180249 第六篇 风起于青萍之末 电源管理请求案例分析 中 http blog csdn
  • 回溯算法(BackTracking)--八皇后问题

    0 xff09 回溯算法 xff1a 回溯算法也算是遍历算法的一种 xff0c 回溯算法是对Brute Force算法的一种改进算法 xff0c 一个典型的应用是走迷宫问题 xff0c 当我们走一个迷宫时 xff0c 如果无路可走了 xff
  • 第十九篇:USB Audio/Video Class设备协议

    转发请注明出处 随着项目的不断进行 我想在网上查找了一下USB Audio Video的最新资料 看看有没有业内人士的更新 由于我们的项目一直在技术的最前延 而且这个USB IF官方发布的协议 也非常非常新 结果找了半天 都是我这篇文章的转
  • 第三十二篇:Windbg中USB2.0调试环境的搭建

    2011年的时候 xff0c 为了开发USB Mass storage UASP USB attached SCSI Protocol 的设备驱动程序 xff0c 从米国买了两个USB2 0的调试小设备 xff08 如下图 xff0c 每个
  • 理解SerDes 之一

    理解SerDes FPGA发展到今天 xff0c SerDes Serializer Deserializer 基本上是标配了 从PCI到PCI Express 从ATA到SATA xff0c 从并行ADC接口到JESD204 从RIO到S
  • 理解SerDes 之二

    理解SerDes 之二 2012 11 11 21 17 12 转载 标签 xff1a dfe serdes it 2 3 接收端均衡器 Rx Equalizer 2 3 1 线形均衡器 Linear Equalizer 接收端均衡器的目标
  • USB3.0的物理层测试探讨

    USB简介 USB Universal Serial Bus 即通用串行总线 xff0c 用于把键盘 鼠标 打印机 扫描仪 数码相机 MP3 U盘等外围设备连接到计算机 xff0c 它使计算机与周边设备的接口标准化 在USB1 1版本中支持
  • ARM SoC漫谈

    作者 xff1a 重走此间路 链接 xff1a https zhuanlan zhihu com p 24878742 来源 xff1a 知乎 著作权归作者所有 商业转载请联系作者获得授权 xff0c 非商业转载请注明出处 芯片厂商向客户介
  • linux下实现生产者消费者问题

    生产者 xff08 producer xff09 和消费者 xff08 consumer xff09 问题是并发处理中最常见的一类问题 xff0c 是一个多线程同步问题的经典案例 可以这样描述这个问题 xff0c 有一个或者多个生产者产生某
  • 解决Ubuntu下每隔几分钟自动锁屏,需要重新输入密码的问题

    看到这篇文章 xff0c 很实用 xff0c mark xff01 http www cnblogs com lanxuezaipiao p 3617436 html
  • Android NFC详解

    1 NFC概览 NFC xff0c 全称是Near Field Communication xff0c 中为近场通信 xff0c 也叫做近距离无线通信技术 使用了NFC技术的设备 xff08 例如移动电话 xff09 可以在彼此靠近的情况下
  • Microsoft VBScript 运行时错误 错误 '800a01a8' 缺少对象: ''

    Microsoft VBScript 运行时错误 错误 39 800a01a8 39 缺少对象 39 39 通常是这个对象已经关闭了 xff0c 你现在又关闭一次 xff01 xff01
  • 0/1背包问题之穷举解法

    0 1背包问题 有一个背包 xff0c 背包容量是M 61 150kg 有7个物品 xff0c 物品不可以分割成任意大小 xff08 这句很重要 xff09 要求尽可能让装入背包中的物品总价值最大 xff0c 但不能超过总容量 物品 A B
  • 把数据转换成json格式的字符串

    最近写程序遇到一个问题 xff0c 把一些数据转换成json格式的字符串保存起来 xff0c 这些数据有普通的键值对 xff0c 还有列表类型的 xff0c 下面写了一个小例子 xff0c 列表数据以复选框CheckBox形式来展示 xff
  • 解决Ubuntu12.04循环登录的问题

    今天用VMvare登录Ubuntu xff0c 发现用户名密码正确的情况下 xff0c 登录不进去 xff0c 循环出现登录界面 xff0c 但是guset可以登录 xff0c 在网上查找资料 xff0c 找到了解决的办法 xff1a 1

随机推荐

  • 美团2018春招笔试题

    任意一个正整数可以用字符 0 9 表示出来 但是当这些字符每种字符数量有限时 xff0c 可能有些正整数表示不出来 比如有两个 1 xff0c 一个 2 xff0c 能表示出11 12 112等等 xff0c 但是无法表示出10 122 2
  • GooglePlay - 排行榜及支付接入

    前言 Google Play应用商店在国外Android市场中地位基本与AppStore在IOS中的地位一致 xff0c 为此考虑国外的应用时 xff0c Android首要考虑的是接入GooglePlay的排行榜等支持 同样的由于Goog
  • 极光推送-点击通知栏跳到指定页面

    在MyReceiver接收器里面 xff0c 添加以下代码 xff1a if JPushInterface ACTION NOTIFICATION OPENED equals intent getAction Log d TAG 34 My
  • Android 5.0以上Button去掉阴影

    1 xff0c 在Button标签中直接添加以下属性 style 61 android attr borderlessButtonStyle 2 xff0c 有的Button的属性已经抽成style 此时直接在style时添加上parent
  • Tinker接入小白教程

    在这里先给大家拜个晚年 xff0c 虽然说新已经过了 本文是今天第一篇文章 xff0c 已经有好长时间没总结了 xff0c 算了给2017开个好头吧 之前一直搞不懂什么是热修复 xff1f 其实热修复就是在应用不用重新安装的情况下更新应用
  • 扫盲Android Studio 仓库jCenter并发布自己的开源库

    AS从哪里获取到开源库 首先我们在使用第三方开源库时 xff0c 直接在项目的 gradle 文件中添加这样一行代码 xff1a compile 39 com jakewharton butterknife 7 0 1 39 添加完之后 x
  • Mac安装android studio后卡在building gradle project info的解决方法

    1 找到 gradle目录 xff0c 一般在 User lt 用户名 gt 下 macOS Sierra 10 12 3可以直接快捷键 shift 43 command 43 显示隐藏的文件即可看到 gradle文件夹 2 进入 grad
  • 动态规划

    动态规划是20世纪50年代由Richard Bellman发明的 不像贪婪算法 xff0c 回溯算法等 xff0c 单从名字上根本理解不了这是什么鬼 Bellman自己也说了 xff0c 这个名字完全是为了申请经费搞出来的 xff08 囧
  • 使用ItemTouchHelper拖拽时两个item跟着动解决方法

    使用ItemTouchHelper时 xff0c 当RecyclerView的item数只有三个时 xff0c 拖动第二个item并拖出边界时 xff0c 第三个item就会往右边动 xff08 按照正常逻辑 xff0c 第三个item是不
  • 仿微信朋友圈发表图片拖拽和删除功能

    小窥朋友圈实现原理 我们使用Android Device Monitor来分析朋友圈发布图片的界面实现原理 如果需要分析其他应用的界面实现也是采用这种方法哦 打开Android Device Monitor xff0c 选择DDMS xff
  • mac ssh记住密码

    以下方法只针对已生成ssh密码的情况 1 cd ssh 2 cp id rsa pub authorized keys 3 有无默认端口号 xff1a xff08 1 xff09 默认端口号为22 xff1a ssh copy id i s
  • idea启动项目启动一半总是卡住不动原因以及解决办法?

    idea 有时出现项目启动运行一半就卡住 xff0c 也不报错 xff0c 你是不是很纳闷 xff1f 其实可能是 你的 断点打的多或者打到方法名上了 解决办法 xff1a 1 找到下图圈出来的按钮 xff0c 这是查看当前项目所有断点的地
  • springsecurity设置用户登录状态过期,让其重新登录

    手动程序让session过期 xff0c 使用户重新登录 判断是否过期 Object expireDate 61 redisTemplate opsForValue get username 43 34 expireDate 34 if e
  • vue如何避免变量赋值后双向绑定

    如 xff1a this list 61 this list2 结果在list改变后 list2也改变 xff0c 这不是我们想要的效果 第一种 xff1a 利用 JSON parse 和 JSON stringify this list
  • 快速部署PaddleHub使用PaddleOCR

    创建虚拟环境 xff1a conda create name hubocr python 61 3 7 安装paddlepaddle pip install paddlepaddle 61 61 2 0 0rc i https mirror
  • 整蛊:聊天中,连续发送消息的vbs脚本

    如何实现连续发送消息呢 xff1f 准备工作 xff1a 只要我们将下面这段代码复制放在记事本里 xff0c 然后保存退出将记事本文件后缀名改为 vbs就可以了 On Error Resume Next Dim wsh s xTimes t
  • 如何处理从application.properties配置文件获取的汉字乱码问题

    平时从配置文件各种读取配置参数都正常 xff0c 但是有时候放了个中文就乱码 xff0c 你肯定试过网上好多方法 xff0c 都没解决 xff0c 那么来看下面 xff0c 恭喜你终于找这里了 这里 xff0c 我们以springboot框
  • mybatis使用相关问题汇总——持续更新中

    1 疑问 xff1a 怎样让表字段和实体类里的驼峰命名字段对应尼 xff1f 解决方案 xff1a 以下配置可让表字段和实体类的字段相对应 1 此方法只针对 39 user name 39 变 userName 这种驼峰有效 xff0c 但
  • 五大常用算法总结

    引言 据说有人归纳了计算机的五大常用算法 xff0c 它们是贪婪算法 xff0c 动态规划算法 xff0c 分治算法 xff0c 回溯算法以及分支限界算法 虽然不知道为何要将这五个算法归为最常用的算法 xff0c 但是毫无疑问 xff0c
  • android 下载应用 通知栏显示进度 下完之后点击安装 (很实用)

    先看效果图 xff1a 这是本人的习惯 xff0c 先上图显示效果 xff0c 看是否是想要的 xff0c 再看代码 有图有真相 代码 xff1a Main package com gem hsx appupdate import andr