• 使用IntentService给自己的Android应用写一个文件下载器。


    接着上一篇的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     }

      

  • 相关阅读:
    实现倒计时
    slidingMenu使用中侧滑回界面后,出现无焦点问题
    android eclipse 下Device无设备问题解决
    android cordova java.lang.Throwable: EventHub.removeMessages(int what = 107) is not supported before the WebViewCore is set up问题的解决和想法
    Android Cordova 对于软键盘弹出后覆盖输入域的解决
    Extjs最后一页数据删除之后自动返回上一页
    jquery Unexpected token i
    批量删除.svn文件夹、.svn文件
    mysql创建用户权限
    mysql存储过程解决数组传参及游标CURSOR的问题解决方案
  • 原文地址:https://www.cnblogs.com/zhengxt/p/3700502.html
Copyright © 2020-2023  润新知