android通过service实现更新并显示下载进度条,最后自动安装实例

首先是service:

service 自定义返回的IBinder:

 /**
     * DownloadBinder中定义了一些实用的方法
     */ 
    public class DownloadBinder extends Binder
    {
        public void start()
        { 
            new Thread()
            { 
                public void run()
                { 
                    createNotification(NOTIFY_ID);  //创建通知  
                    startDownload(); //下载  
                }; 
            }.start();
        } 
 
        /**
         * 获取进度
         * @return 进度
         */ 
        public int getProgress()
        { 
            return progress; 
        } 
       
        /**
         * 设置版本信息对象
         * @param vi 版本信息对象
         */
        public void setVersionInfo(VersionInfo vi){
         versionInfo = vi;
        }
    }

其中activity通过获取到的IBinder操作这个service的两个耗时但最重要的方法:

/**
  * 创建通知
  * @param notifyId 通知的ID
  */
 private void createNotification(int notifyId) {
  int icon = R.drawable.ic_launcher;
  CharSequence tickerText = "开始下载";
  long when = System.currentTimeMillis();
  notification = new Notification(icon, tickerText, when);

  // 放置在"正在运行"栏目中
  notification.flags = Notification.FLAG_ONGOING_EVENT;

  RemoteViews contentView = new RemoteViews(mContext.getPackageName(),
    R.layout.downotice);
  contentView.setTextViewText(R.id.fileName, "正在下载:" + versionInfo.getApkName());//TODO 文件名

  // 指定个性化视图
  notification.contentView = contentView;

  Intent intent = new Intent(this, LoginActivity.class);
  PendingIntent contentIntent = PendingIntent.getActivity(mContext, 0,
    intent, PendingIntent.FLAG_UPDATE_CURRENT);
  // 指定内容意图
  notification.contentIntent = contentIntent;
  // 最后别忘了通知一下,否则不会更新
  notificationManager.notify(notifyId, notification);
 }
   /**
  * 下载
  */
    public void startDownload(){
     
     InputStream is = null;
  FileOutputStream fos = null;
  try {
   
   //初始化数据
      fileSize = 0;
      readSize = 0;
      downSize = 0;
      progress = 0;
      
   HttpClient client = new DefaultHttpClient();
   String apkUrl = getApkUrl(versionInfo);
   HttpGet get = new HttpGet(apkUrl);
   HttpResponse response = client.execute(get);
   if (HttpStatus.SC_OK == response.getStatusLine()
     .getStatusCode()) {
    HttpEntity entity = response.getEntity();
    is = entity.getContent();
    fileSize = entity.getContentLength();
    File file = Constants.DOWNLOAD_FILE;
    if(!file.exists()){
     file.mkdir();
    }
    
       String apkFile = file.getPath() + File.separator + versionInfo.getApkName();
    File ApkFile = new File(apkFile);
    fos = new FileOutputStream(ApkFile);
    
    byte buf[] = new byte[1024];
    
    do{
        readSize = is.read(buf);
           downSize += readSize; 
          
           //更新进度条
           updateMessage();
        if(readSize <= 0){
         //下载完成通知安装
         handler.sendEmptyMessage(HandlerCode.DOWN_OVER);
         break;
        }
        fos.write(buf,0,readSize);
    }while(true);
   }
   
  } catch (MalformedURLException e) {
   e.printStackTrace();
   handler.sendEmptyMessage(HandlerCode.SERVICE_EXCEPTION);
  } catch(IOException e){
   handler.sendEmptyMessage(HandlerCode.SERVICE_EXCEPTION);
   e.printStackTrace();
  }finally{
   try {
    if(null != fos){
     fos.close();
    }
    if(null != is){
     is.close();
    }
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
    }
   
    /**
     * 更新进度条
     */
    public void updateMessage()
    {
     int num = (int)((double)downSize / (double)fileSize * 100);
          
     if(num > progress + 1)
     {
   progress = num;
   
      Message msg0 = handler.obtainMessage(); 
      msg0.what = HandlerCode.DOWN_UPDATE; 
      msg0.arg1 = progress;
      handler.sendMessage(msg0);
     }
    }
    这个是主UI:

/**
  * 下载与UI的交互
  */
    private Handler handler = new Handler()
    { 
        public void handleMessage(android.os.Message msg)
        { 
            switch (msg.what)
            { 
             case HandlerCode.DOWN_UPDATE:
              // 更新进度
        RemoteViews contentView = notification.contentView;
              contentView.setTextViewText(R.id.rate, transferNum(downSize) + "M/" + transferNum(fileSize) +"M   " + msg.arg1 + "%"); 
              contentView.setProgressBar(R.id.progress, 100, msg.arg1, false); 
              // 更新UI
              notificationManager.notify(NOTIFY_ID, notification);
              
                    break;
             case HandlerCode.DOWN_OVER:
              notificationManager.cancel(NOTIFY_ID);
              Toast.makeText(mContext, "更新包下载成功!", Toast.LENGTH_SHORT).show();
                 //打开文件进行安装
              installApk();
                 break;
             case HandlerCode.SERVICE_EXCEPTION:
              Toast.makeText(mContext, "更新包下载失败,请检查网络状况是否正常!", Toast.LENGTH_SHORT).show();
              notificationManager.cancel(NOTIFY_ID);
              break;
         } 
        }; 
    }; 

下载完成之后自动安装的方法installApk():

 /**
     * 安装apk
     */
 private void installApk(){
  
  String saveFileName = Constants.DOWNLOAD_FILE.getPath() + File.separator + versionInfo.getApkName();
  File apkfile = new File(saveFileName);
        if (!apkfile.exists()) {
            return;
        }   
        Intent i = new Intent(Intent.ACTION_VIEW);
        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        i.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive");
        this.startActivity(i);
 
 }

其次是Activity:

创建链接对象获取IBinder

 /**
  * Service和Activity的连接对象
  */
 private ServiceConnection conn = new ServiceConnection() {

  public void onServiceConnected(ComponentName name, IBinder service) {

   binder = (DownloadService.DownloadBinder) service;
  }

  public void onServiceDisconnected(ComponentName name) {
  }
 };

链接service:

private void initService(){
  Intent intent = new Intent(this, DownloadService.class);
  startService(intent); // 如果先调用startService,则在多个服务绑定对象调用unbindService后服务仍不会被销毁
  bindService(intent, conn, Context.BIND_AUTO_CREATE);
  
  //启动线程检查是否需要更新
  new Thread(new Runnable(){
   public void run() {
    Looper.prepare();
    String projectUrl = Constants.PROJECT_URL;
    String versionPath = Constants.UPDATE_SERVICE_PATH;
    String infoPath = Constants.UPDATE_INFO_SERVICE_PATH;
    UpdateManager mUpdateManager = new UpdateManager(LoginActivity.this,projectUrl,versionPath,infoPath);
          mUpdateManager.checkAndUpdate();
          Looper.loop();
   }
  }).start();
 }

检查软件是否更新的方法:

checkAndUpdate():

 if(isAlert){
      activity.getHandler().sendEmptyMessage(HandlerCode.START_VERSION_PROGRESS);
     }
     
     int result = checkIsUpdate();
     
     //若版本需要更新
  if(result == HandlerCode.VERSION_CHECK_IS_OLD){
   if(isAlert){
    
    //关闭进度条
    activity.getHandler().sendEmptyMessage(HandlerCode.CLOSE_PROGRESS);
   }
   showNoticeDialog();
  }else{//无需更新的情况
   if(isAlert){
    
    //关闭进度条
    activity.getHandler().sendEmptyMessage(HandlerCode.CLOSE_PROGRESS);
    
    //做相应的提示
    activity.getHandler().sendEmptyMessage(result);
   }
  }
    }

通过判断后台本版号是否升级的方法:

/**
     * 检查是否需要更新
     * @return 检测结果
     */
    public int checkIsUpdate(){
     
     int result = 0;
     InputStream inputStream = null;
  try {
   
   String infoUrl = versionInfo.getVersionFilePath();
      HttpClient client = new DefaultHttpClient();
   HttpGet get = new HttpGet(infoUrl);
   HttpResponse response = client.execute(get);
   if (HttpStatus.SC_OK == response.getStatusLine()
     .getStatusCode()) {//正常响应时
    HttpEntity entity = response.getEntity();
    inputStream = entity.getContent();
    
    int readByte = 0;
    byte buf[] = new byte[1024];
    StringBuilder stringBuilder = new StringBuilder();
          while((readByte = inputStream.read(buf)) > 0){
              stringBuilder.append(new String(buf, 0, readByte));
          }
         
    JSONObject jsonObject = new JSONObject(stringBuilder.toString());
    String serviceVersionName = jsonObject.getString("versionName");
    String serviceVersionCode = jsonObject.getString("versionCode");
    
             PackageManager packageManager = activity.getPackageManager();
             // getPackageName()是你当前类的包名,0代表是获取版本信息
             PackageInfo packInfo = packageManager.getPackageInfo(activity.getPackageName(),0);
             String versionName = packInfo.versionName;
             int oldCode = packInfo.versionCode;
            
    int newCode = Integer.parseInt(serviceVersionCode);
    if(!versionName.equals(serviceVersionName) && (newCode > oldCode)){
     versionInfo.setApkName(jsonObject.getString("apkName"));
     versionInfo.setAppName(jsonObject.getString("appName"));
     versionInfo.setVersionName(serviceVersionName);
     versionInfo.setVersionCode(serviceVersionCode);
     versionInfo.setVersionMessage(jsonObject.getString("versionMessage"));
     result = HandlerCode.VERSION_CHECK_IS_OLD;
    }else{
     
     //最新版本
     result = HandlerCode.VERSION_CHECK_IS_LATEST;
    }
   }else{//响应不正常时
    result = HandlerCode.VERSION_CHECK_NET_WRONG;
   }
  } catch (ClientProtocolException e) {
   e.printStackTrace();
   result = HandlerCode.VERSION_CHECK_NET_WRONG;
  } catch (IOException e) {
   e.printStackTrace();
   result = HandlerCode.VERSION_CHECK_NET_WRONG;
  } catch (JSONException e) {
   e.printStackTrace();
   result = HandlerCode.VERSION_CHECK_EXCEPTION;
  } catch (NameNotFoundException e) {
   e.printStackTrace();
  }finally{
   try {
    //无网络连接的情况
    if(null != inputStream)
     inputStream.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
     return result;
    }
    显示消息提醒对话框:

 /**
     * 显示消息提醒对话框
     */
 private void showNoticeDialog(){
  
  AlertDialog.Builder builder = new Builder(activity);
  builder.setTitle("软件版本更新");
  
  String message = "最新版本:" + versionInfo.getVersionName()+
    "\n\r" + versionInfo.getVersionMessage();
  builder.setMessage(message);
  builder.setPositiveButton("立即更新", new OnClickListener() {  
   
   public void onClick(DialogInterface dialog, int which) {
    dialog.dismiss();
    DownloadBinder b = activity.getBinder();
    b.setVersionInfo(versionInfo);
    //启动下载服务
    b.start();
   }
  });
  builder.setNegativeButton("以后再说", new OnClickListener() {  
   
   public void onClick(DialogInterface dialog, int which) {
    dialog.dismiss();    
   }
  });
  Dialog noticeDialog = builder.create();
  noticeDialog.show();
 }



你可能感兴趣的:(android通过service实现更新并显示下载进度条,最后自动安装实例)