使用IntentService给自己的Android应用写一个文件下载器。
时间:2014-07-22 23:07:33
收藏:0
阅读:611
接着上一篇的http://www.cnblogs.com/zhengxt/p/3657833.html,当我们想给自己的APP写一个文件下载器时,可以用重写IntentService来实现。
使用IntentService有几个好处,IntentService继承于Service,适合拿来处理一些耗时又不需要去管它的任务。把要执行的任务用Intent加入到队列中,IntentService会有一个工作线程来取出队列中的Intent来处理。需要实现抽象方法onHandleIntent方法来执行这些任务。当所有任务都完成后,IntentService会自动停止。
同时使用Notification在通知栏让用户直观的知道下载进度,推荐使用Android3.0(API11)后提供的Notification.Builder来构建Notification。我这里为了让程序兼容Android2.1-2.3就没有使用Notification.Builder,用被废弃的Notification(int, CharSequence, long)来构建Notification。
还是按照上一篇一样,假设这是个版本更新文件的下载器,当更新文件下载完成后自动弹出安装界面。
IntentService代码:
1 public class DownloadFileService extends IntentService { 2 private static final String TAG = DownloadFileService.class.getSimpleName(); 3 public DownloadFileService() { 4 super("com.test.download"); 5 } 6 7 private NotificationManager notificationManager; 8 private Notification notification; 9 private RemoteViews rViews; 10 protected void onHandleIntent(Intent intent) { 11 Bundle bundle = intent.getExtras(); 12 // 获得下载文件的url 13 String downloadUrl = bundle.getString("url"); 14 // 设置文件下载后的保存路径,保存在SD卡根目录的Download文件夹 15 File dirs = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Download"); 16 // 检查文件夹是否存在,不存在则创建 17 if (!dirs.exists()) { 18 dirs.mkdir(); 19 } 20 File file = new File(dirs, "file.apk"); 21 // 设置Notification 22 notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 23 notification = new Notification(R.drawable.ic_launcher, "版本更新下载", System.currentTimeMillis()); 24 Intent intentNotifi = new Intent(this, Main.class); 25 PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intentNotifi, 0); 26 notification.contentIntent = pendingIntent; 27 // 加载Notification的布局文件 28 rViews = new RemoteViews(getPackageName(), R.layout.downloadfile_layout); 29 // 设置下载进度条 30 rViews.setProgressBar(R.id.downloadFile_pb, 100, 0, false); 31 notification.contentView = rViews; 32 notificationManager.notify(0, notification); 33 // 开始下载 34 downloadFile(downloadUrl, file); 35 // 移除通知栏 36 notificationManager.cancel(0); 37 // 广播出去,由广播接收器来处理下载完成的文件 38 Intent sendIntent = new Intent("com.test.downloadComplete"); 39 // 把下载好的文件的保存地址加进Intent 40 sendIntent.putExtra("downloadFile", file.getPath()); 41 sendBroadcast(sendIntent); 42 } 43 private int fileLength, downloadLength; 44 private void downloadFile(String downloadUrl, File file){ 45 FileOutputStream fos = null; 46 try { 47 fos = new FileOutputStream(file); 48 } catch (FileNotFoundException e) { 49 Log.e(TAG, "找不到保存下载文件的目录"); 50 e.printStackTrace(); 51 } 52 InputStream ips = null; 53 try { 54 URL url = new URL(downloadUrl); 55 HttpURLConnection huc = (HttpURLConnection) url.openConnection(); 56 huc.setRequestMethod("GET"); 57 huc.setReadTimeout(10000); 58 huc.setConnectTimeout(3000); 59 fileLength = Integer.valueOf(huc.getHeaderField("Content-Length")); 60 ips = huc.getInputStream(); 61 // 拿到服务器返回的响应码 62 int hand = huc.getResponseCode(); 63 if (hand == 200) { 64 // 开始检查下载进度 65 handler.post(run); 66 // 建立一个byte数组作为缓冲区,等下把读取到的数据储存在这个数组 67 byte[] buffer = new byte[8192]; 68 int len = 0; 69 while ((len = ips.read(buffer)) != -1) { 70 fos.write(buffer, 0, len); 71 downloadLength = downloadLength + len; 72 } 73 } else { 74 Log.e(TAG, "服务器返回码" + hand); 75 } 76 77 } catch (ProtocolException e) { 78 e.printStackTrace(); 79 } catch (MalformedURLException e) { 80 e.printStackTrace(); 81 } catch (IOException e) { 82 e.printStackTrace(); 83 } finally { 84 try { 85 if (fos != null) { 86 fos.close(); 87 } 88 if (ips != null) { 89 ips.close(); 90 } 91 } catch (IOException e) { 92 e.printStackTrace(); 93 } 94 } 95 } 96 97 98 99 public void onDestroy() { 100 // 移除定時器 101 handler.removeCallbacks(run); 102 super.onDestroy(); 103 } 104 105 // 定时器,每隔一段时间检查下载进度,然后更新Notification上的ProgressBar 106 private Handler handler = new Handler(); 107 private Runnable run = new Runnable() { 108 public void run() { 109 rViews.setProgressBar(R.id.downloadFile_pb, 100, downloadLength*100 / fileLength, false); 110 notification.contentView = rViews; 111 notificationManager.notify(0, notification); 112 handler.postDelayed(run, 1000); 113 } 114 }; 115 116 }
还要记得要在AndroidManifest.xml的application节点里注册Service。例如这样:
1 <service android:name="com.saetest.DownloadFileService"></service>
我们下载个谷歌地图来试试看。
1 public void onClick(View v) { 2 // new CheckedUpdate().execute(); 3 String url = "http://www.appchina.com/market/d/1603385/cop.baidu_0/com.google.android.apps.maps.apk"; 4 Intent downloadIntent = new Intent(this, DownloadFileService.class); 5 Bundle bundle = new Bundle(); 6 bundle.putString("url", url); 7 downloadIntent.putExtras(bundle); 8 startService(downloadIntent); 9 // 设置广播接收器,当新版本的apk下载完成后自动弹出安装界面 10 IntentFilter intentFilter = new IntentFilter("com.test.downloadComplete"); 11 receiver = new BroadcastReceiver() { 12 13 public void onReceive(Context context, Intent intent) { 14 Intent install = new Intent(Intent.ACTION_VIEW); 15 String pathString = intent.getStringExtra("downloadFile"); 16 install.setDataAndType(Uri.fromFile(new File(pathString)), "application/vnd.android.package-archive"); 17 install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 18 context.startActivity(install); 19 } 20 }; 21 registerReceiver(receiver, intentFilter); 22 } 23 24 protected void onDestroy() { 25 // 移除广播接收器 26 if (receiver != null) { 27 unregisterReceiver(receiver); 28 } 29 super.onDestroy(); 30 }
评论(0)