您现在的位置: 中国IT实验室 >> 移动设备开发 >> PLAM >> 文章正文
Palm OS上发送和接收通知(Chinese)

ChinaITLab 收集整理  2005-3-6  保存本文  推荐给好友  QQ上看本站  收藏本站



  通知是一个Palm OS 3.5以及之后版本所具有的功能;系统发送通知给相关的应用程序来通报某个事件已经发生了或者正在发生。
  
  Answer
  通知是一个Palm OS 3.5以及之后版本所具有的功能;系统发送通知给相关的应用程序来通报某个事件已经发生了或者正在发生。
  
  应用程序也可发送通知。有关发送通知的资料,请参见下面的发送通知的部分。
  
  接收通知
  出于效率考虑,你的应用程序只须注册那些你想得到的通知。你可以在Palm OS Programmer's API Reference文档或者头文件 NotifyMgr.h中找到现有的通知列表。
  
  不同的应用程序应该在不同的情况下注册通知:
  
  有时你只想在应用程序运行时得到通知。例如,你想知道一个扩展卡已经插入扩展槽或者已经从扩展槽中拔出,从而更新你的显示。
  
  有时甚至当用户没有运行你的应用程序时,你也总想得到通知。在这种情况下,你应该在获得sysAppLaunchCmdSystemReset 启动码时注册通知,并且永不取消注册。(如果用户删除了你的应用程序,你将会自动取消所有通知的注册。)
  
  下面的例子将介绍当系统被唤醒和进入休眠状态时(也就是当打开和关闭设备时)如何接收通知。例如,这些通知可以用作跟踪设备的使用情况或者监视电池消耗状况。
  
  你必须按以下操作来注册和使用通知:
  
  在你的PilotMain函数中,添加对RegisterForNotifications和HandleNotification的调用;
  创建RegisterForNotifications函数;
  
  创建HandleNotification函数;
  测试通知代码。
  在PilotMain函数中添加代码
  在你判断应用程序是否是以sysAppLaunchCmdNormalLaunch启动码启动的同样的地方,在PilotMain函数的启动码switch声明中添加以下代码:
  case sysAppLaunchCmdSystemReset:
  case sysAppLaunchCmdSyncNotify: // 应用程序安装后发送
  RegisterForNotifications();
  break;
  case sysAppLaunchCmdNotify:
  HandleNotification((SysNotifyParamType *)cmdPBP);
  break;
  
  在PilotMain函数中添加完以上代码后,每次系统重启和通过HotSync程序(当你已经通过调试器安装了应用程序或者直接拖放应用程序到Palm OS模拟器中,就不需要HotSync了)安装你的应用程序时,都会调用RegisterForNotifications函数。
  
  在系统重启时注册通知要特别小心。如果在你处理系统重启时出现代码错误(例如访问全局变量),则会导致Palm OS崩溃并强迫系统再次重启,从而会进入一个死循环当中。 很多用户不知道如何进行无通知重启,所以他们会删除你的应用程序。
  
  创建RegisterForNotifications函数
  static void RegisterForNotifications()
  {
  UInt16 cardNo;
  LocalID dbID;
  
  if (0 != SysCurAppDatabase(&cardNo, &dbID))
  return; // 应该不会失败,以防万一
  
  // 告诉系统我们想知道设备何时休眠和被唤醒
  SysNotifyRegister(cardNo, dbID, sysNotifySleepNotifyEvent, NULL,sysNotifyNormalPriority, 0);
  SysNotifyRegister(cardNo, dbID, sysNotifyLateWakeupEvent, NULL, sysNotifyNormalPriority, 0);
  }
  
  添加完RegisterForNotification函数之后,每次系统休眠和被唤醒时都会调用HandleNotification函数。注意 SysNotifyRegister函数的第四个参数允许你传递一个将要处理通知的回调函数的指针。如果传递NULL作为回调函数的指针,那么系统将会发送sysAppLaunchCmdNotify启动码给你的应用程序(在上面我们已经在PilotMain函数中添加了处理代码)。通常,使用启动码比较简单,但是如果你知道你的应用程序处于激活状态或者正在写一个共享库,你可能会想要使用回调函数。
  
  创建HandleNotification函数
  
  你在HandleNotification函数中想要做什么,这完全取决于你自己。但是为了示范的目的,我们将跟踪设备休眠的时间长度(根据上次进入休眠的时刻)。
  
  #define kWhenWeWentToSleepFtr 1 // 程序局部变量定义
  #define kLastSleepLengthFtr  2 // 在应用程序别的地方读取
  
  static void HandleNotification(SysNotifyParamType *np)
  {
  UInt32 timeAsleep;
  
  if (np->notifyType == sysNotifySleepNotifyEvent)
  FtrSet(appFileCreator, kWhenWeWentToSleepFtr, TimGetSeconds());
  else if (np->notifyType == sysNotifyLateWakeupEvent) {
  FtrGet(appFileCreator, kWhenWeWentToSleepFtr, &timeAsleep);
  FtrSet(appFileCreator, kLastSleepLengthFtr, TimGetSeconds() - timeAsleep);
  }
  }
  
  测试通知代码
  现在为了验证通知代码是否正常运作, 在你的主窗体事件处理函数当中添加以下代码。这些代码将会显示系统休眠的时间长度(通过读取范例HandleNotification函数中设置的feature内存来获得)。
  
  case frmOpenEvent: {
  char buffer[80];
  UInt32 sleepTime;
  
  frmP = FrmGetActiveForm();
  MainFormInit(frmP);
  FrmDrawForm(frmP);
  
  // 简单地绘制在窗体内容区的顶部。(只是示范而已)
  FtrGet(appFileCreator, kLastSleepLengthFtr, &sleepTime);
  StrPrintF(buffer, "Last sleep time: %ld seconds.", sleepTime);
  WinDrawChars(buffer, StrLen(buffer), 0, 16);
  
  handled = true;
  break;
  }
  
  发送通知
  广播一个通知来通报其它应用程序(或者你自己的应用程序)发生了某件值得注意的事情是很容易实现的。如果没有应用程序注册你发送的通知,尽管系统做出判断需要花些时间,但是SysNotifyBroadcast函数的调用仍然会迅速地返回。
  
  你可以调用SysNotifyBroadcast函数来快速地发送一个通知。在这种情况下,你将要等待直到每一个接收者处理完这个通知。
  或者你可以调用SysNotifyBroadcastDeferred函数来发送一个延期的通知。在这种情况下,这个通知会稍后发送(一般来说,“稍后”意味着下一次调用EvtGetEvent函数时)。
  以下代码介绍如何发送一个通知。
  
  // 必须是一个已注册的Creator ID;使用你的应用程序或者其它的到
  http://spp.palmos.com/iws/creator/creatorRegistration.jsp注册一个新的Creator ID。
  
  #define myInterestingEvent 'MyEv'
  
  SysNotifyParamType notify;
  
  notify.notifyType   = myInterestingEvent;
  
  // 表明是谁发送的事件
  notify.broadcaster  = appFileCreator;
  notify.handled    = false;
  // 或者任何你需要发送的附件信息
  notify.notifyDetailsP = NULL;
  
  //或者使用SysNotifyBroadcastDeferred
  SysNotifyBroadcast(notify);
  
  如果你调用的是SysNotifyBroadcastDeferred函数并且有一个notifyDetailsP指向的结构,可以选择让 SysNotifyBroadcastDeferred函数复制你的结构,这样你就不必再考虑何时释放这个结构, 从而简化了内存管理。你可以通过传递一个非零值作为SysNotifyBroadcastDeferred函数的第二个参数来实现这种办法。然后S ysNotifyBroadcastDeferred函数会根据指定的大小分配一块新的内存区,从复制notifyDetailsP指向的结构复制所有的数据,让notifyDetailsP指向自己的内存区。所有的接收者处理完通知之后,SysNotifyBroadcastDeferred函数将释放这个内存区。通过使用这种方法,你可以立即释放notifyDetailsP(或者曾让它指向一个局部变量)指向的内存区,而不必考虑去确保在每一个接收者已经被通报或者内存溢出之前notifyDetailsP指针是正确的。




 相关文章  热门文章
Palm Powered设备上的增强型音频
编写Palm J2ME红外线“聊天”程序
PALM开发教程-…
PALM开发教程-…
PALM开发教程-…
PALM开发教程-…
PALM开发教程-…
PALM开发教程-…
Palm OS上常用编&…
Palm OS上如何利&…

 文章评论


认证培训
热门专题       more
相关下载
论坛新帖
博 客