要学习特定设备ProductID及MachineUID值的使用,可参考下列文档:
S60 Platform: Identification Codes
http://www.forum.nokia.com/info/sw.n..._4_en.pdf.html
Series60ProductID values:
(0x101F6F88) S60 1st Edition (0.9)
(0x101F8202) S60 1st Edition, FP1
(0x101F7960) S60 2nd Edition
(0x101F9115) S60 2nd Edition, FP1
(0x10200BAB) S60 2nd Edition, FP2
(0x102032BD) S60 2nd Edition, FP3
[0x101F7961] S60 3rd Edition
[0x102032BE] S60 3rd Edition, FP1
ProductID MachineUID Device
S60 1st Ed:
0x101F6F87 0x101F4FC3 Nokia 7650
S60 1st Ed, FP1:
0x101F7962 0x101F466A Nokia 3650
****N/A**** 0x101F466A Nokia 3660
****N/A**** 0x101FA031 Sendo-X
0x101F9071 0x101F9071 Siemens SX-1
S60 2nd Ed:
0x101F7963 0x101FB3DD Nokia 6600
S60 2nd Ed, FP1:
0x10200F97 0x10200F97 Nokia 3230
0x101FB3F4 0x101FB3F4 Nokia 6260
0x1020216B 0x101F3EE3 Nokia 6620
0x101FD5DC 0x101FB3F3 Nokia 6670
0x101FD5DB 0x101FB3F3 Nokia 7610
S60 2nd Ed, FP2:
0x101F7964 0x101FBB55 Nokia 6630
0x102078D1 0x10200F99 Nokia 6680
0x102078D0 0x10200F9C Nokia 6681
0x102078CF 0x10200F9B Nokia 6682
S60 2nd Ed, FP3:
0x10200F9A 0x10200F9A Nokia N70
0x10200F98 0x10200F98 Nokia N90
S60 3rd Ed:
0x200005F8 0x200005F8 Nokia 3250
0x20001856 0x20001856 Nokia E60
0x20001858 0x20001858 Nokia E61
0x20001857 0x20001857 Nokia E70
0x200005FF 0x200005FF Nokia N71
0x200005FB 0x200005FB Nokia N73
0x200005F9 0x200005F9 Nokia N80
0x200005FC 0x200005FC Nokia N91
0x200005FA 0x200005FA Nokia N92
N-Gage:
0x101F8A64 0x101F8C19 Nokia N-Gage™
****N/A**** 0x101FB2B1 Nokia N-Gage™ QD
2、一个程序所适用的堆内存
TSS000350
设备, 软件 版本: S60 3rd Edition
说明:
我的程序要多少堆内存才够用呢?
创建日期: July 7, 2006
详细描述:
在一台手机(或SDK的模拟器)上会有一定的物理内存大小,而你的应用程序将获取一部分做为堆内存使用。
当你程序启动后产生进程,会有一个预先分配的堆给其使用。S60第三版设备上缺省大小是4KB,早期的S60平台上是1KB。
根据需要,应用程序可以自由分配更多的堆内存,程序能使用的堆大小可在1M范围内动态增加,这是操作系统所规定最高极限了,呵呵。
如果试图分配的内存超过所能最大限制,将引发KErrNoMemory异常。
大部分Symbian C++程序在这样的堆内存安排下可以正常工作,但有时间我们需要更大的堆内存来工作。我们可以通过MMP文件中使用
EPOCHEAPSIZE命令来指定最大和最小堆内存。
例如
<code>
TARGET MemoryTest.exe
TARGETTYPE exe
UID 0x00000000 KMemoryTestUID3
SECUREID KMemoryTestUID3
VENDORID 0x00000000
CAPABILITY NONE
EPOCHEAPSIZE 0x5000 0x400000
EPOCSTACKSIZE 0x5000
....
</code>
在上述代码中,应用程序描述了它所需要的最大和最小堆内存,分别是0x5000字节(20KB)和0x400000字节(4MB),现在该程序可以安全来分配一
块3MB的堆空间。
Note: As documented, prior to S60 3rd Edition the EPOCHEAPSIZE statement has no effect on WINS32 platforms.
在对使用逐行编码的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
同样,我们也可以在产生新线程时定义该线程的堆栈大小。
3、S60第三版中对messaging components(MTM)的性能需求
TSS000361
设备, 软件 版本: S60 3rd Edition
说明:
创建日期: July 7, 2006
详细描述:
S60第三版上,因为平台安全性的考虑,对公共DLL有很多要求。
这会在下列方面影响messaging component(MTM)的开发使用:
所有public-size MTM component都需要“ALL-TCB”属性,因为他们要被其他public-side application所加载(这些程序拥有设置其的能力)
Public-side MTM component主要为:Client MTM, UI MTM, 以及UI Data MTM.
而private-side MTM component既Server MTM,要和加载进程拥有一样的能力。你的server-side MTM component应该拥有下列能力:
ReadDeviceData, WriteDeviceData, ProtServ, NetworkControl, NetworkServices, LocalServices, ReadUserData.
Given these heavy capability requirements any MTM implementation has to go through the Symbian Signed process and will need
to assign all needed UIDs from the protected UID range (0x00000000 - 0x7FFFFFFF).
4、recognizer文件名最大长度
KIS000385
设备, 软件 版本: S60 1st Edition, S60 2nd Edition
说明:
创建日期: July 7, 2006
详细描述:
安装在/system/recogs/目录下的recognizer DLL文件.mdl,其文件名(包括扩展名)不应该超过16个字符。如果超过这个长度,过长的文件名
会引起设备在启动时锁死。
注意在启动时按住Edit(笔形)键,将不会加载recognizer(及其他启动项目),这个方法可在设备无法正常启动时(因为recognizer故障)使用
。
4、S60第三版中不支持V2 Camera observer
KIS000353
设备, 软件 版本: S60 3rd Edition, S60 3rd Edition FP1
说明:
在S60第三版中,MCameraObserver2将不被支持。
创建日期: July 7, 2006
详细描述:
S60第三版中你会发现有两个版本的camera observer接口类,MCameraObserver和MCameraObserver2
不过这里要说明的是MCameraObserver2尚未被支持。
案例重现:
试图去这样构造一个CCamera的实例:
static IMPORT_C CCamera *NewL(MCameraObserver2 &aObserver,
TInt aCameraIndex,
TInt aPriority);
这不会引发异常,不过返回指针将为NULL
解决方案:
在S60中用到照相机API时应使用MCameraObserver
5、当取消SIS包安装时,并没有完全删除程序文件,而是保留了一部分已安装的内容。
创建日期: April 7, 2005
详细描述:
当安装SIS包时按下“Cancel”取消时,已经拷贝到系统的文件没有被删除而是保留了下来。而程序管理器中错误的显示为已安装。
案例重现:
通过蓝牙或红外传递一个SIS文件到6600的收件箱中,选择安装位置(手机内存或存储卡)然后开始安装,当显示安装进度条时,立刻按取,弹
出确认框后选择“是”。
结果:该应用保留了安装了部分文件,并没有从文件系统中删除这些文件。而在应用程序管理中该程序被错误的显示为已安装。如果要删除该
文件,则会印发错误提示“General: Already in use”
解决方案:
对开发人员以及高级用户来说,可使用文件浏览器或自制程序来从文件系统中删除该SIS.
6、XML Parser API无法使用的问题
KIS000158
开发伙伴平台: 60系列开发平台 2.0
设备, 软件 版本:
大类: Symbian C++
子类: 普通
说明:
尽管XML Parser API在一些开发文档中提及,并且在SDK中也有一些相关性的头文件存在,但其目前仍无法使用。
XML Parser API将在未来的Series 60 Developer Platform被正式支持。
如果你需要的话,可以实现自己的XML解析程序或使用现成的解析器,如Digia SAX Paser
7、如何发现可用的音频设备
TSS000035
开发伙伴平台: 60系列开发平台 1.0/2.0
设备, 软件版本: 无
大类: Symbian C++
子类: 多媒体
说明:
详细描述
我怎样可以检测到系统正在用音频设备播放音频,或者说另外的
一个程序正在使用系统音频设备呢?我怎样可以发现音频设备现
在是否正在忙碌中,有没有可以不打断其他程序的解决方案。
解决方案
检测音频设备并没有直接的方法。但是可以尝试播放一段测试音
乐(频率 20 KHz, 优先级 = EMdaPriorityMin, 长度 = 0 ms).
如果返回的值是KErrInUse,那么这说明音频服务器正在使用中.
注意:有些情况下其他的多媒体客户端程序有可能一直保留对音
频设备的占用。
播放声音的示例代码在Series 60 SDK的Sound example中有演示
8、如何获取设备当前情景模式
TSS000513
设备, 软件 版本:
S60 3rd Edition, FP1
创建日期:
详细描述:
我们可以通过使用Profiles Engine Wrapper API来获取当前情景模式。
首先需要包含这两个头文件:
Code:
mproengengine.h
proengfactory.h然后是链接库:
Code:
ProfileEngine.lib再看下列演示代码:
Code:
MProEngEngine* engine = ProEngFactory::NewEngineLC();
TInt activeId( engine->ActiveProfileId() );通过调用ActiveProfileId()我们可以获取如下返回值:
Code:
0 - General
1 - Silent
2 - Meeting
3 - Outdoor
4 - Pager
5 – Offline
9、如何获取功能键上的文字
TSS000675
设备, 软件 版本:
S60 3rd Edition
S60 3rd Edition, FP1
详细描述:
==描述==
下列代码演示了如何获取当前control pane(CBA)上左、中、右功能键的文字。
我们可以通过CCoeControl::ComponentControl()获取每个功能键的label(CEikLabel),它是功能键上第一个控件。
解决方案
Code:
CEikButtonGroupContainer* cba = CEikButtonGroupContainer::Current();
if( cba )
{
MEikButtonGroup* buttonGroup = cba->ButtonGroup();
for( TInt pos = 0; pos < 3; pos++ )
{
TInt cmdId = buttonGroup->CommandId( pos );
CCoeControl* button = buttonGroup->GroupControlById( cmdId );
if( button && buttonGroup->IsCommandVisible( cmdId ))
{
CEikLabel* label = static_cast<CEikLabel*>( button->ComponentControl(0) );
const TDesC* txt = label->Text();
}
}
}
==注意==
1、上述代码总是返回完整的lable text,即使显示在屏幕上的label是缩短过文字的。
2、CEikCommandButton类中提供了Label()方法以完成该项功能,但目前CBA的实现并没支持该类。
CEikButtonGroupContainer::CommandButtonOrNull()总是会返回NULL。
10、如何更换当前主题
TSS000456
设备, 软件 版本:
S60 3rd Edition
详细描述:
S60第三版SDK并未提供给第三方程序一个方法来更换主题。
但我们可以在
Extensions plug-in package for S60 3rd Edition SDK
http://www.forum.nokia.com/info/sw.n...Pack1.zip.html
获取到我们需要的API.
解决方案
如何更换主题:
1、连接Skin Server
Code:
#include <AknSSrvClient.h> // link against aknskinsrv.lib
RAknsSrvSession skinsSession;
User::LeaveIfError( skinsSession.Connect( this ) );
CleanupClosePushL( skinsSession );
2、获取当前skin的package ID
Code:
#include <centralrepository.h> // link against centralrepository.lib
#include <AknSkinsInternalCRKeys.h>
void CMyThemeManager::StoreCurrentSkinIdL()
{
TAknsPkgIDBuf pidBuf;
CRepository* repository = CRepository::NewL(KCRUidPersonalisation );
TInt retVal = repository->Get( KPslnActiveSkinUid, pidBuf );
delete repository;
repository = NULL;
iOriginalSkinPid.SetFromDesL( pidBuf ); // iOriginalSkinPid is of type TAknsPkgID
}
3、获得已安装skin packages列表
Code:
CArrayPtr<CAknsSrvSkinInformationPkg>* skinInfoArray =
skinsSession.EnumerateSkinPackagesL();
CleanupStack::PushL( skinInfoArray );
4、查询已安装的主题,确认第一个有效新主题
Code:
TInt retValue( KErrNone );
if ( skinInfoArray->Count() > 0 )
{
for ( TInt i = 0; i < skinInfoArray->Count(); i++ )
{
TAknsPkgID pkgId = skinInfoArray->At( i )->PID();
if ( pkgId != iOriginalSkinPid )
{
// Activates a complete skin package
retValue = skinsSession.SetAllDefinitionSets( pkgId );
if ( retValue == KErrNone )
{
SetNewSkinIdL( pkgId );
}
break;
}
}
}5、在Central Repository中存储新主题id
Code:
void CMyThemeManager::SetNewSkinIdL( TAknsPkgID aPkgId )
{
TAknsPkgIDBuf pidBuf;
aPkgId.CopyToDes( pidBuf );
CRepository* repository = CRepository::NewL( KCRUidPersonalisation );
TInt retVal = repository->Set( KPslnActiveSkinUid, pidBuf );
// KPslnActiveSkinLocation value needs to be updated
// if the new skin resides on memory card and the
// previous one resided in phone memory (and vice versa)
delete repository;
repository = NULL;
}