分享

android通知栏进度条

 软件团队头目 2012-10-25

android通知栏进度条

分类: android 2595人阅读 评论(3) 收藏 举报

项目中需要用到通知栏进度条,查找了好多资料、链接如下:

  1. Android 为Notification加上一个进度条
  2. Android实现Service后台下载Notification进度条
  3. Notification使用详解之三:通过服务更新进度通知&在Activity中监听服务进度
  4. android service startService bindService
  5. Android中BindService方式使用的理解
  6. [Android 机制] 大家帮忙看一下这个BUG.
  7. Android 的service的定义可以 作为内部类使用吗?

我先简后难写了两种实现,第一个没有使用服务,activity转向后台进度条消失;另一个使用服务,activity转向后台进度条仍然继续。


以下是第一个实现:

主界面布局代码 notify.xml

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas./apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="vertical" >  
  6.   
  7.     <Button  
  8.         android:id="@+id/button1"  
  9.         android:layout_width="wrap_content"  
  10.         android:layout_height="wrap_content"  
  11.         android:text="开始" />  
  12.   
  13. </LinearLayout>  
通知栏内容布局代码 notify_content.xml

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas./apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent" >  
  5.   
  6.   
  7.     <ProgressBar  
  8.         android:id="@+id/progressBar1"  
  9.         style="?android:attr/progressBarStyleHorizontal"  
  10.         android:layout_width="wrap_content"  
  11.         android:layout_height="wrap_content"  
  12.         android:layout_alignParentRight="true"  
  13.         android:layout_alignParentTop="true"  
  14.         android:layout_marginTop="14dp"  
  15.         android:layout_toRightOf="@+id/imageView1" />  
  16.   
  17.     <TextView  
  18.         android:id="@+id/textView1"  
  19.         android:layout_width="wrap_content"  
  20.         android:layout_height="wrap_content"  
  21.         android:layout_alignParentRight="true"  
  22.         android:layout_below="@+id/progressBar1"  
  23.         android:layout_marginRight="26dp"/>  
  24.   
  25.     <ImageView  
  26.         android:id="@+id/imageView1"  
  27.         android:layout_width="wrap_content"  
  28.         android:layout_height="wrap_content"  
  29.         android:layout_alignBottom="@+id/textView1"  
  30.         android:layout_alignParentLeft="true"  
  31.         android:src="@drawable/ic_launcher" />  
  32.   
  33. </RelativeLayout>  
AndroidManifest.xml 代码添加如下:

  1. <activity  
  2.     android:label="@string/app_name"  
  3.     android:name=".notify.NotificationActivity1" >  
  4.     <intent-filter >  
  5.         <action android:name="android.intent.action.MAIN" />  
  6.   
  7.         <category android:name="android.intent.category.LAUNCHER" />  
  8.     </intent-filter>  
  9. </activity>  
主程序NotificationActivity1.java代码如下:

  1. package com.zhang.new_test.notify;  
  2.   
  3. import android.app.Activity;  
  4. import android.app.Notification;  
  5. import android.app.NotificationManager;  
  6. import android.app.PendingIntent;  
  7. import android.content.Intent;  
  8. import android.os.Bundle;  
  9. import android.os.Handler;  
  10. import android.os.Message;  
  11. import android.view.View;  
  12. import android.view.View.OnClickListener;  
  13. import android.widget.Button;  
  14. import android.widget.RemoteViews;  
  15. import android.widget.Toast;  
  16.   
  17. import com.zhang.new_test.R;  
  18.   
  19. public class NotificationActivity1 extends Activity implements OnClickListener {  
  20.   
  21.     private static final int NOTIFICATION_ID = 0x12;  
  22.     private Notification notification = null;  
  23.     private NotificationManager manager = null;  
  24.     private int _progress = 0;  
  25.     private boolean isStop = false;  
  26.   
  27.     @Override  
  28.     protected void onPause() {  
  29.         isStop = false;  
  30.         manager.cancel(NOTIFICATION_ID);  
  31.   
  32.         super.onPause();  
  33.     }  
  34.   
  35.     @Override  
  36.     public void onCreate(Bundle savedInstanceState) {  
  37.         super.onCreate(savedInstanceState);  
  38.         setContentView(R.layout.notify);  
  39.   
  40.         Button btn = (Button) findViewById(R.id.button1);  
  41.         btn.setOnClickListener(this);  
  42.         notification = new Notification(R.drawable.sg, "带进条的提醒", System.currentTimeMillis());  
  43.   
  44.         notification.contentView = new RemoteViews(getApplication().getPackageName(), R.layout.notify_content);  
  45.         notification.contentView.setProgressBar(R.id.progressBar1, 1000false);  
  46.         notification.contentView.setTextViewText(R.id.textView1, "进度" + _progress + "%");  
  47.           
  48.         notification.contentIntent = PendingIntent.getActivity(this0,new Intent(this, NotificationActivity1.class), 0);  
  49.         
  50.         manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);  
  51.   
  52.     }  
  53.       
  54.     @Override  
  55.     public void onClick(View v) {  
  56.         isStop = true;  
  57.         manager.notify(NOTIFICATION_ID, notification);  
  58.         new ProgressThread().start();  
  59.     }  
  60.       
  61.     private class ProgressThread extends Thread {  
  62.   
  63.         @Override  
  64.         public void run() {  
  65.             while (isStop) {  
  66.                 _progress += 10;  
  67.                 Message msg = handler.obtainMessage();  
  68.                 msg.arg1 = _progress;  
  69.                 msg.sendToTarget();  
  70.   
  71.                 try {  
  72.                     Thread.sleep(500);  
  73.                 } catch (InterruptedException e) {  
  74.                     e.printStackTrace();  
  75.                 }  
  76.             }  
  77.         }  
  78.     }  
  79.       
  80.     public Handler handler = new Handler() {  
  81.         @Override  
  82.         public void handleMessage(Message msg) {  
  83.             notification.contentView.setProgressBar(R.id.progressBar1, 100, msg.arg1, false);  
  84.             notification.contentView.setTextViewText(R.id.textView1, "进度" + msg.arg1 + "%");  
  85.             manager.notify(NOTIFICATION_ID, notification);  
  86.   
  87.             if (msg.arg1 == 100) {  
  88.                 _progress = 0;  
  89.                 manager.cancel(NOTIFICATION_ID);  
  90.                 isStop = false;  
  91.                 Toast.makeText(NotificationActivity1.this"下载完毕"1000).show();  
  92.             }  
  93.         }  
  94.     };  
  95. }  

以下是第二个实现:

主界面布局代码 notify.xml和通知栏内容布局代码 notify_content.xml同上一个实现

AndroidManifest.xml 代码添加如下:

  1. <activity  
  2.     android:label="@string/app_name"  
  3.     android:name=".notify.NotificationActivity2" >  
  4.     <intent-filter >  
  5.         <action android:name="android.intent.action.MAIN" />  
  6.   
  7.         <category android:name="android.intent.category.LAUNCHER" />  
  8.     </intent-filter>  
  9. </activity>  
  10.   
  11. <service android:name=".notify.NotificationActivity2$DownLoadService"/>  
主程序NotificationActivity2.java代码如下:
  1. package com.zhang.new_test.notify;  
  2.   
  3. import android.app.Activity;  
  4. import android.app.Notification;  
  5. import android.app.NotificationManager;  
  6. import android.app.PendingIntent;  
  7. import android.app.Service;  
  8. import android.content.ComponentName;  
  9. import android.content.Context;  
  10. import android.content.Intent;  
  11. import android.content.ServiceConnection;  
  12. import android.os.Binder;  
  13. import android.os.Bundle;  
  14. import android.os.Handler;  
  15. import android.os.IBinder;  
  16. import android.os.Message;  
  17. import android.view.View;  
  18. import android.view.View.OnClickListener;  
  19. import android.widget.Button;  
  20. import android.widget.RemoteViews;  
  21. import android.widget.Toast;  
  22.   
  23. import com.zhang.new_test.R;  
  24.   
  25. public class NotificationActivity2 extends Activity implements OnClickListener {  
  26.       
  27.     private DownLoadService downLoadService;  
  28.       
  29.     @Override  
  30.     public void onCreate(Bundle savedInstanceState) {  
  31.         super.onCreate(savedInstanceState);  
  32.         setContentView(R.layout.notify);  
  33.           
  34.         Button btn = (Button) findViewById(R.id.button1);  
  35.         btn.setOnClickListener(this);  
  36.     }  
  37.       
  38.     @Override  
  39.     protected void onResume() {  
  40.         super.onResume();  
  41.           
  42.         Intent serviceIntent = new Intent(this,DownLoadService.class);  
  43.         startService(serviceIntent);//  
  44.         bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE);  
  45.     }  
  46.       
  47.     @Override  
  48.     protected void onPause() {  
  49.         super.onPause();  
  50.           
  51.         unbindService(serviceConnection);  
  52.     }  
  53.       
  54.     @Override  
  55.     public void onClick(View v) {  
  56.         downLoadService.startDownLoad();  
  57.     }  
  58.       
  59.     private ServiceConnection serviceConnection = new ServiceConnection() {  
  60.           
  61.         @Override  
  62.         public void onServiceConnected(ComponentName name, IBinder service){  
  63.             downLoadService = ((DownLoadService.DownLoadServiceBinder) service).getService();  
  64.             Toast.makeText(NotificationActivity2.this"Service Connected.", Toast.LENGTH_LONG).show();  
  65.         }  
  66.           
  67.         @Override  
  68.         public void onServiceDisconnected(ComponentName name) {  
  69.         }  
  70.     };  
  71.       
  72.     public static class DownLoadService extends Service {  
  73.   
  74.         private static final int NOTIFICATION_ID = 0x12;  
  75.         private Notification notification = null;  
  76.         private NotificationManager manager = null;  
  77.         private int _progress = 0;  
  78.         private boolean isStop = false;  
  79.           
  80.         private Binder serviceBinder = new DownLoadServiceBinder();  
  81.   
  82.         @Override  
  83.         public void onCreate() {  
  84.             super.onCreate();  
  85.               
  86.             notification = new Notification(R.drawable.sg, "带进条的提醒", System.currentTimeMillis());  
  87.   
  88.             notification.contentView = new RemoteViews(getApplication().getPackageName(), R.layout.notify_content);  
  89.             notification.contentView.setProgressBar(R.id.progressBar1, 1000false);  
  90.             notification.contentView.setTextViewText(R.id.textView1, "进度" + _progress + "%");  
  91.               
  92.             notification.contentIntent = PendingIntent.getActivity(this0,new Intent(this, NotificationActivity1.class), 0);  
  93.             
  94.             manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);  
  95.         }  
  96.           
  97.         @Override  
  98.         public IBinder onBind(Intent intent) {  
  99.             return serviceBinder;  
  100.         }  
  101.   
  102.         @Override  
  103.         public void onDestroy() {  
  104.             isStop = false;  
  105.             manager.cancel(NOTIFICATION_ID);  
  106.               
  107.             super.onDestroy();  
  108.         }  
  109.           
  110.         public void startDownLoad() {  
  111.             isStop = true;  
  112.             manager.notify(NOTIFICATION_ID, notification);  
  113.             new ProgressThread().start();  
  114.         }  
  115.   
  116.         public class DownLoadServiceBinder extends Binder {  
  117.             public DownLoadService getService() {  
  118.                 return DownLoadService.this;  
  119.             }  
  120.         }  
  121.           
  122.         private class ProgressThread extends Thread {  
  123.   
  124.             @Override  
  125.             public void run() {  
  126.                 while (isStop) {  
  127.                     _progress += 10;  
  128.                     Message msg = handler.obtainMessage();  
  129.                     msg.arg1 = _progress;  
  130.                     msg.sendToTarget();  
  131.   
  132.                     try {  
  133.                         Thread.sleep(1000);  
  134.                     } catch (InterruptedException e) {  
  135.                         e.printStackTrace();  
  136.                     }  
  137.                 }  
  138.             }  
  139.         }  
  140.           
  141.         public Handler handler = new Handler() {  
  142.             @Override  
  143.             public void handleMessage(Message msg) {  
  144.                 notification.contentView.setProgressBar(R.id.progressBar1, 100, msg.arg1, false);  
  145.                 notification.contentView.setTextViewText(R.id.textView1, "进度" + msg.arg1 + "%");  
  146.                 manager.notify(NOTIFICATION_ID, notification);  
  147.   
  148.                 if (msg.arg1 == 100) {  
  149.                     _progress = 0;  
  150.                     manager.cancel(NOTIFICATION_ID);  
  151.                     isStop = false;  
  152.                     Toast.makeText(DownLoadService.this"下载完毕"1000).show();  
  153.                 }  
  154.             }  
  155.         };  
  156.     }  
  157. }  
效果我就不贴图了,前面提到的链接中有,效果差不多。

接下来分析一下代码,第二个和第一个最大区别是引入了service,这样可以支持后台运行,所以第二个更有实用性。但是刚开始写代码,不应该引入服务,那样会带来过多的复杂度,出bug时很难调试,写完第一个在重构引入服务就没那么麻烦了,大部分代码可以复用的。

主要知识点就是Notification和bindService的使用,我主要遇到两个悲剧,和大家分享一下:

  1. 忘了unbindService,抛了一个不知道的异常,链接6解决了
  2. .notify.NotificationActivity2$DownLoadService 我写成了 .notify.NotificationActivity2.DownLoadService,链接7解决了,这个花了半天时间,我就不相信这个会错,主要是因为写代码时new 静态内部类时都是用 . 啊,忘了配置是用的反射,所以应该用 $ 啊,主要是以前没写过静态内部类的反射,记住教训了。
希望这篇博文对大家有帮助。

1
0

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多