打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
android带进度条的大文件下载代码

首先我们要导入Trinea/Android-common 包,里面有封装好的下载类和安装apk类,可以方便的获取下载状态,下载地址:https://github.com/Trinea/android-common




首先声明权限:

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


先写一个service类来定时访问服务器获取新版本号,并弹出对话框提示
andoridManifest注册下面要写的服务:

  1. <service android:name=".CheckVersion">  

  1. package com.example.download_test;  
  2.   
  3. import org.json.JSONObject;  
  4.   
  5. import cn.trinea.android.common.util.DownloadManagerPro;  
  6. import cn.trinea.android.common.util.PackageUtils;  
  7. import android.app.Activity;  
  8. import android.app.AlertDialog;  
  9. import android.app.AlertDialog.Builder;  
  10. import android.app.DownloadManager;  
  11. import android.app.Notification;  
  12. import android.app.NotificationManager;  
  13. import android.app.PendingIntent;  
  14. import android.app.ProgressDialog;  
  15. import android.app.Service;  
  16. import android.content.Context;  
  17. import android.content.DialogInterface;  
  18. import android.content.Intent;  
  19. import android.graphics.Paint.Join;  
  20. import android.net.Uri;  
  21. import android.os.Handler;  
  22. import android.os.IBinder;  
  23. import android.os.Message;  
  24. import android.widget.Toast;  
  25.   
  26. public class CheckVersion extends Service {  
  27.     NotificationManager mNotificationManager;//声明通知栏manager  
  28.     public static DownloadManager downloadManager;//用于给别的类获取id用的超全局下载管理类  
  29.     //用来标志现在是否已经有对话框浮出的状态  
  30.     boolean boxFlag=false;  
  31.     //下载文件的路径  
  32.     public static String URL = "http://192.168.1.112:8080/auto_serve/weichat.apk";  
  33.     //获取新版本号的地址  
  34.     public static String VERSION_URL = "http://192.168.1.112:8080/auto_serve/version_code.txt";  
  35.     //声明进度条对话框  
  36.     ProgressDialog mReadProcessDia=null;    
  37.     //设置最大进度  
  38.     public final static int MAX_READPROCESS = 100;   
  39.     //设置用于弹出对话框的activity对象  
  40.     public Context context =  MainActivity.SUPERCONTEXT;  
  41.       
  42.     /** 
  43.      * 在检测到新版本时,和点击了确定更新按钮后,显示对话框的handler          
  44.      * @author Administrator 
  45.      * 
  46.      */  
  47.     class versionHandler extends Handler{  
  48.         @Override  
  49.         public void handleMessage(Message msg) {  
  50.             // TODO Auto-generated method stub  
  51.               
  52.             //如果收到的是更新进度条的message  
  53.             if(msg.arg1==222){  
  54.                  System.out.println("收到进度"+msg.arg2);  
  55.                     //进度条对话框更新进度  
  56.                     mReadProcessDia.setProgress(msg.arg2);    
  57.                        
  58.                 return;  
  59.             }  
  60.               
  61.             //如果收到的是提示更新的message  
  62.             Toast.makeText(getApplicationContext(), "发现新版本", Toast.LENGTH_SHORT).show();  
  63.               
  64.             //蹦出通知对话框  
  65.             if(boxFlag==false){  
  66.             AlertDialog.Builder normalDia =new AlertDialog.Builder(context);    
  67.             normalDia.setIcon(R.drawable.ic_launcher);    
  68.             normalDia.setTitle("新版本提示");    
  69.             normalDia.setCancelable(false);  
  70.             normalDia.setMessage("有新版本了,是否更新");              
  71.             normalDia.setPositiveButton("确定", new DialogInterface.OnClickListener() {   
  72.                 public void onClick(DialogInterface dialog, int which) {    
  73.                     System.out.println("点击了确定");  
  74.                     boxFlag=true;//禁止弹出新的对话框  
  75.                     //初始化进度条对话框  
  76.                     mReadProcessDia=new ProgressDialog(context);    
  77.                     mReadProcessDia.setProgress(0);    
  78.                     mReadProcessDia.setIndeterminate(false);    
  79.                     mReadProcessDia.setCancelable(false);//设置进度条对话框是否可以被点没,如果为true,相当于后台下载,完毕后不受影响  
  80.                     mReadProcessDia.setTitle("下载进度");    
  81.                     mReadProcessDia.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);    
  82.                     mReadProcessDia.setMax(MAX_READPROCESS);    
  83.                     mReadProcessDia.show();    
  84.                     new Thread(downloadRunnable).start();//启动下载子线程  
  85.                       
  86.   
  87.                 }    
  88.             });    
  89.                  
  90.                 normalDia.setNegativeButton("取消", new DialogInterface.OnClickListener() {    
  91.                     public void onClick(DialogInterface dialog, int which) {    
  92.                           System.out.println("点击了取消");  
  93.                           boxFlag=false;//后面可以继续弹出新对话框  
  94.                     }    
  95.                 });    
  96.                 if(boxFlag==false){  
  97.                     normalDia.create().show();  
  98.                     boxFlag=true;//禁止再弹出对话框  
  99.                 }  
  100.             }  
  101.               
  102.               
  103.               
  104.               
  105.             if(mNotificationManager==null){//通知栏提示只显示一次  
  106.             mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);  
  107.             //设置通知栏的图标  
  108.             int icon = R.drawable.ic_launcher;  
  109.             //通知栏的浮现文本  
  110.             CharSequence tickerText = "发现新版本";  
  111.             long when = System.currentTimeMillis();  
  112.             Notification notification = new Notification(icon, tickerText, when);  
  113.              //定义下拉通知栏时要展现的内容信息  
  114.             Context context = getApplicationContext();  
  115.             CharSequence contentTitle = "汽车报价大全发现新版本";  
  116.             CharSequence contentText = "点击此处自动更新";  
  117.             Intent notificationIntent = new Intent(CheckVersion.this, MainActivity.class);  
  118.             PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0,notificationIntent, 0);  
  119.             notification.setLatestEventInfo(context, contentTitle, contentText,contentIntent);    
  120.             //用mNotificationManager的notify方法通知用户生成标题栏消息通知  
  121.             mNotificationManager.notify(1, notification);  
  122.             
  123.             }  
  124.         }  
  125.           
  126.     }  
  127.       
  128.       
  129.     //声明handler  
  130.      versionHandler handler1 = new versionHandler();  
  131.        
  132.      //下载子线程的方法  
  133.      Runnable downloadRunnable = new Runnable() {  
  134.             public void run() {  
  135.                 System.out.println("下载线程已启动");  
  136.                 downloadManager = (DownloadManager)getSystemService(DOWNLOAD_SERVICE);  
  137.                 //设置下载地址  
  138.                 String apkUrl = URL;  
  139.                 DownloadManager.Request request = new DownloadManager.Request(Uri.parse(apkUrl));  
  140.                 //设置下载路径和文件名,不要忘了开启写存储设备权限  
  141.                 request.setDestinationInExternalPublicDir("Trinea", "MeiLiShuo.apk");//表示设置下载地址为sd卡的Trinea文件夹,文件名为MeiLiShuo.apk。其他设置下载路径接口为setDestinationUri,setDestinationInExternalFilesDir,setDestinationToSystemCache。其中setDestinationToSystemCache仅限系统app使用。  
  142.                 //魅族手机在通知栏不会有提示,其他的好像都行  
  143.                 request.setTitle("汽车报价正在下载");//设置下载中通知栏提示的标题  
  144.                 request.setDescription("新版2.0");//设置下载中通知栏提示的介绍  
  145.                 request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);//表示下载进行中和下载完成的通知栏是否显示。默认只显示下载中通知。VISIBILITY_VISIBLE_NOTIFY_COMPLETED表示下载完成后显示通知栏提示。VISIBILITY_HIDDEN表示不显示任何通知栏提示,这个需要在AndroidMainfest中添加权限android.permission.DOWNLOAD_WITHOUT_NOTIFICATION.  
  146.                 //request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);//表示下载允许的网络类型,默认在任何网络下都允许下载。有NETWORK_MOBILE、NETWORK_WIFI、NETWORK_BLUETOOTH三种及其组合可供选择。如果只允许wifi下载,而当前网络为3g,则下载会等待。  
  147.                 //request.setAllowedOverRoaming(boolean allow)移动网络情况下是否允许漫游。  
  148.                 //request.setMimeType("application/cn.trinea.download.file");//设置下载文件的mineType。因为下载管理Ui中点击某个已下载完成文件及下载完成点击通知栏提示都会根据mimeType去打开文件,所以我们可以利用这个属性。比如上面设置了mimeType为application/cn.trinea.download.file,我们可以同时设置某个Activity的intent-filter为application/cn.trinea.download.file,用于响应点击的打开文件。  
  149.                 //request.addRequestHeader(String header, String value)// 添加请求下载的网络链接的http头,比如User-Agent,gzip压缩等  
  150.                   
  151.                 //获取该下载的标示id  
  152.                  long downloadId = downloadManager.enqueue(request);  
  153.                  DownloadManagerPro downloadManagerPro = new DownloadManagerPro(downloadManager);  
  154.                  //用于更新进度条的方法,一秒更新五次  
  155.                  while(1==1){  
  156.                      try {  
  157.                         Thread.sleep(200);//设置更新频率  
  158.                           
  159.                     } catch (InterruptedException e) {  
  160.                         // TODO Auto-generated catch block  
  161.                         e.printStackTrace();  
  162.                     }  
  163.                        
  164.                     //获得下载进度信息  
  165.                     int[] bytesAndStatus = downloadManagerPro.getBytesAndStatus(downloadId);  
  166.                     //[0]是已经下载的大小,[1]是总大小,[2]是网络环境,2是联网,4是断网  
  167.                     int progress = 0;  
  168.                     try {//可能会有除以0异常  
  169.                         progress = bytesAndStatus[0]/(bytesAndStatus[1]/100);  
  170.                     } catch (Exception e) {  
  171.                         // TODO Auto-generated catch block  
  172.                         e.printStackTrace();  
  173.                     }  
  174.                      Message message = Message.obtain();  
  175.                      message.arg1=222;  
  176.                      message.arg2=progress;  
  177.                      handler1.sendMessage(message);//发送给handler更新进度条  
  178.                      //如果下载完毕,关闭进度条和该线程  
  179.                      if(bytesAndStatus[0]==bytesAndStatus[1]){  
  180.                          mReadProcessDia.cancel();  
  181.                          break;  
  182.                      }  
  183.                  }  
  184.             };  
  185.         };  
  186.       
  187.         @Override  
  188.     /** 
  189.      * 一旦该服务启动,就不停的联网获取新版本号 
  190.      */  
  191.     public int onStartCommand(Intent intent, int flags, int startId) {  
  192.         // TODO Auto-generated method stub  
  193.         System.out.println("服务开启");  
  194.           
  195.         new Thread(){  
  196.             @Override  
  197.             public void run() {  
  198.                 // TODO Auto-generated method stub  
  199.                 while(1==1){//不停地联网检查有无新版本并和现有版本比较  
  200.                 try {  
  201.                     //从服务器获取json并解析出新版本号,这里可以灵活处理  
  202.                     String versionJson = GetCarBrands.net(VERSION_URL, null, null);  
  203.                     JSONObject jsonObject = new JSONObject(versionJson);  
  204.                     int newVersion = jsonObject.getInt("version");  
  205.                     //请灵活处理  
  206.                       
  207.                     System.out.println("新版本是"+newVersion);  
  208.                     //获取现在的版本号  
  209.                     int oldVersion = PackageUtils.getAppVersionCode(getApplicationContext());  
  210.                     System.out.println("旧版本是"+oldVersion);  
  211.                     if(newVersion>oldVersion){  
  212.                         System.out.println("该更新了!!!");  
  213.                         Message message = Message.obtain();  
  214.                         message.arg1=1;  
  215.                         if(boxFlag==false)//如果现在可以弹出对话框,就向handler发出更新ui的通知  
  216.                         handler1.sendMessage(message);  
  217.                     }  
  218.                 } catch (Exception e) {  
  219.                     // TODO Auto-generated catch block  
  220.                     e.printStackTrace();  
  221.                 }  
  222.                 try {  
  223.                     Thread.sleep(90000);//设置访问服务器获取版本号的频率  
  224.                 } catch (InterruptedException e) {  
  225.                     // TODO Auto-generated catch block  
  226.                     e.printStackTrace();  
  227.                 }  
  228.                 }  
  229.             }  
  230.         }.start();  
  231.         return super.onStartCommand(intent, flags, startId);  
  232.     }  
  233.       
  234.     @Override  
  235.     public IBinder onBind(Intent intent) {  
  236.         // TODO Auto-generated method stub  
  237.         return null;  
  238.     }  
  239.       
  240.   
  241. }  


然后android-common为我们提供了一个广播接收器,这个接收器专门用于收取下载完毕的广播,所以我们把下载完毕后调用的功能写在这里面

  1. package com.example.download_test;  
  2.   
  3. import cn.trinea.android.common.util.PackageUtils;  
  4. import android.app.AlertDialog;  
  5. import android.app.DownloadManager;  
  6. import android.app.ProgressDialog;  
  7. import android.app.Service;  
  8. import android.content.BroadcastReceiver;  
  9. import android.content.Context;  
  10. import android.content.DialogInterface;  
  11. import android.content.Intent;  
  12. import android.net.Uri;  
  13.   
  14. public class CompleteReceiver extends BroadcastReceiver {  
  15.     //设置用于弹出对话框的activity    <pre name="code" class="java">       //设置用于弹出对话框的activity  
  16. <span style="white-space:pre">    </span>  
  17. <span style="white-space:pre">    </span>@Override //收到下载完毕的广播  
  18. <span style="white-space:pre">    </span>public void onReceive(final Context context, Intent intent) {  
  19. <span style="white-space:pre">        </span>// TODO Auto-generated method stub  
  20. <span style="white-space:pre">        </span>//获得被下载文件的标示id  
  21. <span style="white-space:pre">        </span>long completeDownloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);  
  22. <span style="white-space:pre">        </span>System.out.println(completeDownloadId+"下载完毕");  
  23. <span style="white-space:pre">        </span>//从别的类那里获得管理器  
  24. <span style="white-space:pre">        </span>DownloadManager downloadManager = CheckVersion.downloadManager;  
  25. <span style="white-space:pre">        </span>//根据下载id获得下载后的路径  
  26. <span style="white-space:pre">        </span>final Uri path = downloadManager.getUriForDownloadedFile(completeDownloadId);  
  27. <span style="white-space:pre">        </span>System.out.println("下载存储uri是"+path);//file:///storage/emulated/0/Trinea/MeiLiShuo-7.apk  
  28. <span style="white-space:pre">        </span>//将路径uri转换成String  
  29. <span style="white-space:pre">        </span>final String pathString = path.toString().substring(7,path.toString().length());  
  30. <span style="white-space:pre">        </span>System.out.println("下载路径是"+ pathString);//:   /storage/emulated/0/Trinea/MeiLiShuo-7.apk  
  31. <span style="white-space:pre">        </span>  
  32. <span style="white-space:pre">        </span>//安装要放在子线程进行  
  33. <span style="white-space:pre">        </span>final Thread installThread = new Thread(){  
  34. <span style="white-space:pre">            </span>public void run() {  
  35. <span style="white-space:pre">                </span>//返回-3是路径错误,不用添加任何权限,软件会自动申请root  
  36. <span style="white-space:pre">                </span>//PackageUtils.installSilent静默安装,会请求获得root权限  
  37. <span style="white-space:pre">                </span>//PackageUtils.installNormal普通安装  
  38. <span style="white-space:pre">                </span>System.out.println("错误码:::"+PackageUtils.installNormal(context,pathString));  
  39. <span style="white-space:pre">                </span>System.out.println("安装成功");  
  40. <span style="white-space:pre">                </span>  
  41. <span style="white-space:pre">            </span>};  
  42. <span style="white-space:pre">        </span>};  
  43. <span style="white-space:pre">        </span>  
  44. <span style="white-space:pre">        </span>//下载完毕后弹出个对话框,点确定开始安装  
  45. <span style="white-space:pre">        </span>AlertDialog.Builder normalDia =new AlertDialog.Builder(context);    
  46.         normalDia.setIcon(R.drawable.ic_launcher);    
  47.         normalDia.setTitle("下载完毕");    
  48.         normalDia.setCancelable(false);  
  49.         normalDia.setMessage("下载完毕,是否安装");              
  50.         normalDia.setPositiveButton("确定", new DialogInterface.OnClickListener() {   
  51.             public void onClick(DialogInterface dialog, int which) {    
  52.                 System.out.println("点击了确定");  
  53. <span style="white-space:pre">        </span>       installThread.start();//启动安装子线程  
  54. <span style="white-space:pre">        </span>          
  55.             }    
  56.         });    
  57.         normalDia.setNegativeButton("取消", new DialogInterface.OnClickListener() {    
  58.             public void onClick(DialogInterface dialog, int which) {    
  59.                   System.out.println("点击了取消");  
  60.             }    
  61.         });    
  62.         normalDia.create().show();  
  63. <span style="white-space:pre">    </span>}  


还需要在主线程开启上面的服务就好了,并且在activity中注册上面写的接收器

  1. /** 注册下载成功的广播接受者 **/  
  2.         completeReceiver = new CompleteReceiver();  
  3.         registerReceiver(completeReceiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));  
  1. </pre><pre name="code" class="java">//启动检查版本的服务  
  2. <span style="white-space:pre">        </span>Intent intent = new Intent(this,CheckVersion.class);  
  3. <span style="white-space:pre">        </span>startService(intent);  




本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
android – 没有填充的进度对话框
[AHK]定时监控监解析通达信股票警告信息
JavaScript的setAttribute兼容性问题解决方法
火狐自动换行处理
美!太美了!//清理了大量无效代码
Java泛型编程最全总结
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服