首页 > 代码库 > Oschina 安卓客户端源码学习之三

Oschina 安卓客户端源码学习之三

今天呢,来研究一个功能,消息通知

(1)首先是消息推送的获得或者说是产生。

在main.java这个文件里有这样一个函数

/**
	 * 轮询通知信息
	 */
	private void foreachUserNotice() {
		final int uid = appContext.getLoginUid();
		final Handler handler = new Handler() {
			public void handleMessage(Message msg) {
				if (msg.what == 1) {
					UIHelper.sendBroadCast(Main.this, (Notice) msg.obj);
				}
				foreachUserNotice();// 回调
			}
		};
		new Thread() {
			public void run() {
				Message msg = new Message();
				try {
					sleep(60 * 1000);
					if (uid > 0) {
						Notice notice = appContext.getUserNotice(uid);
						msg.what = 1;
						msg.obj = notice;
					} else {
						msg.what = 0;
					}
				} catch (AppException e) {
					e.printStackTrace();
					msg.what = -1;
				} catch (Exception e) {
					e.printStackTrace();
					msg.what = -1;
				}
				handler.sendMessage(msg);
			}
		}.start();
	}


这便是简单粗暴的消息取得过程

sleep(60* 1000);

休息一分钟之后appContext.getUserNotice(uid);通过这个函数来取得消息。跟踪该函数代码后得知,它其实是和开源中国的服务器请求了一些数据,然后构造成Notice对象,返回来。然后塞到msg里。最后通过handler.sendMessage(msg);把msg发送出去。而在上面handleMessage里头又调用了foreachUserNotice()这个函数。这就是最终的一个过程,周而复始,一分钟歇一次,歇够了要数据。专业一点叫轮询。

然后我们看这个handleMessage里头有一个sendBroadCast函数,也就是说轮询之后得到的notice最终都是发送广播,发送出去了。

 

(2)接下来,我们来看看广播的接收部分

首先静态注册了一个广播

<receiver android:name=".ui.BroadCast">
            <intent-filter>
                <action android:name="net.oschina.app.action.APPWIDGET_UPDATE"/>
            </intent-filter>
       </receiver>


我们找到ui.BroadCast这个类,下面是对收到的广播的处理方法

@Override
   public void onReceive(Contextcontext, Intent intent) {
      StringACTION_NAME = intent.getAction();
      if("net.oschina.app.action.APPWIDGET_UPDATE".equals(ACTION_NAME))
      { 
          int atmeCount =intent.getIntExtra("atmeCount", 0);//@我
          int msgCount =intent.getIntExtra("msgCount", 0);//留言
          int reviewCount =intent.getIntExtra("reviewCount", 0);//评论
          int newFansCount =intent.getIntExtra("newFansCount", 0);//新粉丝
          int activeCount = atmeCount+ reviewCount + msgCount + newFansCount;//信息总数
         
          //动态-总数
          if(Main.bv_active != null){
             if(activeCount > 0){
                Main.bv_active.setText(activeCount+"");
                Main.bv_active.show();
             }else{
                Main.bv_active.setText("");
                Main.bv_active.hide();
             }
          }
          //@我
          if(Main.bv_atme != null){
             if(atmeCount > 0){
                Main.bv_atme.setText(atmeCount+"");
                Main.bv_atme.show();
             }else{
                Main.bv_atme.setText("");
                Main.bv_atme.hide();
             }
          }
          //评论
          if(Main.bv_review != null){
             if(reviewCount > 0){
                Main.bv_review.setText(reviewCount+"");
                Main.bv_review.show();
             }else{
                Main.bv_review.setText("");
                Main.bv_review.hide();
             }
          }
          //留言
          if(Main.bv_message != null){
             if(msgCount > 0){
                Main.bv_message.setText(msgCount+"");
                Main.bv_message.show();
             }else{
                Main.bv_message.setText("");
                Main.bv_message.hide();
             }
          }
         
          //通知栏显示
          this.notification(context,activeCount);
      }
   }


查看代码得知bv_active等bv开头的变量类型都是BadgeView变量。这个类继承自textView类。实现的功能呢就是一个控件上方一个红色小圆圈,里面有数字。也就是说提示你的新消息条数,这玩意,很常用的哈。具体的就不说了。

这里呢就是把notice的内容拿出来去更新这个控件。这个消息的过程在这就走到终点了。

this.notification这个函数呢,很明显就是手机通知栏的消息通知了

咱们来看看

private voidnotification(Context context, int noticeCount){   
      //创建NotificationManager
      NotificationManagernotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
     
      StringcontentTitle = "开源中国";
      StringcontentText = "您有 " + noticeCount + " 条最新信息";
      int _lastNoticeCount;
     
      //判断是否发出通知信息
      if(noticeCount == 0)
      {
          notificationManager.cancelAll();
          lastNoticeCount= 0;
          return;
      }
      else if(noticeCount == lastNoticeCount)
      {
          return;
      }
      else
      {
          _lastNoticeCount= lastNoticeCount;
          lastNoticeCount= noticeCount;
      }
     
      //创建通知 Notification
      Notificationnotification = null;
     
      if(noticeCount >_lastNoticeCount)
      {
          StringnoticeTitle = "您有 " + (noticeCount-_lastNoticeCount) + " 条最新信息";
         notification= newNotification(R.drawable.icon, noticeTitle, System.currentTimeMillis());
      }
      else
      {
          notification= newNotification();
      }
     
      //设置点击通知跳转
      Intentintent = newIntent(context, Main.class);
      intent.putExtra("NOTICE",true);
   intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
     
     PendingIntentcontentIntent = PendingIntent.getActivity(context, 0, intent,PendingIntent.FLAG_UPDATE_CURRENT);
     
      //设置最新信息
      notification.setLatestEventInfo(context,contentTitle, contentText, contentIntent);
     
      //设置点击清除通知
      notification.flags = Notification.FLAG_AUTO_CANCEL;
     
      if(noticeCount >_lastNoticeCount)
      {
          //设置通知方式
          notification.defaults |= Notification.DEFAULT_LIGHTS;
         
          //设置通知音-根据app设置是否发出提示音
         if(((AppContext)context.getApplicationContext()).isAppSound())
             notification.sound = Uri.parse("android.resource://"+ context.getPackageName() + "/" + R.raw.notificationsound);
         
          //设置振动 <需要加上用户权限android.permission.VIBRATE>
          //notification.vibrate = new long[]{100, 250, 100, 500};
      }
     
      //发出通知
      notificationManager.notify(NOTIFICATION_ID,notification);    
   }


   具体的就不分析了,还是很简单的。

Oschina 安卓客户端源码学习之三