【IT168 技术】从事Symbian开发工作也有几个年头了,一直想总结一下开发过程中遇到的问题以及解决技巧,但是总是有这样那样的理由不愿花时间去总结,今天天气不错,心情也挺好,摆出一副专家的气势伏案工作,翻出这几年的工作笔记,打开除了上班时间懒得去碰的电脑,开始了自己的总结大会。
问题一、如何枚举出正在运行的App
结合RApaLsSession和TApaTaskList应该可以做到.
RApaLsSession:
GetAppIcon()
GetAppInfo()
TApaTaskList:
FindApp()
问题二、从收件箱读取彩信图片
mmslist实现了首先以listbox列表的形式列出了收件箱中的所有彩信,选择某一条彩信后可以显示出它的发送端号码和彩信的文本信息;现在我想让它显示发送端号码和彩信图片(假设我的彩信都是图片格式);请教两位应该怎么才能实现读彩信图片并显示的功能。
下面是读彩信文本信息的代码,你们参考一下:
void CMmslController::GetMessageL( const TDesC& aItem,
TDes& aMessageText ) const
{
//Read the message Uid from aItem
TUint32 id = 0;
TLex lexer( aItem );
lexer.SkipSpace();
TChar ch( lexer.Get() );
while ( ( ch != ‘\t’ ) && ( ch != 0 ) ) // Finding end of 1.st line
{
ch = lexer.Get();
}
lexer.SkipSpace();
lexer.Val( id, EHex );
if( iCurEntries->Find( id ) == KErrNotFound )
{
return;
}
CMsvEntry* msvEntry = iSession->GetEntryL( id );
CleanupStack::PushL( msvEntry );
const TMsvEntry& msgEntry = msvEntry->Entry();
CBaseMtm* clientMtm = iMtmReg->NewMtmL( msgEntry.iMtm );
CleanupStack::PushL( clientMtm );
clientMtm->SwitchCurrentEntryL( msvEntry->EntryId() );
// An instance of the TDesOverflow derived class used to suppress
// the panic that would be generated if buffer length was exceeded
// in calls to AppendFormat
TOverrideOverFlow noOflo;
// Text is located in iDescription field.
aMessageText.AppendFormat( msgEntry.iDescription, &noOflo );
//aMessageText.AppendFormat( msgEntry.iDetails );
CleanupStack::PopAndDestroy( 2 ); // clientMtm, msvEntry
}
问题三、如何让程序在安装后自动运行
如何让一个程序(或是一个server)在安装后自动运行于手机中,这是非常容易的,只需在你的PKG文件中,在包含你的app或exe文件的那行末尾加上“FR,RI”。
“FR”表示“File Run”,而“RI”则表示“Run during Installation”。请注意,务必要先开始rsc,aif,mbm文件的安装,然后才能是APP等(也就是在pkg文件的末尾进行app的安装)
举例:
“\Symbian.1\Series60\Epoc32\release\thumb\urel\MyApp.rsc” -
“!:\system\apps\MyApp\MyApp.rsc”
“\Symbian.1\Series60\Epoc32\release\thumb\urel\MyApp_caption.rsc” -
“!:\system\apps\MyApp\MyApp_caption.rsc”
“\Symbian.1\Series60\Epoc32\release\thumb\urel\MyApp.aif” -
“!:\system\apps\MyApp\MyApp.aif”
“\Symbian.1\Series60\Epoc32\release\thumb\urel\MyApp.app” -
“!:\system\apps\MyApp\MyApp.app”,FR,RI
问题四、全面了解文件类型和从属关系
下图显示了在一个典型的Symbian程序中各文件的从属关系。
[attach]457[/attach]
.hrh文件中包含所有要在.rss、.h和.cpp中使用的枚举类型。它们主要使用在应用程序的菜单、工具栏等地方,下面展示了一个典型的例子:
//MyApp.hrh
//
enum{
EMyAppCmdOpenFile = 0×6000,
EMyAppCmdEdit,
};
按照惯例这些命令ID值的范围应该从0×6000开始向上。
.rss文件中是资源文件,这些文件包括所有静态字符串、按钮、菜单和列表等的定义,都使用在应用程序UI中。此外,Nokia Series 60向导还可能生成一个.loc文件,这个文件同.rss文件很相似但只用于描述你程序中的静态字符串,利用它你可以很容易的将程序变成多语言版本。
.rsg是生成的资源文件。它们是在编译时刻由资源编译器产生的,.cpp文件将包含它们以便处理资源。
.mbm是symbian位图文件,它里面可以存储几个位图。
.mbg是在创建.mbm时生成的。这些文件一般包含在那些使用位图的RSS文件中,一个mbg文件包括在.mbm中各位图的ID。
问题五、如何在网络通讯中正确显示中文
1。经过对照GB2312/GBK编码表,在程序中定义_LIT8(KTest, “中文测试”);是GB2312/GBK编码
2。直接从输入框取出的字符串,经过按照byte分析并比较中文和unicode对照表,发现是UTF-16LE(Sixteen-bit UCS Transformation Format, little-endian byte order)编码
3,中文对服务器的传输建议统一处理成UTF8编码进行,从对话框获得的也一样处理,服务器需要对应识别过来的字符串并做处理。
问题六、如何动态更改CEikLabel 的text
CEikLabel* iLabelStatus;
…..
iLabelStatus = new (ELeave) CEikLabel;
iLabelStatus->SetContainerWindowL( *this );
iLabelStatus->SetTextL( this->iStatusStr );
….
//动态在这里更改
iLabelStatus->SetTextL(iStatusStr);
iLabelStatus->DrawNow();
如果初始化时就无法显示,请对照helloworld代码检查自己label是否设置正确;如果是进度进行中无法显示,请检查CActive是否正确执行,单步DrawNow是否被正确调用。
问题七、在listbox中怎么处理所选项的事件
触发事件并不是很复杂的事情,
TKeyResponse CXXContainer::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType)
{
TInt code = aKeyEvent.iCode;
switch(code)
{
// is navigator button pressed导航按钮被按下时
case EKeyOK:
{
// pass the key press event to view,
// then view will pass it to ui class’s handler
iXXView->ProcessListEvent(iListBox->CurrentItemIndex()) ;
}
return (EKeyWasConsumed);
case EKeyLeftArrow :
case EKeyRightArrow :
return (EKeyWasConsumed);
default:
// Let Listbox take care of its key handling
return iListBox->OfferKeyEventL(aKeyEvent, aType) ;
}
}
这个iXXView的ProcessListEvent()函数就是传入当前用户选择的那个list item的index。
问题八、pkg文件中指定多个操作系统版本
pkg file定义了安装文件(sis)的内容,它包括应用程序的UID,一个支持的语言列表,目标产品的UID和打包在sis的一组文件:
; MyGame.pkg
; Specifies an installation file for MyGame ///////为MyGame文件制定一个安装文件
;Languages
&EN
;Header
#,(0×1000ABCD),1,0,0
; Required line for Series 60 devices. Defines the target product
; UID.
(0×101F6F88), 0, 0, 0,
“\epoc32\release\thumb\urel\MyGame.app”-“!:\system\apps\MyGame\MyGame.app”
“\epoc32\release\thumb\urel\MyGame.rsc”-“!:\system\apps\MyGame\MyGame.rsc”
“\epoc32\release\thumb\urel\MyGame.mbm”-“!:\system\apps\MyGame\MyGame.mbm”
“\epoc32\release\thumb\urel\MyGame.aif”-“!:\system\apps\MyGame\MyGame.aif”
“..\MyGame\MyGameSample.wav”-“!:\system\apps\MyGame\MyGameSample.wav”
Product UID定义了应用程序的目标环境,大部分的s60版本是向下兼容的。
参见下表:
Nokia 7650 0×101F6F87
Nokia 3650 0×101F7962
Nokia 9210/9290 0×10005E33
Nokia N-gage 0×101F8A64
Siemens SX1 0×101F9071
Series 60 Platform v0.9 0×101F6F88
Series 60 Platform v1.0 0×101F795F
Series 60 Platform v1.1 0×101F8201
Series 60 Platform v1.2 0×101F8202
Series 60 Platform v2.0 0×101F7960
如果程序需要依据各不同的平台来进行安装,那就可以使用条件语句块来处理,这时pkg里的语句如下:
;
; Files to install
;
IF MachineUID=0×101fb3dd
; Nokia 6600 specific files
“..\MyFiles\FileFor6600.dat”-“!:\system\apps\MyGame\MyData.dat”
ELSEIF MachineUID=0×101f466a
; Nokia 3650 specific files
“..\MyFiles\FileFor3650.dat”-“!:\system\apps\MyGame\MyData.dat”
ELSE
; Files for other devices
“..\MyFiles\FileForOthers.dat”-“!:\system\apps\MyGame\MyData.dat”
ENDIF
就可以生成一个支持多平台的安装文件,除了机器UID外,还有很多属性,如内存和CPU的标识:
注意,机器UID和Product UID是不同的,见下:
Nokia 7650 0×101F4FC3
Nokia 3650 0×101F466A
Nokia 6600 0×101FB3DD
Nokia 9210/9290 0×10005E33
Nokia N-Gage 0×101F8C19
Win32 Emulator 0×10005F62
可以使用如下的代码来找出该设备的机器UID:
#include //and link with hal.lib
TInt machineUid = 0;
HAL::Get(HALData::EmachineUid, machineUid);
问题九、如何按字节读取文件
1.RFile::Read()
TInt Read(TDes8& aDes,TInt aLength) const;
Description
Reads specified number of bytes of binary data from file — synchronous overload.
2.Typedef TText8
typedef unsigned char TText8;
问题十、如何取出Symbian手机中的信息
方法有两个:
1 确定出他们的路径,用文件的方式读;
2 用系统给这两个部分提供的API
通讯录方面的(别人的代码网上找的):
_LIT(KNameLabel,”Name”);
_LIT(KMobileLabel,”Mobile”);
_LIT(KName,”Steve”);
_LIT(KMobile,”+8613900000000″);
// Open the default contacts database:
CContactDatabase* contactsDb = CContactDatabase::OpenL();
CleanupStack::PushL(contactsDb);
// Create a contact card and add some fields:
CContactItem* contact = CContactCard::NewLC();
CContactItemField* field = CContactItemField::NewLC(KStorageTypeText, KUidContactFieldFamilyName);
field->SetMapping(KUidContactFieldVCardMapUnusedN);
field->SetLabelL(KNameLabel);
field->TextStorage()->SetTextL(KName);
contact->AddFieldL(*field);
CleanupStack::Pop();
field = CContactItemField::NewLC(KStorageTypeText, KUidContactFieldPhoneNumber);
field->SetMapping(KUidContactFieldVCardMapTEL);
field->SetLabelL(KMobileLabel);
field->TextStorage()->SetTextL(KMobile);
contact->AddFieldL(*field);
CleanupStack::Pop();
// Add the new contact to the database and set it as the own card:
contactsDb->AddNewContactL(*contact);
contactsDb->SetOwnCardL(*contact);
CleanupStack::PopAndDestroy(2); // contact contactsDb
短信的:
CMsvEntry或 CMsvServerEntry