Android 自动更新之状态栏下载状态和进度
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就可以了,最终的效果图片