Android开发之文件下载,状态时显示下载进度,点击自动安装
在进行软件升级时,需要进行文件下载,在这里实现自定义的文件下载,并在状态栏显示下载进度,下载完成后,点击触发安装。
效果如图:
用于下载文件和显示现在进度的线程类如下:
- packagecom.channelsoft.ahzyfis.util;
- importjava.io.File;
- importjava.io.FileOutputStream;
- importjava.io.InputStream;
- importjava.net.HttpURLConnection;
- importjava.net.URL;
- importandroid.app.Notification;
- importandroid.app.NotificationManager;
- importandroid.app.PendingIntent;
- importandroid.content.Context;
- importandroid.content.Intent;
- importandroid.net.Uri;
- importandroid.os.Environment;
- importandroid.os.Handler;
- importandroid.os.Message;
- importandroid.util.Log;
- importandroid.widget.RemoteViews;
- importandroid.widget.Toast;
- importcom.channelsoft.ahzyfis.AhzyFisActivity;
- importcom.channelsoft.ahzyfis.R;
- /**
- *
- *<dl>
- *<dt>AppFileDownUtils.java</dt>
- *<dd>Description:文件下载</dd>
- *<dd>Copyright:Copyright(C)2011</dd>
- *<dd>Company:</dd>
- *<dd>CreateDate:2011-10-19</dd>
- *</dl>
- *
- *@authorZhanHua
- */
- publicclassAppFileDownUtilsextendsThread{
- privateContextmContext;
- privateHandlermHandler;
- privateStringmDownloadUrl;//文件下载url,已做非空检查
- privateStringmFileName;
- privateMessagemsg;
- privatefinalStringAPP_FOLDER="DownDemo";//sd卡应用目录
- privatefinalStringAPK_FOLDER="apkFile";//下载apk文件目录
- publicstaticfinalintMSG_UNDOWN=0;//未开始下载
- publicstaticfinalintMSG_DOWNING=1;//下载中
- publicstaticfinalintMSG_FINISH=1;//下载完成
- publicstaticfinalintMSG_FAILURE=2;//下载失败
- privateNotificationManagermNotifManager;
- privateNotificationmDownNotification;
- privateRemoteViewsmContentView;//下载进度View
- privatePendingIntentmDownPendingIntent;
- publicAppFileDownUtils(Contextcontext,Handlerhandler,
- StringdownloadUrl,StringfileName){
- mContext=context;
- mHandler=handler;
- mDownloadUrl=downloadUrl;
- mFileName=fileName;
- mNotifManager=(NotificationManager)mContext
- .getSystemService(Context.NOTIFICATION_SERVICE);
- msg=newMessage();
- }
- @Override
- publicvoidrun(){
- try{
- if(Environment.getExternalStorageState().equals(
- Environment.MEDIA_MOUNTED)){
- MessagedowningMsg=newMessage();
- downingMsg.what=MSG_DOWNING;
- mHandler.sendMessage(downingMsg);
- //SD卡准备好
- FilesdcardDir=Environment.getExternalStorageDirectory();
- //文件存放路径:sdcard/DownDemo/apkFile
- Filefolder=newFile(sdcardDir+File.separator+APP_FOLDER
- +File.separator+APK_FOLDER);
- if(!folder.exists()){
- //创建存放目录
- folder.mkdir();
- }
- FilesaveFilePath=newFile(folder,mFileName);
- System.out.println(saveFilePath);
- mDownNotification=newNotification(
- android.R.drawable.stat_sys_download,mContext
- .getString(R.string.notif_down_file),System
- .currentTimeMillis());
- mDownNotification.flags=Notification.FLAG_ONGOING_EVENT;
- mDownNotification.flags=Notification.FLAG_AUTO_CANCEL;
- mContentView=newRemoteViews(mContext.getPackageName(),
- R.layout.custom_notification);
- mContentView.setImageViewResource(R.id.downLoadIcon,
- android.R.drawable.stat_sys_download);
- mDownPendingIntent=PendingIntent.getActivity(mContext,0,newIntent(),0);
- booleandownSuc=downloadFile(mDownloadUrl,saveFilePath);
- if(downSuc){
- msg.what=MSG_FINISH;
- Notificationnotification=newNotification(
- android.R.drawable.stat_sys_download_done,mContext
- .getString(R.string.downloadSuccess),
- System.currentTimeMillis());
- notification.flags=Notification.FLAG_ONGOING_EVENT;
- notification.flags=Notification.FLAG_AUTO_CANCEL;
- Intentintent=newIntent(Intent.ACTION_VIEW);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.setDataAndType(Uri.fromFile(saveFilePath),
- "application/vnd.android.package-archive");
- PendingIntentcontentIntent=PendingIntent.getActivity(
- mContext,0,intent,0);
- notification.setLatestEventInfo(mContext,mContext
- .getString(R.string.downloadSuccess),null,
- contentIntent);
- mNotifManager.notify(R.drawable.icon,notification);
- }else{
- msg.what=MSG_FAILURE;
- Notificationnotification=newNotification(
- android.R.drawable.stat_sys_download_done,mContext
- .getString(R.string.downloadFailure),
- System.currentTimeMillis());
- notification.flags=Notification.FLAG_AUTO_CANCEL;
- PendingIntentcontentIntent=PendingIntent.getActivity(
- mContext,0,newIntent(),0);
- notification.setLatestEventInfo(mContext,mContext
- .getString(R.string.downloadFailure),null,
- contentIntent);
- mNotifManager.notify(R.drawable.icon,notification);
- }
- }else{
- Toast.makeText(mContext,Environment.getExternalStorageState(),
- Toast.LENGTH_SHORT).show();
- msg.what=MSG_FAILURE;
- }
- }catch(Exceptione){
- Log.e(AhzyFisActivity.TAG,"AppFileDownUtilscatchException:",e);
- msg.what=MSG_FAILURE;
- }finally{
- mHandler.sendMessage(msg);
- }
- }
- /**
- *
- *Desc:文件下载
- *
- *@paramdownloadUrl
- *下载URL
- *@paramsaveFilePath
- *保存文件路径
- *@returnture:下载成功false:下载失败
- */
- publicbooleandownloadFile(StringdownloadUrl,FilesaveFilePath){
- intfileSize=-1;
- intdownFileSize=0;
- booleanresult=false;
- intprogress=0;
- try{
- URLurl=newURL(downloadUrl);
- HttpURLConnectionconn=(HttpURLConnection)url.openConnection();
- if(null==conn){
- returnfalse;
- }
- //读取超时时间毫秒级
- conn.setReadTimeout(10000);
- conn.setRequestMethod("GET");
- conn.setDoInput(true);
- conn.connect();
- if(conn.getResponseCode()==HttpURLConnection.HTTP_OK){
- fileSize=conn.getContentLength();
- InputStreamis=conn.getInputStream();
- FileOutputStreamfos=newFileOutputStream(saveFilePath);
- byte[]buffer=newbyte[1024];
- inti=0;
- inttempProgress=-1;
- while((i=is.read(buffer))!=-1){
- downFileSize=downFileSize+i;
- //下载进度
- progress=(int)(downFileSize*100.0/fileSize);
- fos.write(buffer,0,i);
- synchronized(this){
- if(downFileSize==fileSize){
- //下载完成
- mNotifManager.cancel(R.id.downLoadIcon);
- }elseif(tempProgress!=progress){
- //下载进度发生改变,则发送Message
- mContentView.setTextViewText(R.id.progressPercent,
- progress+"%");
- mContentView.setProgressBar(R.id.downLoadProgress,
- 100,progress,false);
- mDownNotification.contentView=mContentView;
- mDownNotification.contentIntent=mDownPendingIntent;
- mNotifManager.notify(R.id.downLoadIcon,
- mDownNotification);
- tempProgress=progress;
- }
- }
- }
- fos.flush();
- fos.close();
- is.close();
- result=true;
- }else{
- result=false;
- }
- }catch(Exceptione){
- result=false;
- Log.e(AhzyFisActivity.TAG,"downloadFilecatchException:",e);
- }
- returnresult;
- }
- }
在下载过程中,如果需要和主线程(UI Main Thread)通信,及时让主线程了解下载进度和状态,可用通过Handle向主线程发送Message
进度条显示的布局文件如下:
- <?xmlversion="1.0"encoding="utf-8"?>
- <LinearLayout
- android:id="@+id/custom_notification"
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <ImageView
- android:id="@+id/downLoadIcon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="5dip"
- android:layout_gravity="center_vertical"
- />
- <TextView
- android:layout_height="fill_parent"
- android:layout_width="wrap_content"
- android:layout_marginLeft="5dip"
- android:text="@string/downloadProgress"
- android:gravity="center_vertical"
- />
- <ProgressBar
- android:id="@+id/downLoadProgress"
- style="?android:attr/progressBarStyleHorizontal"
- mce_style="?android:attr/progressBarStyleHorizontal"
- android:layout_marginLeft="10dip"
- android:layout_width="150dip"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- />
- <TextView
- android:id="@+id/progressPercent"
- android:layout_height="fill_parent"
- android:layout_width="wrap_content"
- android:layout_marginLeft="5dip"
- android:gravity="center_vertical"
- />
- </LinearLayout>