谷歌建议我们使用versionCode自增来表明版本升级,无论是大的改动还是小的改动,而versionName是显示用"/> "/>

Android学习系列(2)--App自动更新之通知栏下载

2018-04-15 16页 doc 76KB 22阅读

用户头像

is_574951

暂无简介

举报
Android学习系列(2)--App自动更新之通知栏下载Android学习系列(2)--App自动更新之通知栏下载 Android学习系列(2)--App自动更新之通知栏下载 这篇文章是android开发人员的必备知识,是我特别为大家整理和总结的,不求完美,但是有用。 1.设计思路,使用VersionCode定义为版本升级参数。 android为我们定义版本提供了2个属性: 1 4 android:versionName="1.0" > 谷歌建议我们使用versionCode自增来表明版本升级,无论是大的改动还是小的改动,而versionName是显示用户看的软件版...
Android学习系列(2)--App自动更新之通知栏下载
Android学习系列(2)--App自动更新之通知栏下载 Android学习系列(2)--App自动更新之通知栏下载 这篇文章是android开发人员的必备知识,是我特别为大家整理和总结的,不求完美,但是有用。 1.设计思路,使用VersionCode定义为版本升级参数。 android为我们定义版本提供了2个属性: 1 4 android:versionName="1.0" > 谷歌建议我们使用versionCode自增来表明版本升级,无论是大的改动还是小的改动,而versionName是显示用户看的软件版本,作为显示使用。所以我们选择了VersionCode作为我们定义版本升级的参数。 2.工程目录 为了对真实项目或者企业运用有实战指导作用,我模拟一个独立的项目,工程目录设置的合理严谨一些,而不是仅仅一个demo。 假设我们以上海地铁为项目,命名为"Subway",工程结构如下, 3.版本初始化和版本号的对比。 首先定义在全局文件Global.java中定义变量localVersion和serverVersion分别 存放本地版本号和服务器版本号。 1 public class Global { //版本信息 2 3 public static int localVers 4 ion = 0; 5 public static int serverVer 6 sion = 0; public static String downloadDir = "app/download/"; } 因为本文只是重点说明升级更新,为了防止其他太多无关代码冗余其中,我直接在 SubwayApplication中定义方法initGlobal()方法。 1 /** * 初始化全局变量 2 * 实际工作中这个方法中serverVersion从服务器端获取,最好在启动画面的3 activity中执行 4 5 */ 6 public void initGlobal(){ 7 try{ 8 Global.localVersion = 9 getPackageManager().getPackageInfo(getPackageName(),0).versionC ode; //设置本地版本号 10 Global.serverVersion = 1;//假定服务器版本为2,本地版本默认11 是1 12 }catch (Exception ex){ ex.printStackTrace(); } } 如果检测到新版本发布,提示用户是否更新,我在SubwayActivity中定义了 checkVersion()方法: 1 /** * 检查更新版本 2 3 */ 4 public void checkVersion(){ 5 6 if(Global.localVersion < Global.serverVersion){ //发现新版本,提示用户更新 7 8 AlertDialog.Builder alert = new AlertDialog.Builder(this); alert.setTitle("软件升级") 9 .setMessage("发现新版本,建议立即更新使用.") 10 .setPositiveButton("更新11 12 ", new DialogInterface.OnClickListener() { 13 public void onClick(DialogInterface 14 dialog, int which) { //开启更新服务UpdateService 15 //这里为了把update更好模块化,可以传一些16 updateService依赖的值 17 //如布局ID,资源ID,动态获取的标,这里以18 app_name为例 19 20 Intent updateIntent 21 =new Intent(SubwayActivity.this, UpdateService.class); 22 updateIntent.putExtra("titleId",R.string.app 23 _name); 24 startService(updateIntent); 25 } 26 }) .setNegativeButton("取消27 28 ",new DialogInterface.OnClickListener(){ 29 public void onClick(DialogInterface 30 dialog, int which) { 31 dialog.dismiss(); } }); alert.create().show(); }else{ //清理工作,略去 //cheanUpdateFile(),文章后面我会附上代码 } } 如下图: 好,我们现在把这些东西串一下: 第一步在SubwayApplication的onCreate()方法中执行initGlobal()初始化版本变 量。 1 public void onCreate 2 () { 3 super.onCreate() 4 ; initGlobal(); } 第二步在SubwayActivity的onCreate()方法中检测版本更新checkVersion()。 1 public void onCreate(Bundle 2 savedInstanceState) { 3 super.onCreate(savedInstanceSta 4 te); 5 setContentView(R.layout.main); checkVersion(); } 现在入口已经打开,在checkVersion方法的第18行代码中看出,当用户点击更新, 我们开启更新服务,从服务器上下载最新版本。 4.使用Service在后台从服务器端下载,完成后提示用户下载完成,并关闭服务。 定义一个服务UpdateService.java,首先定义与下载和通知相关的变量: //标题 1 2 private int titleId = 0; 3 //文件存储 4 5 private File updateDir 6 = null; 7 private File updateFile 8 = null; 9 //通知栏 10 11 private NotificationMana12 ger 13 updateNotificationManage r = null; private Notification updateNotification = null; //通知栏跳转Intent private Intent updateIntent = null; private PendingIntent updatePendingIntent = null; 在onStartCommand()方法中准备相关的下载工作: 1 @Override 2 public int onStartCommand(Intent intent, int flags, int startId) { //获取传值 3 4 titleId = intent.getIntExtra("titleId",0); //创建文件 5 6 if(android.os.Environment.MEDIA_MOUNTED.equals(android.os.Environment.getExte 7 rnalStorageState())){ 8 updateDir 9 = new File(Environment.getExternalStorageDirectory(),Global.downloadDir); 1 updateFile 0 = new File(updateDir.getPath(),getResources().getString(titleId)+".apk"); 1 } 1 1 this.updateNotificationManager = 2 (NotificationManager)getSystemService(NOTIFICATION_SERVICE); 1 this.updateNotification = new Notification(); 3 //设置下载过程中,点击通知栏,回到主界面 1 4 updateIntent = new Intent(this, SubwayActivity.class); 1 updatePendingIntent = PendingIntent.getActivity(this,0,updateIntent,0); //设置通知栏显示 5 1 updateNotification.icon = R.drawable.arrow_down_float; updateNotification.tickerText = "开始下载"; 6 updateNotification.setLatestEventInfo(this,"上海地铁1 7 ","0%",updatePendingIntent); //发出通知 1 8 updateNotificationManager.notify(0,updateNotification); 1 //开启一个新的线程下载,如果使用Service同步下载,会导致ANR问题,Service本身也会阻9 塞 2 new Thread(new updateRunnable()).start();//这个是下载的重点,是下载的过程 0 2 1 return super.onStartCommand(intent, flags, startId); 2} 2 2 3 2 4 2 5 2 6 2 7 2 8 上面都是准备工作,如图: 从代码中可以看出来,updateRunnable类才是真正下载的类,出于用户体验的考虑, 这个类是我们单独一个线程后台去执行的。 下载的过程有两个工作:1.从服务器上下载数据;2.通知用户下载的进度。 线程通知,我们先定义一个空的updateHandler。 1 private Handler updateHandler 2 = new Handler(){ 3 @Override 4 public void handleMessage(Mes 5 sage msg) { 6 } }; 再来创建updateRunnable类的真正实现: 1 class updateRunnable implements Runnable { 2 Message message = updateHandler.obtainMessage(); 3 public void run() { 4 message.what = DOWNLOAD_COMPLETE; 5 try{ //增加权限; 6 7 if(!updateDir.exists()){ 8 updateDir.mkdirs(); 9 } 10 if(!updateFile.exists()){ 11 updateFile.createNewFile(); 12 } //下载函数,以QQ为例子 13 //增加权限; 14 15 long downloadSize = 16 downloadUpdateFile(":8080/msoft/ 17 179/1105/10753/MobileQQ1.0(Android)_Build0198.apk",update18 File); 19 if(downloadSize>0){ //下载成功 20 21 updateHandler.sendMessage(message); 22 } 23 }catch(Exception ex){ 24 ex.printStackTrace(); 25 message.what = DOWNLOAD_FAIL; //下载失败 26 27 updateHandler.sendMessage(message); } } } 下载函数的实现有很多,我这里把代码贴出来,而且我们要在下载的时候通知用户下载进度: 1 public long downloadUpdateFile(String downloadUrl, File 2 saveFile) throws Exception { //这样的下载代码很多,我就不做过多的说明 3 4 int downloadCount = 0; 5 int currentSize = 0; 6 long totalSize = 0; 7 int updateTotalSize = 0; 8 9 HttpURLConnection httpConnection = null; 10 InputStream is = null; 11 FileOutputStream fos = null; 12 13 try { 14 URL url = new URL(downloadUrl); 15 httpConnection = (HttpURLConnection)url.openConnection(); 16 httpConnection.setRequestProperty("User-Agent", "PacificHttpC 17 lient"); 18 if(currentSize > 0) { 19 httpConnection.setRequestProperty("RANGE", "bytes=" + 20 currentSize + "-"); 21 } 22 httpConnection.setConnectTimeout(10000); 23 httpConnection.setReadTimeout(20000); 24 updateTotalSize = httpConnection.getContentLength(); 25 if (httpConnection.getResponseCode() == 404) { 26 throw new Exception("fail!"); 27 } 28 is = httpConnection.getInputStream(); 29 fos = new FileOutputStream(saveFile, false); 30 byte buffer[] = new byte[4096]; 31 int readsize = 0; 32 while((readsize = is.read(buffer)) > 0){ 33 fos.write(buffer, 0, readsize); 34 totalSize += readsize; //为了防止频繁的通知导致应用吃紧,百分比增加10才通知一次 35 36 if((downloadCount == 0)||(int) 37 (totalSize*100/updateTotalSize)-10>downloadCount){ 38 downloadCount += 10; 39 updateNotification.setLatestEventInfo(UpdateService.this, "正在下载", (int)totalSize*100/updateTotalSize+"%", updatePendingIntent); 40 41 updateNotificationManager.notify(0, 42 updateNotification); 43 } 44 } 45 } finally { 46 if(httpConnection != null) { 47 httpConnection.disconnect(); 48 } 49 if(is != null) { 50 is.close(); 51 } if(fos != null) { fos.close(); } } return totalSize; } 显示下载进度,如图: 下载完成后,我们提示用户下载完成,并且可以点击安装,那么我们来补全前面的Handler 吧。 先在UpdateService.java定义2个常量来表示下载状态: //下载状态 1 2 private final static int DOWNLOAD_COMP 3 LETE = 0; private final static int DOWNLOAD_FAIL = 1; 根据下载状态处理主线程: 1 private Handler updateHandler = new Handler(){ 2 @Override 3 public void handleMessage(Message msg) { 4 switch(msg.what){ 5 case DOWNLOAD_COMPLETE: //点击安装PendingIntent 6 7 Uri uri = Uri.fromFile(updateFile); 8 Intent installIntent = new Intent(Intent.ACTION_VIEW); 9 installIntent.setDataAndType(uri, "application/vnd.android.packag 1e-archive"); 0 updatePendingIntent = 1PendingIntent.getActivity(UpdateService.this, 0, installIntent, 0); 1 updateNotification.defaults = Notification.DEFAULT_SOUND;//铃声提1 醒 2 updateNotification.setLatestEventInfo(UpdateService.this, "上海地1 铁", "下载完成,点击安装。", updatePendingIntent); 3 1 updateNotificationManager.notify(0, updateNotification); 4 //停止服务 1 5 stopSelf(); 1 break; 6 case DOWNLOAD_FAIL: //下载失败 1 updateNotification.setLatestEventInfo(UpdateService.this, "上海地7 铁", "下载完成,点击安装。", updatePendingIntent); 1 8 updateNotificationManager.notify(0, updateNotification); 1 break; 9 default: 2 stopSelf(); 0 } 2 } 1 }; 2 2 2 3 2 4 2 5 2 6 2 7 2 8 下载完成,如图: 至此,文件下载并且在通知栏通知进度。 发现本人废话很多,其实几句话的事情,来来回回写了这么多,啰嗦了,后面博文我会朝着 精简方面努力。 PS:前面说要附上cheanUpdateFile()的代码 1 File updateFile 2 = new File(Global.downloadDir,getResources().getString(R.string.app_name)+ 3 ".apk"); 4 if(updateFile.exists()){ //当不需要的时候,清除之前的下载文件,避免浪费用户空间 5 updateFile.delete(); }
/
本文档为【Android学习系列&#40;2&#41;--App自动更新之通知栏下载】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索