摘要
本文介绍了BREW短消息的另一种用途,用户可以通过发送一条基于BREW的特定格式的短信,来启动手机的某一个BREW应用。BREW应用开发商可以采用本文提供的方法可以灵活地实现各种对BREW应用程序的远程启动功能;例如新闻订阅、通知、提醒,天气预报提示等等。
关键字 BREW, SMS, 短消息,ITAPI
BREW特定短信的发送和接收过程的底层实现机制
BREW定义了一种特定的短消息格式来启动应用程序。BREW把这种格式的短消息称为BREW特定应用消息(BREW application-directed message),即这种特殊的短消息是发送给某一个特定的BREW应用程序的。为方便起见,以下文中我们统称之为BREW短信,以区别普通短信。
BREW短信的格式如下:
//BREW:<Class ID>:<Text Payload>
其中:
//BREW——消息头,表示本短信为BREW短信;
Class ID——表示接收短信的应用程序的Class ID 号;
Text Payload——附加的消息文本,ASCII格式;
例如:
//BREW:01009FF0:test
//BREW:0x01009FF0:Hello world
BREW短信的发送非常简单。和发送普通短信一样,调用ITAPI_SendSMS()函数发送就可以了。例如:
ITAPI_SendSMS(pMe->m_pITAPI,”13331016512”,”//BREW:0x01009FF0:Hello world”, 0, (PFNSMSSTATUS)MySmsNotify, pMe);
BREW短信的接收过程如下:
1. BREW手机的底层软件首先截获短消息,判断消息头是否为 //BREW;
2. 如果判断是BREW短信,则启动BREW应用管理器;
3. BREW应用管理器根据收到的Class ID加载对应的BREW应用程序,并完成该应用程序的初始化工作;
4. BREW应用管理器发送EVT_APP_MESSAGE事件给应用程序;
5. 应用程序的HandleEvent()函数处理EVT_APP_MESSAGE事件,如果需要启动应用,则调用ISHELL_StartApplet()函数来启动;或者也可以“悄悄地”进行处理而不用启动应用程序。
通过以上的描述我们知道,BREW应用管理器是通过发送EVT_APP_MESSAGE来唤醒应用程序的,所以应用程序必须处理EVT_APP_MESSAGE才能接收BREW短信,才能完成程序的启动。具体例子如下:
……
case EVT_APP_MESSAGE:
//start up applet
ISHELL_StartApplet(pMe->a.m_pIShell,
AEECLSID_HELLOWORLD);
return TRUE;
……
注意:代码中的 return TRUE 语句是必须要加上的。
如果应用程序想得到BREW短信的文本信息,可以通过EVT_APP_MESSAGE事件的dwParam参数来得到。即参数dwParm的内容实际上是指向Text Payload消息体的指针。具体例子如下:
case EVT_APP_MESSAGE:
{
char* textPayload = (char *)dwParam;
return TRUE;
}
如何在BREW短信中发送和接收中文
为简单起见,前面都是以发送英文ASCII字符为例子的,其实BREW短信也可以发送/接收中文字符,只是步骤上比发送英文复杂一些。
我们知道,中文短消息需要用UNCODE码格式,但是BREW短信的消息头必须用ASCII码发送(包括Class ID),即字符串 //BREW:<Class ID>: 须用英文发送才能被BREW的底层软件正确识别,如果是UNICODE字符,会被认作是普通短消息而不会启动相应的应用程序。这就产生了一个矛盾:如果用ASCII码,则无法发送中文;如果用UNICODE码,则会被认作普通短消息。
解决办法是采用拼接的办法“骗过”BREW底层。即BREW短消息的消息头部分采用ASCII码,后段的消息体部分采用UNICODE码,把这两段拼起来发送出去就可以了。具体步骤如下:
1. 定义变量wStrMessage, 类型为(AECHAR*),指向一段UNICODE字符串的缓冲区;
2. 定义变量BrewHeader存储BREW短信的消息头字符串,这里假设为 //BREW:0x01009FF0:。将这段ASCII字符串拷贝到wStrMessage缓冲区的开始段。可以用STRNCPY函数来完成拷贝,例子如下:
STRNCPY( (char *)(wStrMessage), BrewHeader, STRLEN(BrewHeader) );
3. 在wStringMessage缓冲区中,紧接着BREW短消息头的后面,将中文字符串ChineseTextMsg拷贝过来;
例如:WSTRCPY(&(wstrMessage[STRLEN(BrewHeader)/2]),
ChineseTextMsg);
4. 调用ITAPI_SendSMS()函数发送,注意UNICODE字符串wStrMessage要强制转换成(const char*),这是ITAPI_SendSMS()函数要求的。
经过以上的处理,在要发送的UNICODE字符串的前面实际上是包含了BREW消息头的ASCII字符,所以能被BREW底层正确识别,而BREW底层对其后面的数据不作任何处理。
在接收方处理中文短信很简单,EVT_APP_MESSAGE事件的dwParam变成了指向UNICODE字符串的指针,只要把该段的数据拷贝过来即可。例子如下:
case EVT_APP_MESSAGE:
{
WSTRCPY( (AECHAR*)wTextPayload, (AECHAR*)dwParam);
return TRUE;
}
采用上述方法,即可以发送中文,也可以发送中英文混排的字符串。我们在几款手机上测试通过。需要注意的是由于中文短信最多是70个,扣除掉BREW短信头,大约还能够发送60个中文字符。
用BREW短信开发应用程序的几种解决方案
开法商可以BREW短信功能可以根据不同的需求灵活地实现各种应用,这里我们提供几种方案,以供参考:
1. 在短信中直接传送消息。如果在用户的数据量不大的情况下,是最简单实用的方法。缺点是当数据量变大时,不适用;
2. 在短信中传送应用程序的启动参数。和命令行参数类似,通过发送不同的参数来执行程序的不同分枝。可以用ISHELL_StartAppletArgs()函数来实现。
具体例子如下:
case EVT_APP_MESSAGE:
{
char * lpszMsg = (char *)dwParam;
ISHELL_StartAppletArgs(pme->a.m_pIShell, AEECLSID_TAPIAPP, lpszMsg);
}
return TRUE;
应用程序可以分成不同种情况,参数1执行A情况,2执行B情况,3执行C情况。。。以此类推。
3. 在短信中传送一个网站的URL地址,应用程序收到短信后可以自动连接网站。
例如:
case EVT_APP_MESSAGE:
const char * url = (const char *)dwParam;
if(url && !STRNICMP(url,”http”,4))
ISHELL_BrowseURL(pme->a.m_pIShell, url);
return(TRUE);
总之,对BREW短信的消息体,开发者可以做任意地解释,开发者可以根据自己的特点加以灵活地运用。
几点说明
有以下几点需要注意:
也可以发送普通短信的方式来发送BREW短信,只要数据格式正确,在任何一台能发短信的手机上都可以发送。但是由于短信格式必须是ASCII,所以要先把 手机的语言设置成英文再发送;在中文环境下即使输入英文,发送的实际上也是UNICODE码,在接收方BREW手机的底层软件也会无法识别,从而无法启动 应用程序;
如果BREW短信的消息头格式错误,则该短信会被手机的短消息信箱接收到。
如果BREW短信的消息头格式正确,但是Class ID错误或者接收方手机中无此应用程序,该短消息会丢弃不用,而不会传到手机的普通短消息信箱中,也不产生任何形式的提示信息。
接收方的应用程序无需在MIF文件中作notification, ITAPI等选项设置。
参考资料
1. BREW 2.0 API Reference
2. BREW 2.0 SDK User’s Guide
3. Handling SMS in BREW", BREW Online Knowledge base, Document ID 52, http://www.qualcomm.com/brew/developer/resources/ds/kb/52.html