当取消SIS包安装时,并没有完全删除程序文件,而是保留了一部分已安装的内容。
详细描述:
当安装SIS包时按下“Cancel”取消时,已经拷贝到系统的文件没有被删除而是保留了下来。而程序管理器中错误的显示为已安装。
案例重现:
通过蓝牙或红外传递一个SIS文件到6600的收件箱中,选择安装位置(手机内存或存储卡)然后开始安装,当显示安装进度条时,立刻按取,弹出确认框后选择“是”。
结果:该应用保留了安装了部分文件,并没有从文件系统中删除这些文件。而在应用程序管理中该程序被错误的显示为已安装。如果要删除该文件,则会印发错误提示“General: Already in use”
解决方案:
对开发人员以及高级用户来说,可使用文件浏览器或自制程序来从文件系统中删除该SIS.
S60第三版SDK中MMF框架API的问题
详细描述:
S60第三版SDK中缺少MMF Controller Framework头文件和库,这样的话,我们将不会搜索到关于MMF的信息和媒体格式插件,这将导致一些MMF的相关引用。如CVideoRecorderUtility在构造时就需要Controller和格式UIDs。
带完整键盘的S60第三版设备上的按键映射
详细描述:
在Nokia E61以及E70等带全键盘的机器上运行的程序时,如果要捕捉CCoeControl派生类下的按键事件时,在FEP模式下的编辑框中是无法获取同样键值的(通过TKeyEvent::iCode)。
这是因为QWERTY键盘的映射是依赖于当前的语言和输入模式的。例如,在Nokia E61上,CCoeControl派生类在数字键盘被按下时总是获得1,2,3。。。。而只有在FEP模式下的编辑框中(如CEikEdwin)它才能获取字母键"r","t",。。。等。
注意scan codes(TKeyEvent::iScanCode)是不会受当前语言或输入模式影响的。
解决方案:
应用程序在处理文本输入时,应该使用表示准的Avkon编辑框控件。
S60第三版中不支持V2 Camera observer
详细描述:
S60第三版中你会发现有两个版本的camera observer接口类,MCameraObserver和MCameraObserver2
不过这里要说明的是MCameraObserver2尚未被支持。
案例重现:
试图去这样构造一个CCamera的实例:
static IMPORT_C CCamera *NewL(MCameraObserver2 &aObserver,
TInt aCameraIndex,
TInt aPriority);
这不会引发异常,不过返回指针将为NULL
解决方案:
在S60中用到照相机API时应使用MCameraObserver
S60上不再支持CMdaAudioConvertUtility
详细描述:
CMdaAudioConvertUility做为Symbian' Media Client Audio API的一部分,从S60第二版SDK, FP1后就不再被支持。
当在新平台使用时,所有CMdaAudioConvertUtility::OpenL()所返回的变量将为KErrNotSupported错误代码。
解决方案:
Audio convert utility在S60上不再被支持,流媒体程序不再需要将声音先转成PCM中间格式,取而代之的是我们可以直接将压缩的声音数据向流中传递或从中接收,只需在初始化流对象时提供一
个被支持的数据类型(fourCC代码)。
如,使用CMdaAudioInputStream从AMR-NB格式中直接读取声音数据:
void MyStreamClass::MaiscOpenComplete(TInt aError)
{
iInputStream->SetDataTypeL(KMMFFourCCCodeAMR);
…
}
S60第三版中访问SMS设置的新PAI
详细描述:
现在在CSmsAccount中有一个新的API,下面这段代码就展示了如何使用该类去设置SMSC地址以便发送消息。
// ---------------------------------------- // // Sets the message center to the message // // ---------------------------------------- TInt CFW3MsgEngine::SetSMSCL() { TInt err = 0; // CSmsHeader encapsulates data specific for sms messages, // like service center number and options for sending. CSmsHeader& header = iMtm->SmsHeader(); CSmsSettings* settings = CSmsSettings::NewL(); CleanupStack::PushL(settings); CSmsNumber* sc = CSmsNumber::NewL(); //CSmsNumber* sc = 0; CleanupStack::PushL(sc); //--------- SMSC & header set-up settings->CopyL(iMtm->ServiceSettings()); // restore existing settings // set send options settings->SetDelivery(ESmsDeliveryImmediately); // set to be delivered immediately header.SetSmsSettingsL(*settings); // Set SMSC address if (header.Message().ServiceCenterAddress().Length() == 0) { // No smsc set. We assume there is at least one sc number defined and use // the default SC number. CSmsSettings* serviceSettings = &(iMtm->ServiceSettings()); // if number of scaddresses in the list is null if (!serviceSettings->ServiceCenterCount()) // New messaging API uses new methods { // here there should be a dialog in which user can add sc number _LIT(KNotSet,"SMSC not set"); // Display a Note CAknGlobalNote* globalNote = CAknGlobalNote::NewLC(); globalNote->ShowNoteL(EAknGlobalInformationNote , KNotSet); CleanupStack::PopAndDestroy(); // globalNote } else { // set sc address to default. sc->SetAddressL((serviceSettings->GetServiceCenter(serviceSettings->DefaultServiceCenter())).Address()); // New messaging API uses new methods header.Message().SetServiceCenterAddressL(sc->Address()); } } //--------- SMSC & header set-up CleanupStack::PopAndDestroy(2); // sc, settings return err; }
recognizer文件名最大长度
详细描述:
安装在\system\recogs\目录下的recognizer DLL文件.mdl,其文件名(包括扩展名)不应该超过16个字符。如果超过这个长度,过长的文件名会引起设备在启动时锁死。
注意在启动时按住Edit(笔形)键,将不会加载recognizer(及其他启动项目),这个方法可在设备无法正常启动时(因为recognizer故障)使用。
S60第三版中最小缺省堆栈大小
详细描述:
在symbian OS v9中缺省的堆栈大小从20kb缩减到8kb,以优化内存的消耗。这主要是因为平台安全性导致了在系统中同时运行的进程增多。
实际上,8kb的堆栈大小对任何一个稍大的S60程序来说都是不够的。如果在当前设备上缺省的堆栈能运行你的程序,那因为堆栈的溢出(平台库的消耗而引发堆栈的增长),它也很容易引发崩溃
。在S60第三版SDK中建议所有程序都增长到20KB堆栈,这需要为此重新编译。
案例重现:
解决方案:
我们可以通过在.mmp工程定义文件中使用epocstacksize命令行来修改缺省的8KB大小。
epocstacksize stacksize
堆栈的大小,可以通过十六进制或十进制来指定。但这对winscw/wins平台是无效的。
列如下面这行将堆栈大小增加到20KB
epocstacksize 0x5000
同样,我们也可以在产生新线程时定义该线程的堆栈大小。
无法备份或恢复C:\System目录下的公共文件
详细描述:
无法备份或恢复C:\System下的公共文件,虽然data caging configuration并没有把该目录做为私有或控制访问来考虑。
开发者应使用如C:\Data这样的目录,注册为备份及恢复用的公共文件路径。
请阅读文档"PC connectivity: how to write backup-aware software"(http://www.symbian.com/developer/tec...??的知识。
在对一张使用逐行编码的JPG图片进行解码时,会出现“内存不够”的错误
详细描述:
在对使用逐行编码的JPG图片进行解码时将比对使用顺序编码的JPG图片解码占用更多内存。
列如当使用CImageDecoder类对一张较大的逐行编码JPEG进行解码时,CImageDecoder::Convert()将会获得KErrNoMemory(-4)错误。
应用程序增加堆的大小将有助于这类问题的解决,我们可以在.mmp文件中使用EPOCHEAPSIZE命令进行调整,如:
EPOCHEAPSIZE 0x1000 0x200000
这样将初始化的堆大小从4KB(缺省)调整到2MB
案例重现:
解决方案:
我们可以通过在.mmp工程定义文件中使用epocstacksize命令行来修改缺省的8KB大小。
epocstacksize stacksize
堆栈的大小,可以通过十六进制或十进制来指定。但这对winscw/wins平台是无效的。
列如下面这行将堆栈大小增加到20KB
epocstacksize 0x5000
同样,我们也可以在产生新线程时定义该线程的堆栈大小。
在S60上编写一个有发送短信功能的程序
详细描述:
根据下面Forum Nokia上的示例来写一个具有短信发送能力的程序是很简单的。根据不同的目标平台,有两种方法可选择,在早期的S60和S80设备上一般使用一个客户端的MTM API,而S60第三版中
则介绍了一个更为高级易用的API。
2nd Edition platforms:
在S60第二版和S80平台上如果要发送SMS程序可以直接使用SMS Client MTM来进行信息发送。早期的平台上对开发者来说主要的问题是其中一部分需要的API不是公开的,不过在S60 2nd和S80 2nd中
已经解决了。
Forum Nokia已有SMS示例,它将教你一步步来生成并发送一个短信。可以通过下列连接查看:
S60 Platform: SMS Example
http://www.forum.nokia.com/info/sw.n..._0_en.zip.html
3rd Edition:
在S60第三版上通过新的SendAs API我们可以更加容易的发送短信。这是封装在messaging client MTMs上的API,通过它们你的程序可以去访问所有支持的messaging protocol,而不光是sms
messaging。
S60第三版也支持对MTM的直接使用。
可以通过下列连接去找到在MTM方法和新的SendAs方法的示例:
S60 Platform: SMS Example
http://www.forum.nokia.com/info/sw.n..._0_en.zip.html
Related topics:
Forum Nokia Messaging examples (C++)
http://www.forum.nokia.com/main/1%2c...0_11%2c00.html
Messaging discussion on Forum Nokia C++ developer's board
http://discussion.forum.nokia.com/fo...splay.php?f=26
Messaging in Symbian Developer Library - online API reference
http://www.symbian.com/developer/tec...reference/cpp/
如果控制一个进程中的堆分配
详细描述:
我的程序试图从堆上分配一定内存,却产生了失败。我该怎么做才能分配到更多内存呢?
我们可以在.mmp中通过EPOCHEAPSIZE命令直接来保留或压缩一定内存空间,这样进程在启动时就能使用。
Syntax: epocheapsize minimum maximum
最小值(以字节为单位,一般为4K左右)以保证进程的正常运行。
最大值说明进行所能使用内存的数量限度。
要获取更多信息可参考Symbian FAQ知识库:
http://www3.symbian.com/faq.nsf/0/8D...5?OpenDocument
程序的自启动的动态配置
详细描述:
目前,在S60第三版中,如果一个程序想要自启动,你可以通过启动列表管理API来完成它。具体信息可以在S60 3rd Edition SDK中找到。
为了进行Symbian Signed criteria的传递,你需要在你的程序中提供对自启动的取消功能。暂时没有公开的API可以帮助你解决这个问题,下面有两个解决方案:
1)设计一个启动程序,它可用来启动一个实际的应用程序。无论手机何时启动该启动程序需被自动开启。然后它检查配置文件(.ini),如果配置文件中该boot选项被标记为开启,那就去启动响应的实际程序,如果为关闭,那就终止自己,当然也不需要去启动实际程序了。
注意在启动程序成功启动实际程序后它不能立刻将自己结束掉,否则实际程序将因此而无法成功运行。
在实际运用中,第三方程序可以找到一个公共位置去存放配置文件,或者为两个程序(启动程序和实际程序)准备一个公共的secure ID。RVCT编译程序可以帮助你解决这个问题。
2)你也可以安排手机开启后每次都去启动实际程序,在开始阶段就去检查配置文件,如果其中的flag被标记为ON,则继续运行它自己,如果flag被标记为OFF,则需要调用CAknAppUi::Exit()函数来结束自己。
同第一个方案相比,这个方法不需要去解决两个程序同时拥有一个secure ID的问题。这样如果程序十分大,并且用户不是选择每次都自启动的话,我们可以花费更多CPU时间在加载程序上。
从Symbian Singed的角度来看,第二个方法要优于第一个。
安全共享数据及数据库加密
详细描述:
从Symbian OS v9.x后就不再提供数据库加密机制了,保护你数据库不被其他程序访问的唯一方法就是将数据库文件存储在你的私人数据空间。不过这样其他程序也就没法访问到它了。
Symbian OS v9.x中所介绍的安全共享数据库的方法为,通过data caging机制保护并共享数据。
数据库是通过DBMS client-serve API来生成并被访问的。数据库文件被存储在DBMS server的data cage文件夹中。DBMS server根据与此数据库预先关联的安全法则允许其他客户端程序去访问它。这种安全法则可以规定客户端只能具有ReadDeviceData能力。为了向数据库写入东西,客户端得具有WriteDeviceData能力,和一个给定的Secure ID(SID)
不幸的是,安全法则目前只能存放在Z盘中。这意味着第三方开发者无法定义或安装他们自己的安全法则。同样,当第三方程序需要使用一个好的方法来同享数据库时,也没有能使用的预先配置的法则。
如果你的程序需要访问一个共享数据库,那下列选项是可以考虑的:
将数据库存放在一个共同目录下(如果不需要考虑安全性问题)
为你的服务提供一个API以访问存储在自己
在通话时捕捉到结束键(红色键)
详细描述:
我们可以使用下列代码在通话时捕捉到结束键。
Please note that SwEvent capability is needed to make successful calls to the mentioned Window Server functions.
#include <W32STD.H> // link against ws32.lib #include <e32keys.h> ... RWindowGroup& groupWin = CCoeEnv::Static()->RootWin(); TInt endKey1 = groupWin.CaptureKeyUpAndDowns( EStdKeyNo, 0, 0 ); TInt endKey2 = groupWin.CaptureKey( EKeyNo, 0, 0 ); // -> End key can now be processed before the phone application of the device... ... // Cancel the capture groupWin.CancelCaptureKeyUpAndDowns( endKey1 ); groupWin.CancelCaptureKey( endKey2 );
搜索可用的WLAN网络
详细描述:
搜索WLAN可用网络时,可以通过Connection Moniter Server API来获得他们实际的信号强度。
下面是该API的一个使用示例:
#include <rconnmon.h> void CWlanTest:: ListNetworksAndSignalL(CDesCArraySeg& aNetworks) { _LIT(KNetInfo, "Network: %S\tSignal: %d"); TBuf<32> netName; TBuf<100> line; RConnectionMonitor monitor; TPckgBuf<TConnMonNetworkNames> pkgNetworks; // establish connection with the monitor server monitor.ConnectL(); // prepare leave clean-up CleanupClosePushL(monitor); TRequestStatus status; // get the list of available networks monitor.GetPckgAttribute(EBearerIdWLAN, 0, KNetworkNames, pkgNetworks, status); // suspend thread until the info is retrieved // production code should use active objects User::WaitForRequest( status ) ; // leave if the asynchronous method returned an error User::LeaveIfError(status.Int()); // reset networks list aNetworks.Reset(); // add retrieved networks to the list for(TUint i=0; i<pkgNetworks().iCount; i++) { netName.Copy(pkgNetworks().iNetwork[i].iName); line.Format(KNetInfo, &netName, pkgNetworks().iNetwork[i].iSignalStrength); aNetworks.AppendL(line); } // close server session CleanupStack::PopAndDestroy(&monitor); } Note: - Link against: ConnMon.lib - S60 3rd Edition-specific capability needed: NetworkServices
S60第三版中出现了2个浏览器,缺省的为双模式浏览器
详细描述:
S60第三版设备现在有2个浏览器,传统的双模式浏览器支持Extensible Hypertext Markup Language Mobile Profile (XHTML MP)/ Wireless Markup Language (WML)和HTML。这个浏览器被命名为“Services”(hoolee语,就是中文机中的“服务”)
第二个浏览器是Noia开源浏览器,它支持XHTML MP和HTML,不过尚未支持WML。这个浏览器力图保持web页面原来的布局,似它看起来就和原来设计初衷一样。这个浏览器被命名为“Web”(hoolee语,取代了Opera了,呵呵)
如果用户请求,如一个MMS消息里有条连接要打开web页面,这是就会打开双模式浏览器去解析它。因为它是目前缺省的。
而从S60第三版FP1向后,Nokia开源浏览器将做为平台唯一的浏览器存在了
在第三版中的ETel库
说明:
受争议的ETel库在第三版中已经去掉了,去掉的库包括ETel Core和ETel MM(etel.h和etelmm.h),在第三版中之后一个公共的电话API将被提供那就是CTelephony API(etel3rdparty.h和etel3rdparty.lib)
检查离线模式
说明:
在S60第三版中,我们通过读取Centrol Repository中的电话设置来检查离线模式是否启动。
要获得情景模式的设置,只有对Central Repository进行调用才行:
#include <centralrepository.h> #include <ProfileEngineSDKCRKeys.h> CRepository* cr = CRepository::NewLC( KCRUidProfileEngine ); TInt value; // Get ID of current profile User::LeaveIfError( cr->Get( KProEngActiveProfile, value ) ); // Check value to determine the active profile if ( value == 5 ) { // current profile is the offline profile } // ...
要了解更多关于Profile Engine的信息,可阅读SDK的帮助文档和“Profiles Engine Active Profile Settings API.”
在S60第二版,FP2设备上获取电量状态
解决方案:
这些值在新版中确实有所改变,而公开文档中却并未写上。
你可以通过使用下列值来查询电量状态。
// The current battery status information const TInt KUidBatteryCStatusValue = 0x100052D8; const TUid KUidBatteryCStatus = {KUidBatteryCStatusValue}; enum TSABatteryCStatus { ESACBatteryOk, ESACBatteryLow, ESACBatteryEmpty, ESACPowerOff }; // The amount of battery bars const TInt KUidBatteryBarsValue = 0x100052D3; const TUid KUidBatteryBars ={KUidBatteryBarsValue}; enum TSABatteryBars { ESABBars_0, ESABBars_1, ESABBars_2, ESABBars_3, ESABBars_4, ESABBars_5, ESABBars_6, ESABBars_7 };