Android通知栏实现APP下载更新(DownloadManager和自定义Notification2种方式实现)

        在Android开发应用中,我们经常会遇到软件自动下载更新功能,最简单的方法先采用HttpClient去下载apk资源,在下载的过程中我们通过计算来算出下载的进度,然后我们可以使用Dialog+ProgressBar去显示下载进度。这种实现方式有很多不完美之处,首先在Dialog+ProgressBar去实现,下载的过程中我们无法进行其他的操作,得停留在这个页面,用户体验不太好,其次,在下载的过程中会遇到很多异常需要我们自己去处理,比较麻烦,如果再要自己实现断点下载的功能,那就比较头痛了。下面来介绍2种我自己在项目开发中整理出来的比较好用的方法,第一种是采用Xutil(Github一款比较好用的框架,主要功能有数据库封装,网络请求,图片处理,注解)+自定义Notification,第2种是利用系统提供的DownloadManager去实现。

       先说第一种,它主要是主要是通过Xutil框架封装好的文件下载请求框架去实现的,然后通过自定义Notification去显示相关下载信息,贴上图和相应代码:

[java]  view plain  copy
  1. package com.example.download;  
  2.   
  3. import java.io.File;  
  4.   
  5. import android.app.Notification;  
  6. import android.app.NotificationManager;  
  7. import android.content.Context;  
  8. import android.content.Intent;  
  9. import android.net.Uri;  
  10. import android.os.Environment;  
  11. import android.widget.RemoteViews;  
  12.   
  13. import com.lidroid.xutils.HttpUtils;  
  14. import com.lidroid.xutils.exception.HttpException;  
  15. import com.lidroid.xutils.http.ResponseInfo;  
  16. import com.lidroid.xutils.http.callback.RequestCallBack;  
  17.   
  18. public class HttpConnectService {  
  19.     private static final int NOTIFY_ID = 0;  
  20.     private NotificationManager mNotificationManager;  
  21.     private Notification mNotification;  
  22.   
  23.     // 下载地址  
  24.     private String apkUrl = "http://dldir1.qq.com/dlomg/weishi/weishi_guanwang.apk";  
  25.   
  26.     // 下载包安装路径  
  27.     private static final String savePath = Environment.getExternalStorageDirectory().getAbsolutePath()+"/weishi.apk";  
  28.       
  29.     public void connectDownLoad(final Context context,final String packageName) {  
  30.         mNotificationManager = (NotificationManager) context.getSystemService(android.content.Context.NOTIFICATION_SERVICE);  
  31.         HttpUtils http = new HttpUtils();  
  32.         http.configTimeout(30000);  
  33.         http.configSoTimeout(30000);  
  34.         http.download(apkUrl,savePath, falsefalse,  
  35.                 new RequestCallBack<File>() {  
  36.   
  37.                     @Override  
  38.                     public void onStart() {   
  39.                        setUpNotification(packageName,context);  
  40.                     }  
  41.   
  42.                     @Override  
  43.                     public void onLoading(long total,long current,boolean isUploading) {     
  44.                         int progress = (int) (current * 100/total);  
  45.                         RemoteViews contentview = mNotification.contentView;  
  46.                         contentview.setTextViewText(R.id.tv_progress, progress + "%");  
  47.                         contentview.setProgressBar(R.id.progressbar, 100, progress, false);  
  48.                         mNotificationManager.notify(NOTIFY_ID, mNotification);  
  49.                     }  
  50.   
  51.                     @Override  
  52.                     public void onSuccess(ResponseInfo<File> responseInfo) {  
  53.                         mNotificationManager.cancel(NOTIFY_ID);  
  54.                         installAPK(responseInfo.result, context);  
  55.                     }  
  56.   
  57.                     @Override  
  58.                     public void onFailure(HttpException error, String msg) {  
  59.                         RemoteViews contentview = mNotification.contentView;  
  60.                         contentview.setTextViewText(R.id.tv_progress,"下载失败");  
  61.                         contentview.setProgressBar(R.id.progressbar, 100,0false);  
  62.                         mNotificationManager.notify(NOTIFY_ID, mNotification);  
  63.                     }  
  64.                 });  
  65.     }  
  66.   
  67.       
  68.     /** 
  69.      * 创建通知 
  70.      */  
  71.     @SuppressWarnings("deprecation")  
  72.     private void setUpNotification(String packageName,Context context) {  
  73.         mNotification = new Notification(R.drawable.weishi, "正在下载",  System.currentTimeMillis());  
  74.         mNotification.flags = Notification.FLAG_ONGOING_EVENT;  
  75.         RemoteViews contentView = new RemoteViews(packageName, R.layout.download_notification_layout);  
  76.         mNotification.contentView = contentView;  
  77.         mNotificationManager.notify(NOTIFY_ID, mNotification);  
  78.     }  
  79.       
  80.     //安装APK  
  81.     private void installAPK(File t,Context context) {  
  82.         Intent intent = new Intent();  
  83.         intent.setAction("android.intent.action.VIEW");  
  84.         intent.addCategory("android.intent.category.DEFAULT");  
  85.         intent.setDataAndType(Uri.fromFile(t),"application/vnd.android.package-archive");  
  86.         context.startActivity(intent);  
  87.     }  
  88.       
  89. }  

      主要功能实现在connectDownLoad方法里面,在这个方法里面我们重写了4个方法,分别是onStart(),onLoading(),onSuccess(),onFailure(),对应下载的4种情况,即下载开始,下载进行时,下载完成,下载失败,下载开始时创建一个自定义的Notification,我们将自定义的布局的内容写在R.layout.download_notification_layout布局文件里面,在loading方法里面系统提供了3个参数,我们使用其中的2个参数,total代表文件总大小,current代表已经下载了多少,通过int progress = (int) (current * 100/total)我们就可以计算出下载进度,然后我们通过mNotificationManager.notify(NOTIFY_ID, mNotification)去刷新Notification内容显示,然后我们在onsuccess和onFailure方法里面处理相应的情况,下载成功时我们弹出安装页面,提示用户进行安装,失败时也给出相关提示。

      下面来讲第二种实现方式,就是利用Android系统的DownloadManager 去实现的,个人觉得比较方便实用,它可以检测下载速度,显示下载进度,文件大小,断点下载等强大功能,下载过程中他会自动检测网络状态,网络断开时停止下载,连接上时自动接着下载,还可以设置成只有在wifi下面才进行下载,下面直接贴出效果图和相应代码,代码里面关键代码都写了注释,比较简单。


[java]  view plain  copy
  1. package com.example.download;  
  2.   
  3. import android.annotation.SuppressLint;  
  4. import android.app.Activity;  
  5. import android.app.DownloadManager;  
  6. import android.app.DownloadManager.Query;  
  7. import android.app.DownloadManager.Request;  
  8. import android.database.Cursor;  
  9. import android.net.Uri;  
  10. import android.os.Bundle;  
  11. import android.view.View;  
  12. import android.view.View.OnClickListener;  
  13. import android.widget.Button;  
  14.   
  15. @SuppressLint("NewApi")  
  16. public class MainActivity extends Activity  implements OnClickListener{  
  17.       
  18.     static final String DOWNLOAD_FILE_NAME = "weishi.apk";  
  19.     private DownloadManager manager ;  
  20.     private Button downBtn1 ;  
  21.     private Button downBtn2 ;  
  22.     private long downloadId;  
  23.     @Override  
  24.     public void onCreate(Bundle savedInstanceState) {  
  25.         super.onCreate(savedInstanceState);  
  26.         setContentView(R.layout.activity_main);  
  27.         manager =(DownloadManager)getSystemService(DOWNLOAD_SERVICE);  
  28.         downBtn1 = (Button)findViewById(R.id.downBtn1);  
  29.         downBtn1.setOnClickListener(this);   
  30.         downBtn2 = (Button)findViewById(R.id.downBtn2);  
  31.         downBtn2.setOnClickListener(this);   
  32.     }  
  33.       
  34.     @Override  
  35.     public void onClick(View v) {     
  36.         switch (v.getId()) {  
  37.             case R.id.downBtn1:  
  38.                 Query query = new Query();  
  39.                 query.setFilterById(downloadId);  
  40.                 query.setFilterByStatus(DownloadManager.STATUS_RUNNING);//正在下载        
  41.                 Cursor c = manager.query(query);  
  42.                 if(c.moveToNext()){  
  43.                     //正在下载中,不重新下载  
  44.                 }else{  
  45.                     //创建下载请求  
  46.                     DownloadManager.Request down=new DownloadManager.Request (Uri.parse("http://dldir1.qq.com/dlomg/weishi/weishi_guanwang.apk"));  
  47.                     //设置允许使用的网络类型,这里是移动网络和wifi都可以  
  48.                     down.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE|DownloadManager.Request.NETWORK_WIFI);  
  49.                     //显示在下载界面,即下载后的文件在系统下载管理里显示  
  50.                     down.setVisibleInDownloadsUi(true);  
  51.                     //设置下载标题        
  52.                     down.setTitle("微视");  
  53.                     //显示Notification  
  54.                     down.setNotificationVisibility(Request.VISIBILITY_VISIBLE);  
  55.                     //设置下载后文件存放的位置,在SDCard/Android/data/你的应用的包名/files/目录下面  
  56.                     down.setDestinationInExternalFilesDir(thisnull,DOWNLOAD_FILE_NAME);  
  57.                     //将下载请求放入队列,返回值为downloadId  
  58.                     downloadId = manager.enqueue(down);  
  59.                 }          
  60.                 break;  
  61.       
  62.             case R.id.downBtn2:  
  63.                  HttpConnectService hcs = new HttpConnectService();  
  64.                  hcs.connectDownLoad(this, getPackageName());  
  65.                  break;  
  66.         }  
  67.     }  
  68. }  

           然后我们在AndroidManifest.xml配置文件里面去注册一个广播,监听下载完成的动作,这里不建议这Activity里面动态注册广播,因为这样activity销毁时广播会被销毁我们就无法接受到下载完成的广播了。

          

[java]  view plain  copy
  1. package com.example.download;  
  2.   
  3. import java.io.File;  
  4.   
  5. import android.annotation.SuppressLint;  
  6. import android.app.DownloadManager;  
  7. import android.app.DownloadManager.Query;  
  8. import android.content.BroadcastReceiver;  
  9. import android.content.Context;  
  10. import android.content.Intent;  
  11. import android.database.Cursor;  
  12. import android.net.Uri;  
  13.   
  14. @SuppressLint("NewApi")  
  15. public class DownloadCompleteReceiver extends BroadcastReceiver {  
  16.     private DownloadManager manager ;  
  17.     @Override  
  18.     public void onReceive(Context context, Intent intent) {  
  19.         manager =(DownloadManager)context.getSystemService(Context.DOWNLOAD_SERVICE);  
  20.         if(intent.getAction().equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)){  
  21.             //通过downloadId去查询下载的文件名  
  22.             long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);  
  23.             Query query = new Query();    
  24.             query.setFilterById(downloadId);         
  25.             Cursor myDownload = manager.query(query);    
  26.             if (myDownload.moveToFirst()) {    
  27.               int fileNameIdx = myDownload.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME);    
  28.               String fileName = myDownload.getString(fileNameIdx);    
  29.               installAPK(fileName,context);  
  30.             }  
  31.         }  
  32.     }  
  33.       
  34.     //安装APK  
  35.     private void installAPK(String  filePath,Context context) {  
  36.         Intent intent = new Intent();  
  37.         intent.setAction("android.intent.action.VIEW");  
  38.         intent.addCategory("android.intent.category.DEFAULT");  
  39.         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//广播里面操作需要加上这句,存在于一个独立的栈里  
  40.         intent.setDataAndType(Uri.fromFile(new File(filePath)),"application/vnd.android.package-archive");  
  41.         context.startActivity(intent);  
  42.     }  

  1. }  

  2. 转自:http://blog.csdn.net/wcbcslg/article/details/46364453

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
实现Android应用程序下载文件并同时显示进度条,可以使用Android DownloadManager类。 DownloadManagerAndroid系统提供的一个下载管理器,它可以轻松地执行文件下载,并且可以方便地显示进度条。 以下是实现此功能的步骤: 1. 添加权限 在AndroidManifest.xml文件添加以下权限: ``` <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" /> ``` 2. 创建DownloadManager请求 创建一个DownloadManager.Request对象,设置下载请求的URL、下载文件的名称和类型。 ``` DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); request.setTitle("下载文件"); request.setDescription("正在下载"); request.setMimeType("application/pdf"); request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "file.pdf"); ``` 3. 获取DownloadManager实例 获取DownloadManager实例,并将DownloadManager.Request对象传递给enqueue()方法。 ``` DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); long downloadId = manager.enqueue(request); ``` 4. 显示进度条 使用一个ProgressDialog对象来显示下载进度条,通过查询DownloadManager的状态来更新进度条的值。 ``` ProgressDialog progressDialog = new ProgressDialog(MainActivity.this); progressDialog.setMessage("正在下载"); progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); progressDialog.setCancelable(true); progressDialog.show(); new Thread(new Runnable() { @Override public void run() { boolean downloading = true; while (downloading) { DownloadManager.Query q = new DownloadManager.Query(); q.setFilterById(downloadId); Cursor cursor = manager.query(q); cursor.moveToFirst(); int bytesDownloaded = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)); int bytesTotal = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)); if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_SUCCESSFUL) { downloading = false; } final int dl_progress = (int) ((bytesDownloaded * 100l) / bytesTotal); runOnUiThread(new Runnable() { @Override public void run() { progressDialog.setProgress(dl_progress); } }); cursor.close(); } } }).start(); ``` 在以上代码,我们启动一个新线程来查询下载进度,并使用runOnUiThread()方法更新ProgressDialog对象的进度条。 完整代码示例: ``` public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); String url = "http://www.example.com/file.pdf"; DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); request.setTitle("下载文件"); request.setDescription("正在下载"); request.setMimeType("application/pdf"); request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "file.pdf"); DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); long downloadId = manager.enqueue(request); ProgressDialog progressDialog = new ProgressDialog(MainActivity.this); progressDialog.setMessage("正在下载"); progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); progressDialog.setCancelable(true); progressDialog.show(); new Thread(new Runnable() { @Override public void run() { boolean downloading = true; while (downloading) { DownloadManager.Query q = new DownloadManager.Query(); q.setFilterById(downloadId); Cursor cursor = manager.query(q); cursor.moveToFirst(); int bytesDownloaded = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)); int bytesTotal = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)); if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_SUCCESSFUL) { downloading = false; } final int dl_progress = (int) ((bytesDownloaded * 100l) / bytesTotal); runOnUiThread(new Runnable() { @Override public void run() { progressDialog.setProgress(dl_progress); } }); cursor.close(); } } }).start(); } } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值