Android实现Service后台下载Notification进度条

原文网址:http://www.obatu.com/android-service-download-notification-progressbar/

 

 最近的项目中,有一个需求是 【后台下载+多线程+Notificaton进度条】的应用。要求有一个Service做下载服务,Notification中显示一进度条,进度条由Service来更新。
花了个把小时在网上找代码,没有一个完美的方案,最后根据片段信息,自己实现了。贴出来分享一下。

思路:

  • 1. 有一个提供队列下载的Service
  • 2. 该Service可以绑定,绑定的时候返回本身实例
  • 3. 该Service提供方法给绑定了该Service的Activity,Activity可以调用Service的提供的方法,给Service添加队列
  • 4. 该Service提供了当前下载队列的信息,信息包括下载的名称,下载进度,Activity通过接口读取队列信息用于操作,如:取消


实现:

1. 队列类


  
  
  1. public class DownLoadQueue{
  2.  
  3.     public int id; //队列id , 该id标识了一条下载线程和Notification
  4.  
  5.     public String name; // 队列名称,用于显示在Notification中
  6.  
  7.      public int progress = 0; //进度,一个0-100之前的整数,标识百分比
  8.  
  9.      public boolean isCancel = fale; //是否已经取消,该开关用于取消下载
  10.  

2. Service类:


  
  
  1.   public class DownloadService extends Service{
  2.  
  3.            private Map downLoadQueue ; //下载队列,格式:
  4.  
  5.              private Binder serviceBinder = new DownLoadServiceBinder();
  6.  
  7.                // Activity绑定后,会自动条用这个方法
  8.                @Override
  9.                public IBinder onBind(Intent intent)
  10.                {
  11.                     Log.d("DownloadService", "onBind");
  12.                     return serviceBinder;
  13.                }
  14.  
  15.                ....
  16.  
  17.                private void startDownLoad(DownLoadQueue queue){
  18.                     new Thread(){
  19.                          public void run(){
  20.                               //进行下载工作,这里需要更新downLoadQueue中对应的queue的进度信息
  21.                               //使用Handler更新notification信息
  22.                               ....
  23.                          }
  24.  
  25.                     }.start();
  26.                }
  27.  
  28.                public void addQueue(DownLoadQueue queue){
  29.                     this.downLoadQueue.add(queue.id,queue);
  30.                     this.startDownLoad(queue);
  31.                }
  32.  
  33.                public Map getQueueList () {
  34.                     return this.downLoadQueue;
  35.                }
  36.  
  37.              public class public DownLoadServiceBinder extends Binder{
  38.                   public DownloadService getService(){
  39.                          return DownloadService.this;
  40.                     }
  41.              }

3. Activity类:


  
  
  1. public class DownLoadActivity{
  2.           private Handler handler = new Handler();
  3.           private DownloadService downLoadService;
  4.           private ServiceConnection serviceConnection = new ServiceConnection()
  5.           {
  6.                // 连接服务失败后,该方法被调用
  7.                @Override
  8.                public void onServiceDisconnected(ComponentName name)
  9.                {
  10.                     downLoadService = null;
  11.                     Toast.makeText(DownLoadActivity.this, "Service Failed.", Toast.LENGTH_LONG).show();
  12.                }
  13.                // 成功连接服务后,该方法被调用。在该方法中可以获得downLoadService对象
  14.                @Override
  15.                public void onServiceConnected(ComponentName name, IBinder service)
  16.                {
  17.                     // 获得downLoadService对象
  18.                     downLoadService = ((DownLoadService.DownLoadServiceBinder) service).getService();
  19.                     Toast.makeText(DownLoadActivity.this, "Service Connected.", Toast.LENGTH_LONG).show();
  20.                }
  21.           };
  22.  
  23.           @Override
  24.           public void onCreate(Bundle savedInstanceState){
  25.                super.onCreate(savedInstanceState);
  26.                Intent serviceIntent = new Intent(DownLoadActivity.this,DownloadService.class);
  27.                bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
  28.                startService(serviceIntent);
  29.                .....
  30.           }
  31.  
  32.           private void startDownLoad(){
  33.                DownLoadQueue queue = new DownLoadQueue();
  34.                queue.id = 1;
  35.                queue.name = "愤怒的小鸟"
  36.                ...
  37.                downLoadService.addDownLoad(queue);
  38.                ....
  39.           }
  40.  
  41.           @Override
  42.           public void onDestroy(){
  43.                super.onDestroy();
  44.                unbindService(new Intent(DownLoadActivity.this,DownloadService.class));
  45.           }

4. 在Service中更新Notification时,不能过于频繁,否则会造成卡机。notification使用RemoteView来自定义Notification,加入进度条加入各种说明文字,等等。

以上文字只是简单的提及了一些思路。在项目中已经实现。下次修改完善后贴上来分享。希望能够将该功能做成一个独立的Service供大家在项目中嵌入使用。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
实现Android应用程序中下载文件并同时显示进度条,可以使用Android DownloadManager类。 DownloadManager是Android系统提供的一个下载管理器,它可以轻松地执行文件下载,并且可以方便地显示进度条。 以下是实现此功能的步骤: 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(); } } ```
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值