RApaLsSession apaLsSession; const TUid KOSSBrowserUidValue = {0x1020724D}; HBufC* param = HBufC::NewLC(64); param->Des().Copy(_L("4 http://www.yahoo.com/")); TUid id(KOSSBrowserUidValue); TApaTaskList taskList(CEikonEnv::Static()->WsSession()); TApaTask task = taskList.FindApp(id); if(task.Exists()) { task.BringToForeground(); HBufC8* param8 = HBufC8::NewLC(param->Length()); param8->Des().Append(*param); task.SendMessage(TUid::Uid(0), *param8); // UID not used CleanupStack::PopAndDestroy(param8); } else { if(!apaLsSession.Handle()) { User::LeaveIfError(apaLsSession.Connect()); } TThreadId thread; User::LeaveIfError(apaLsSession.StartDocument(*param, KOSSBrowserUidValue, thread)); apaLsSession.Close(); } CleanupStack::PopAndDestroy(param);
注意:如果浏览器正在加载一个URL,而另一个程序试图去打开它。那就会在加载新的url时报“Unable to retrieve”错误。
RHostResolver和选择接入点对话框重复显示的问题
案例重现:
连接socket server(RSocketServ),打开一个RConnection示例:
iSocketServer.Connect();
iConnection.Open(iSocketServer);
这样就开始了一个internet连接:
iConnection.Start();
这时会出现一个选择接入点对话框,要选择一个适当的访问接入点。
在连接已经建立后,使用RHostResolver打开一个DNS resolver session,并开始尝试解析一个主机名:
iResolver.Open(iSocketServer, KAfInet, KProtocolInetUdp);
iResolver.GetByName(someHost, iResult);
这时选择接入点对话框会会再次出现。
解决方案:
传递当前RConnection示例到host resolver中:
iResolver.Open(iSocketServer, KAfInet, KProtocolInetUdp, iConnection);
自签名程序的UID
详细描述:
S60第三版对所有安装程序引进了强制签名机制。如果一个应用程序没有capabilites属性或仅使用了开放给所有人的capabilites属性,它可以生成一个新证书,并用它来签名。所有的免费程序都
可以这样处理。
更多关于自签名证书的信息可通过查看SDK帮助获取:Introduction to S60 3rd Edition >> How to Sign .sis Files.
使用自签名证书意味着该程序被看做不可信任的,不可信任的程序应该使用unprotected range of UIDs下的唯一标识。否则安装在第三版设备上将会导致失败。
Protected UID range: 0x00000000 … 0x7FFFFFFF
Unprotected UID range: 0x80000000 … 0xFFFFFFFF
特别要指出的是,有两组重要的未保护UID范围:
UIDs for self-signed app. releases: 0xA0000000 … 0xAFFFFFFF
UIDs for test/development use: 0xE0000000 … 0xEFFFFFFF
UID的分配是由symbian公司来管理的,要获得更多相关方面的信息请参考http://www.symbiansigned.com
自定义CMdaAudioInputStream的buffer大小
详细描述:
对S60 MMF客户端音频程序来说,处理S60设备中输入流时,是否可以自定义buffer的大小。
解决方案:
在S60 MMF架构中缺省的声音I/O数据buffer大小是根据声音硬件和音频编码性能来分配的。使用CMdaAudioInputStream的客户端程序将考虑到下列局限:
但使用PCM16(缺省)格式时:
声音设备返回的input buffer总是320个字节(S60第二版,FP2和FP3)或4096字节(S60第三版)。这也是调用CMdaAudioInputStream::ReadL()所能返回最大数据长度,因此不建议超过此限度大小。
如果传递到客户端ReadL()中的buffer小于该大小,那服务端buffer就会被组成适合大小的块以便传入。如果这样操作后还有剩余,就不会满足这里最大长度大小。例如,当在S60第三版中使用一个
3840字节的buffer大小时,第一个返回的buffer为3840字节,而下一个就是(4096-3840)256字节,然后再这样重复继续。
当使用非PCM格式处理流时:
对一个压缩音频格式,每个返回的input buffer都典型的包括一个音频数据的单独帧。例如,当使用AMR-NB格式时(在MaiscOpenComplete()方法):
iInputStream->SetDataTypeL(KMMFFourCCCodeAMR);
调用后,每次返回buffer将包括14个字节(一个单独的AMR-NB frame in ,5.15 kbit/s)可演绎20ms of audio data;
CVideoPlayerUtility::SetRotationL()崩溃或错误现象
说明:
调用CVideoPlayerUtility中的SetRotationL()方法会产生错误结果,甚至导致设备重启。
创建日期: February 23, 2006
详细描述:
使用 CVideoPlayerUtility::SetRotationL(TVideoRotation aRotation)时,将参数aRotation设置为EVideoRotationClockwise180 或EVideoRotationClockwise270,这样可能导致设备重启或旋转后的画面扭曲难看。
如果参数为EVideoRotationClockwise90 那将没有这方面的问题。
解决方案:
在CVideoPlayerUtility中使用90度顺时针方面。在7-11-2005后的版本中已经修正了这个问题。
在\private目录下存储应用程序图片文件
详细描述:
如果图片文件aFileName存放在一个受保护目录下,如\private\
void CreateIconL( CFbsBitmap *&aBitmap,
CFbsBitmap *&aMask,
const TDesC &aFileName,
TInt aBitmapId,
TInt aMaskId )
这是因为Avkon icon server无法访问存放在保护目录下的文件。
案例重现:
在这种情况下AknIconUtils::CreateIconL()不会引发异常,不管怎么说,aBitmap和aMask参数将不会指向有效位图。如果尝试使用返回的位图将会引发错误异常。
例如,尝试使用AknIconUtils::SetSize()设置位图大小时会引发error -46(KErrPermissionDenied)
解决方案:
不要将文件名传递到CAknIconUtils,程序应当完成max-in类MAknIconFileProvider,以便提供一个打开的文件句柄给Avkon icon server.
CAknIconUtils有一个可供重载的CreateIconL()方法以便接收一个MAknIconFileProvider示例。
这里提供一个完成MAknIconFileProvider 类的示例,请S60 Platform: Scalable Screen-Drawing Example, 可在http://www.forum.nokia.com/下载
注意:包含应用程序图标的.mbm和.mif文件(会在LOCALISABLE_APP_INFO资源定义中被引用)应该永远安装在\resource\apps\.目录下。
当使用MMS MTM发送一个彩信时引发“message-format-corrupt”
详细描述:
是使用MMS Client MTM中的方法发送一个自定义的MMS信息时,我被提示“message-format-corrupt”错误,请问这是什么原因?
这是一个发生在网络上的错误,得到这样错误的原因说明你的信息中某部分没能被网络接受。一个网络操作对信息的要求十分严格。
因此你的程序在某些网络下可能工作很好,但在另一些情况下就会被拒绝。
解决方案:
你需要仔细检查程序设置的所有附加信息头内容。将他们设置正确,以便目标网络接受这些内容。
SIS包和本地化资源文件
详细描述:
概况:
当使用本地化资源文件为程序添加了多语言支持后,下面一个步骤就是将他们加入.pkg文件,并生成SIS包。
有两个方法来完成这个任务:
将资源打包在.pkg文件时,可选择语言相关方式也可以选择语言无关方式。
语言无关文件:
下列文件都别拷贝到目标机器上,而不管其语言设置或用户选择。
"MyApp.r01" - "!:\system\apps\MyApp\MyApp.r01" ; 01=English
"MyApp.r02" - "!:\system\apps\MyApp\MyApp.r02" ; 02=French
"MyApp.r03" - "!:\system\apps\MyApp\MyApp.r03" ; 03=German
; etc (see TLanguage in e32std.h for all lang. enumerations)
由程序框架根据当前语言设置决定,在程序运行时载入哪种语言。将所有资源文件都拷贝在设备将增长内存消耗,但另一个方面,程序也能支持设备当前语言(可能需要重启后才能更改语言设置)
语言相关文件:
设计一个文件列表,只能根据用户在安装时选的语言来安装一个。文件的顺序和个数必须和.pkg文件中语言行指定的一致:
{ "MyApp.r01",
"MyApp.r02",
"MyApp.r03" } - "!:\system\apps\MyApp\MyApp.rsc"
因为只有一个本地化资源文件能被拷贝,程序将不支持设备上的语言设置,改变程序的语言将需要重新安装一次。
总结:
我们在选择何种方法时应该着重考虑所有本地化资源文件加在一起的大小,以及程序是否要去支持设备上的语言设置更改。
在S60第三版SIS文件中指定平台依赖属性
详细描述:
在S60第二版中,我们要在pkg中指定软件平台依赖性时,必须遵循下列格式。
; Supports S60 2nd Edition
(0x101F7960), 0, 0, 0, {"Series60ProductID"}
(0x101F7960), 0, 0, 0,
在S60第三版中,平台依赖性是从硬件依赖考虑的,而平台UID必须是用中括号来定义:
; Supports S60 3rd Edition
[0x101F7961], 0, 0, 0, {"Series60ProductID"}
而老的定义形式在S60第三版中的pkg文件中仍然有效,makesis执行时不会提示错误。不过如果要安装这样形式的SIS文件到第三版设备上将会引发“Application not compatible” 错误。因为安装程序无法识别平台UID。
一些支持自定义产生pkg文件的工具及IDE可能仍然在使用老格式,这个需要注意。
解决方案:
检查那些为生成在S60第三版上SIS包的pkg文件中,关于平台依赖性设置的格式是否正确。
SIS文件中的Vendor信息在软件各版本中不应更改
详细描述:
Vendor信息在pkg文件中是强制需要的:
; localized vendor name(s) (corresponding to language),
; displayed during installation
%{"Vendor-EN", ...}
; non-localized (global) vendor name
:{"Unique Vendor"}
要注意的是,升级包中non-localized vendor string需要和已安装在设备中的一致。
这是为了和签名一致,防止未认证的升级包代替合法vendor.
如果vendor string新旧不一致的话,在安装时就会报告“Update error”的错误信息
如果MIME类型不匹配则无法显示Flash
详细描述:
在一些web网站中,网页内容包括flash,和相应的TYPE属性。当发送过来的MIME类型和实际不一致时(如text/plain),则S60的浏览器将无法显示正确内容。
不被任何程序所支持的MIME类型是从server询问得到的,而不是从TYPE属性
发件箱中的自己生成的信息
详细描述:
这个情况在所有自写信息的程序中都会出现,换句话说,如果你使用CMsvEntry,TMsvEntry和一个client MTM来生成并发送短信,就会出现这样的问题。
你可通过生成并立刻发送一条信息来重演上述状况,这条信息根据你在信息TMsvEntry对象中对iDate的设置可能会留在收件箱中保持一段时间状态为“正在发送”
解决方案:
解决这个问题的方法是将你的TMsvEntry中的iDate设置为Universal Time(调用iDate.UniversalTime()),这样信息服务器根据本地时间和信息中的时间戳来计算时差,并由此安排发送时间。
如果在缩放图片时不保留高宽比将导致程序异常
详细描述:
如果程序使用CBitmapScaler的Scale方法将一个张图片(如为132x176)进行了缩放处理(如176x144),而其aMaintainAspectRatio参数为EFalse,则程序会引发USER 21错误,异常中断。
解决方案:
如果需要将上述情况进行缩放绘制到屏幕上,你可以使用CGraphicContext:rawBitmap方法。
如果缩放后的图片还要使用,你可在CBitmapContext对象上使用同样方式处理,保持图片原来构造时的样子。下列代码可融入Series 60 Developer Platform 2.0: Image Converter Example示例中做测试使用。
void CImageConverterEngine::ScaleL(TSize aSize) { CWsBitmap *newBitmap = new (ELeave) CWsBitmap(CEikonEnv::Static()->WsSession()); CleanupStack::PushL(newBitmap); User::LeaveIfError(newBitmap->Create( aSize,CEikonEnv::Static()->DefaultDisplayMode())); CFbsBitmapDevice* bitDev = CFbsBitmapDevice::NewL(newBitmap); CleanupStack::PushL(bitDev); CBitmapContext* bgc = NULL; User::LeaveIfError(bitDev->CreateBitmapContext(bgc)); bgc->DrawBitmap(TRect(TPoint(0,0), aSize), iBitmap); delete bgc; CleanupStack::PopAndDestroy(2); // bitDev, newBitmap delete iBitmap; iBitmap = newBitmap; iController->NotifyCompletion(KErrNone); }
导入工程到IDE时图象资源可能无法生成
详细描述:
在S60第三版上,multi-image文件(.mbm或.mif)以及相关的image header files(.mbg)是通过mifconv图象转换工具生成的。是bld.inf中通过一个扩展的makefile来完成的,这个方法在S60 2nd Edition, Feature Pack 3.就开始被支持。
这些扩展的makefile不会在IDE中随着工程的编译而被执行,因此图片文件和头文件将不会在编译时自动产生,通常这就导致工程因为缺少.mbg文件而失败。
解决方案:
我们可以通过abld命令去生成这些图片资源,到\group目录下,输入
bldmake bldefiles
abld resource
在此后,工程就能被顺利导入IDE并被编译,注意如果图片资源(source bitmaps或SVG images)被修改了,那这个过程还要重复做一次。
当键盘锁定被取消时可能会导致无意中将程序切换到后台
详细描述:
大部分S60游戏都会将键锁定模式取消,以便多键同时按下时不影响游戏。这可以通过调用应用程序UI(CAknAppUi)来完成:
SetKeyBlockMode(ENoKeyBlock)
在S60第二版FP2或更新的版本中,如果为键盘锁定模式取消状态,那下列按键组合被同时按下会导致程序被切换到后台:
‘7’ + ‘8’ + ‘0’ + ‘*’
‘9’ + ‘0’ + ‘#’
解决方案:
目前没有好的解决方案,游戏设计中应该避免用户偶然按下上述按键组合
Form UI component要支持皮肤
详细描述:
如果一个运行在S60第二版,FP3设备上的程序,使用了form(CAknForm),那它必须要支持皮肤,否则程序将无法绘制该表单。
我们在程序UI类(从CAknAppUi中继承)的构造函数ConstructL()中通过传递EAknEnableSkin参数来让程序支持皮肤功能。
void CMyAppUi::ConstructL()
{
BaseConstructL(EAknEnableSkin);
...
}
这个form布局的问题在S60第二版FP3模拟器上不会出现。
情景重现:
比较一下设置及不设置EAknEnableSkin情况下我们使用CAknForm的情况。
这个我们可以通过使用CAknForm类的SDK示例程序(如Form, Popupfield example)来具体。
压缩SVG文件
详细描述:
我们可以在S60第二版,FP3的SDK中通过SVGTBINENCODE.EXE程序来对Scalable Vector Graphics(SVG)图形文件进行二进制编码和压缩。
SVGTBINENCODE的使用方法为:
1、备份你的.svg文件——你将使用一个不可编辑的压缩版本覆盖原来的那个。
2、对.svg文件在模拟器目录中进行拷贝。如%EPOCROOT%\epoc32\winscw\c\system\temp\
3、在命令行方式下,运行svgtbinencode压缩程序。
cd %EPOCROOT%\epoc32\release\winscw\? svgtbinencode -Dnogui -- c:\system\temp\sourceimage.svg
这将在同样目录下生成一个二进制编码版本的SVG图形文件,其扩展名为.svgb
将这个.svgb文件拷贝到原来.svg文件所在位置。
删除老的.SVG文件,因为你将要用压缩版本去替代它。
将这个.svgb文件重命名为.svg扩展名。
运行MifConv.exe程序来生成一个multi-icon文件(.MIF),如果使用扩展过的makefile(icons.mk),那这些在编译过程中会自动完成。
注意,MifConv无法识别.svgb扩展名,如果你没将其改名为.svg扩展名那它将无法识别接收这个二进制编码的SVG文件。