Android 自動更新之狀態列下載狀態和進度
阿新 • • 發佈:2019-01-29
android 自動檢測版本在這裡就不用說了,今天想和大家一起分享的是如何將下載更新檔案最小化到工作列下載,替代掉醜陋的對話方塊提示下載,對話方塊提示下載的使用者體驗相當不好,我們把它修改成為後臺下載這樣可以改善使用者的使用體驗。 廢話就不多說了,直接貼程式碼。首先要建立一個Service來執行下載更新檔案的任務: public class UpdateService extends Service{ private NotificationManager nm; private Notification notification; private File tempFile=null; private boolean cancelUpdate=false; private MyHandler myHandler; private int download_precent=0; private RemoteViews views; private int notificationId=1234; @Override public IBinder onBind(Intent intent) { return null; } @Override public void onStart(Intent intent,int startId){ super.onStart(intent, startId); } @Override public int onStartCommand(Intent intent,int flags,int startId){ nm=(NotificationManager)getSystemService(NOTIFICATION_SERVICE); notification=new Notification(); notification.icon=android.R.drawable.stat_sys_download; //notification.icon=android.R.drawable.stat_sys_download_done; notification.tickerText=getString(R.string.app_name)+"更新"; notification.when=System.currentTimeMillis(); notification.defaults=Notification.DEFAULT_LIGHTS; //設定工作列中下載程序顯示的views views=new RemoteViews(getPackageName(),R.layout.update); notification.contentView=views; PendingIntent contentIntent=PendingIntent.getActivity(this,0,new Intent(this,City.class),0); notification.setLatestEventInfo(this,"","", contentIntent); //將下載任務新增到工作列中 nm.notify(notificationId,notification); myHandler=new MyHandler(Looper.myLooper(),this); //初始化下載任務內容views Message message=myHandler.obtainMessage(3,0); myHandler.sendMessage(message); //啟動執行緒開始執行下載任務 downFile(intent.getStringExtra("url")); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy(){ super.onDestroy(); } //下載更新檔案 private void downFile(final String url) { new Thread() { public void run(){ try { HttpClient client = new DefaultHttpClient(); // params[0]代表連線的url HttpGet get = new HttpGet(url); HttpResponse response = client.execute(get); HttpEntity entity = response.getEntity(); long length = entity.getContentLength(); InputStream is = entity.getContent(); if (is != null) { File rootFile=new File(Environment.getExternalStorageDirectory(), "/pinke"); if(!rootFile.exists()&&!rootFile.isDirectory()) rootFile.mkdir(); tempFile = new File(Environment.getExternalStorageDirectory(), "/pinke/"+url.substring(url.lastIndexOf("/")+1)); if(tempFile.exists()) tempFile.delete(); tempFile.createNewFile(); //已讀出流作為引數建立一個帶有緩衝的輸出流 BufferedInputStream bis = new BufferedInputStream(is); //建立一個新的寫入流,講讀取到的影象資料寫入到檔案中 FileOutputStream fos = new FileOutputStream(tempFile); //已寫入流作為引數建立一個帶有緩衝的寫入流 BufferedOutputStream bos = new BufferedOutputStream(fos); int read; long count=0; int precent=0; byte[] buffer=new byte[1024]; while( (read = bis.read(buffer)) != -1 && !cancelUpdate){ bos.write(buffer,0,read); count+=read; precent=(int)(((double)count/length)*100); //每下載完成5%就通知工作列進行修改下載進度 if(precent-download_precent>=5){ download_precent=precent; Message message=myHandler.obtainMessage(3,precent); myHandler.sendMessage(message); } } bos.flush(); bos.close(); fos.flush(); fos.close(); is.close(); bis.close(); } if(!cancelUpdate){ Message message=myHandler.obtainMessage(2,tempFile); myHandler.sendMessage(message); }else{ tempFile.delete(); } } catch (ClientProtocolException e) { Message message=myHandler.obtainMessage(4,"下載更新檔案失敗"); myHandler.sendMessage(message); } catch (IOException e) { Message message=myHandler.obtainMessage(4,"下載更新檔案失敗"); myHandler.sendMessage(message); } catch(Exception e){ Message message=myHandler.obtainMessage(4,"下載更新檔案失敗"); myHandler.sendMessage(message); } } }.start(); } //安裝下載後的apk檔案 private void Instanll(File file,Context context){ Intent intent = new Intent(Intent.ACTION_VIEW); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setAction(android.content.Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(file),"application/vnd.android.package-archive"); context.startActivity(intent); } /*事件處理類*/ class MyHandler extends Handler{ private Context context; public MyHandler(Looper looper,Context c){ super(looper); this.context=c; } @Override public void handleMessage(Message msg){ super.handleMessage(msg); if(msg!=null){ switch(msg.what){ case 0: Toast.makeText(context,msg.obj.toString(), Toast.LENGTH_SHORT).show(); break; case 1: break; case 2: //下載完成後清除所有下載資訊,執行安裝提示 download_precent=0; nm.cancel(notificationId); Instanll((File)msg.obj,context); //停止掉當前的服務 stopSelf(); break; case 3: //更新狀態列上的下載進度資訊 views.setTextViewText(R.update_id.tvProcess,"已下載"+download_precent+"%"); views.setProgressBar(R.update_id.pbDownload,100,download_precent,false); notification.contentView=views; nm.notify(notificationId,notification); break; case 4: nm.cancel(notificationId); break; } } } } } 下載更新提示的佈局xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:background="#f2f2f2" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="center"> <ImageView android:id="@+update_id/ivLogo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/logo" android:layout_margin="10dip" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" android:layout_weight="1" android:layout_marginRight="10dip"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@color/deepblack" android:text="@string/app_name" android:textSize="18dip" android:textStyle="bold"/> <ProgressBar android:id="@+update_id/pbDownload" android:layout_width="fill_parent" android:layout_height="12dip" android:progress="0" android:max="100" android:progressDrawable="@drawable/pb_style" style="?android:attr/progressBarStyleHorizontal" mce_style="?android:attr/progressBarStyleHorizontal" /> <TextView android:id="@+update_id/tvProcess" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@color/deepblack" android:text="已下載0%" android:textSize="12dip" android:textStyle="bold" /> </LinearLayout> </LinearLayout> </LinearLayout> 在外面需要呼叫下載任務的地方使用startService(intent)來呼叫這個Service就可以了,最終的效果圖片