您当前的位置: 首页 > 

Notification使用详解之二:可更新进度的通知

发布时间:2014-04-18 08:50:41 ,浏览量:0

分享一下如何实现一个可更新进度的通知。

我们将会模拟一个下载任务,先启动一个线程负责模拟下载工作,在这个过程中更新进度信息,然后下载线程把最新的进度信息以消息的形式,发送到UI线程的消息队列中,最后UI线程负责根据最新的进度信息来更新进度通知的UI界面。

好,大概就是这个步骤。接下来我们根据具体的实例来演示一下这个过程。

我们新建一个notification项目,然后修改/res/layout/main.xml布局文件,代码如下:

[html] view plain copy print ?
  1. 注意,为了使示例中的Java代码看起来结构更加清晰,我们将按钮的点击事件都定义在布局文件中。

    然后再来看一下MainActivity.java的代码:

    [java] view plain copy print ?
    1. package com.scott.notification;  
    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.Context;  
    8. import android.content.Intent;  
    9. import android.os.Bundle;  
    10. import android.os.Handler;  
    11. import android.os.Message;  
    12. import android.view.View;  
    13. import android.widget.RemoteViews;  
    14.   
    15. public class MainActivity extends Activity {  
    16.   
    17.     private static final int NOTIFY_ID = 0;  
    18.   
    19.     private boolean cancelled;  
    20.   
    21.     private NotificationManager mNotificationManager;  
    22.     private Notification mNotification;  
    23.   
    24.     private Context mContext = this;  
    25.   
    26.     private Handler handler = new Handler() {  
    27.         public void handleMessage(android.os.Message msg) {  
    28.             switch (msg.what) {  
    29.             case 1:  
    30.                 int rate = msg.arg1;  
    31.                 if (rate < 100) {  
    32.                     // 更新进度  
    33.                     RemoteViews contentView = mNotification.contentView;  
    34.                     contentView.setTextViewText(R.id.rate, rate + "%");  
    35.                     contentView.setProgressBar(R.id.progress, 100, rate, false);  
    36.                 } else {  
    37.                     // 下载完毕后变换通知形式  
    38.                     mNotification.flags = Notification.FLAG_AUTO_CANCEL;  
    39.                     mNotification.contentView = null;  
    40.                     Intent intent = new Intent(mContext, FileMgrActivity.class);  
    41.                     PendingIntent contentIntent = PendingIntent.getActivity(mContext, 0, intent, 0);  
    42.                     mNotification.setLatestEventInfo(mContext, "下载完成", "文件已下载完毕", contentIntent);  
    43.                 }  
    44.   
    45.                 // 最后别忘了通知一下,否则不会更新  
    46.                 mNotificationManager.notify(NOTIFY_ID, mNotification);  
    47.                 break;  
    48.             case 0:  
    49.                 // 取消通知  
    50.                 mNotificationManager.cancel(NOTIFY_ID);  
    51.                 break;  
    52.             }  
    53.         };  
    54.     };  
    55.   
    56.     @Override  
    57.     public void onCreate(Bundle savedInstanceState) {  
    58.         super.onCreate(savedInstanceState);  
    59.         setContentView(R.layout.main);  
    60.     }  
    61.   
    62.     public void download(View view) {  
    63.         mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);  
    64.   
    65.         int icon = R.drawable.down;  
    66.         CharSequence tickerText = "开始下载";  
    67.         long when = System.currentTimeMillis();  
    68.         mNotification = new Notification(icon, tickerText, when);  
    69.   
    70.         // 放置在"正在运行"栏目中  
    71.         mNotification.flags = Notification.FLAG_ONGOING_EVENT;  
    72.   
    73.         RemoteViews contentView = new RemoteViews(mContext.getPackageName(), R.layout.download_notification_layout);  
    74.         contentView.setTextViewText(R.id.fileName, "AngryBird.apk");  
    75.         // 指定个性化视图  
    76.         mNotification.contentView = contentView;  
    77.   
    78.         // intent为null,表示点击通知时不跳转  
    79.         PendingIntent contentIntent = PendingIntent.getActivity(mContext, 0, null, 0);  
    80.         // 指定内容意图  
    81.         mNotification.contentIntent = contentIntent;  
    82.   
    83.         mNotificationManager.notify(NOTIFY_ID, mNotification);  
    84.   
    85.         new Thread() {  
    86.             public void run() {  
    87.                 startDownload();  
    88.             };  
    89.         }.start();  
    90.     }  
    91.   
    92.     public void cancel(View view) {  
    93.         cancelled = true;  
    94.     }  
    95.   
    96.     private void startDownload() {  
    97.         cancelled = false;  
    98.         int rate = 0;  
    99.         while (!cancelled && rate < 100) {  
    100.             try {  
    101.                 // 模拟下载进度  
    102.                 Thread.sleep(500);  
    103.                 rate = rate + 5;  
    104.             } catch (InterruptedException e) {  
    105.                 e.printStackTrace();  
    106.             }  
    107.             Message msg = handler.obtainMessage();  
    108.             msg.what = 1;  
    109.             msg.arg1 = rate;  
    110.             handler.sendMessage(msg);  
    111.         }  
    112.         if (cancelled) {  
    113.             Message msg = handler.obtainMessage();  
    114.             msg.what = 0;  
    115.             handler.sendMessage(msg);  
    116.         }  
    117.     }  
    118. }  
    package com.scott.notification;
    
    import android.app.Activity;
    import android.app.Notification;
    import android.app.NotificationManager;
    import android.app.PendingIntent;
    import android.content.Context;
    import android.content.Intent;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.view.View;
    import android.widget.RemoteViews;
    
    public class MainActivity extends Activity {
    
    	private static final int NOTIFY_ID = 0;
    
    	private boolean cancelled;
    
    	private NotificationManager mNotificationManager;
    	private Notification mNotification;
    
    	private Context mContext = this;
    
    	private Handler handler = new Handler() {
    		public void handleMessage(android.os.Message msg) {
    			switch (msg.what) {
    			case 1:
    				int rate = msg.arg1;
    				if (rate < 100) {
    					// 更新进度
    					RemoteViews contentView = mNotification.contentView;
    					contentView.setTextViewText(R.id.rate, rate + "%");
    					contentView.setProgressBar(R.id.progress, 100, rate, false);
    				} else {
    					// 下载完毕后变换通知形式
    					mNotification.flags = Notification.FLAG_AUTO_CANCEL;
    					mNotification.contentView = null;
    					Intent intent = new Intent(mContext, FileMgrActivity.class);
    					PendingIntent contentIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
    					mNotification.setLatestEventInfo(mContext, "下载完成", "文件已下载完毕", contentIntent);
    				}
    
    				// 最后别忘了通知一下,否则不会更新
    				mNotificationManager.notify(NOTIFY_ID, mNotification);
    				break;
    			case 0:
    				// 取消通知
    				mNotificationManager.cancel(NOTIFY_ID);
    				break;
    			}
    		};
    	};
    
    	@Override
    	public void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.main);
    	}
    
    	public void download(View view) {
    		mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    
    		int icon = R.drawable.down;
    		CharSequence tickerText = "开始下载";
    		long when = System.currentTimeMillis();
    		mNotification = new Notification(icon, tickerText, when);
    
    		// 放置在"正在运行"栏目中
    		mNotification.flags = Notification.FLAG_ONGOING_EVENT;
    
    		RemoteViews contentView = new RemoteViews(mContext.getPackageName(), R.layout.download_notification_layout);
    		contentView.setTextViewText(R.id.fileName, "AngryBird.apk");
    		// 指定个性化视图
    		mNotification.contentView = contentView;
    
    		// intent为null,表示点击通知时不跳转
    		PendingIntent contentIntent = PendingIntent.getActivity(mContext, 0, null, 0);
    		// 指定内容意图
    		mNotification.contentIntent = contentIntent;
    
    		mNotificationManager.notify(NOTIFY_ID, mNotification);
    
    		new Thread() {
    			public void run() {
    				startDownload();
    			};
    		}.start();
    	}
    
    	public void cancel(View view) {
    		cancelled = true;
    	}
    
    	private void startDownload() {
    		cancelled = false;
    		int rate = 0;
    		while (!cancelled && rate < 100) {
    			try {
    				// 模拟下载进度
    				Thread.sleep(500);
    				rate = rate + 5;
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    			Message msg = handler.obtainMessage();
    			msg.what = 1;
    			msg.arg1 = rate;
    			handler.sendMessage(msg);
    		}
    		if (cancelled) {
    			Message msg = handler.obtainMessage();
    			msg.what = 0;
    			handler.sendMessage(msg);
    		}
    	}
    }

    值得注意的是,在控制下载线程时使用了cancelled这个boolean值标志变量,对于线程的控制更好一些,不建议使用Thread.interrupt()去中断一个线程。另外,对于更新通知的UI界面时,要记住调用NotificationManager.notify(int id, Notification notification)方法通知一下,否则即使设置了新值,也不会起作用的。

    程序中用到的带进度的通知布局/res/layout/download_notification_layout.xml布局文件代码如下:

    [html] view plain copy print ?
    1. 该通知的布局使用了相对布局,更加灵活易用,所以推荐大家多使用相对布局。

      对于MainActivity.java中涉及到的FileMgrActivity,它是一个简单的界面,这里就不在介绍了,that's not the point。

      最后我们跑一下程序,看看效果如何:

      貌似还不错,好了,今天先到这里,下次再找机会分享。

关注
打赏
1688896170
查看更多评论

暂无认证

  • 0浏览

    0关注

    111426博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.0857s