symbian养成手记(蓝牙、短信附件)

提取蓝牙附件

2009年09月2日,星期三

#include <btmsgtypeuid.h> //for KUidMsgTypeBt
CMsvEntrySelection* entries = inboxMsvEntry->ChildrenWithMtmL(KUidMsgTypeBt);//从Inbox里面过滤出所有来自Bt的带附件的消息
//也可以通过CMsvEntryFilter来达到相同目的:
CMsvEntryFilter* filter = CMsvEntryFilter::NewLC();
filter->SetMtm(KUidMsgTypeBt);//SetType在这里起不到作用
//当然,使用了filter后需要通过CMsvSession来获取CMsvEntrySelection:
iMsvSession->GetChildIdsL(inboxMsvEntry->EntryId(),*filter,*filteredEntries);//filteredEntries要事先new出来

//CMsvEntrySelection得到后循环创建CMsvEntry
CMsvEntry* btEntry = iMsvSession->GetEntryL(entries->At(i));
//然后看这个btEntry中有多少个Child,循环每一个child
CMsvEntrySelection* btChildren = btEntry->ChildrenL();
//对每一个child,调用btEntry->SetEntryL(btChildren->At(j));,查看其是否拥有CMsvStore,有的话获取MMsvAttachmentManager搞附件

//该干嘛干嘛

Series 60第三版上提取消息的附件

2009年09月2日,星期三

S60 3rd上的MTM框架提供了MMsvAttachmentManager(附件管理器)这个接口类管理各种不同消息的附件,它把操作各种附件的实现交给各 MTM,使用者只需要简单通过附件管理器提供的方法就可以操作消息的附件。附件管理器基于CMsvAttachment管理各类型的附件,而 CMsvAttachment是消息框架中提供的用来表现任何类型附件的对象,通过它不用实际加载或检索附件就可得到附件的许多属性。消息管理器支持下面几种不同类型的附件:
1.        文件附件:被拷贝或创建在消息存储(Message Store)中的文件。
2.        文件链接附件:附件是链接到磁盘中的文件,没有拷贝到消息存储(Message Store)中。
3.        消息条目(Entry):系统中的消息可以注册为别一个消息的附件。
下面的代码演示了如何通过MMsvAttachmentManager提取消息中的附件:
//Extract attachments to specified path
void CMsgEngine::ExtractAttachmentL( const TDesC &aNewPath, CDesCArray &aFileNameArray, TMsvId aEntryId )
{
aFileNameArray.Reset();
CMsvEntry* msvEntry = iSession->GetEntryL( aEntryId );
CleanupStack::PushL( msvEntry );
if( !msvEntry->HasStoreL() )
{
CleanupStack::PopAndDestroy( msvEntry );
return;
}
CMsvStore *store = msvEntry->ReadStoreL();
CleanupStack::PushL( store );
MMsvAttachmentManager& attachManager = store->AttachmentManagerL();
RFs fileSession;
User::LeaveIfError( fileSession.Connect() );
CleanupClosePushL( fileSession );
for( TInt i = 0; i < attachManager.AttachmentCount(); ++i )
{
CMsvAttachment *attachment = attachManager.GetAttachmentInfoL( i );
CleanupStack::PushL( attachment );
TPtrC8 mime = attachment->MimeType();
CMsvAttachment::TMsvAttachmentType type = attachment->Type();
if( type != CMsvAttachment::EMsvMessageEntry )
{
TFileName newPath( aNewPath );
newPath.Append( attachment->AttachmentName() );
aFileNameArray.AppendL( attachment->AttachmentName() );
RFile file = attachManager.GetAttachmentFileL( i );
TInt size(0);
file.Size( size );
HBufC8 *buf = HBufC8::NewLC( size );
TPtr8 ptrBuf( buf->Des() );
file.Read( ptrBuf, size );
RFile newFile;
User::LeaveIfError ( newFile.Replace( fileSession, newPath, EFileWrite ) );
newFile.Write( ptrBuf );
newFile.Close();
CleanupStack::PopAndDestroy( buf );
}
CleanupStack::PopAndDestroy( attachment );
}
CleanupStack::PopAndDestroy( 3, msvEntry );
}
有人可能会注意到CMsvAttachment已经提供了AttachmentName()和FilePath()方法来提供附件的名称与路径,那为什么不使用BaflUtils:: CopyFile()等API直接复制?测试一下就可以发现这些附件是存储在私有目录下的,其它程序没有AllFiles是不能访问的,所以需要使用MMsvAttachmentManagerr::GetAttachmentFileL()返回的RFile来读取文件数据,另外注意返回的RFile是以只读的形式打开文件,所以不能对附件进行修改。

从CTelephony获取网络名

2009年09月2日,星期三

CNwNameCheck类描绘了如何使用CTelephony API获取当前网络名,注意这个例子仅为S60第三版手机所用,无法工作在老版本上。

要使用实例,则需要完成回调接口实现,并在构造CNwNameCheck实例时将类传递进去,这样回调函数就可以获得当前网络名了。

GetNetWorkName.cpp

CNwNameCheck::~CNwNameCheck()
{
	Cancel();
	delete iTelephony;
}

void CNwNameCheck::ConstructL(void)
{
    iTelephony = CTelephony::NewL();
    iTelephony->GetCurrentNetworkName(iStatus, iIdV1Pkg);
	SetActive();
}

CNwNameCheck::CNwNameCheck(MNwNameObserver& aObserver)
: CActive(EPriorityNormal),iObserver(aObserver),iIdV1Pkg(iIdV1)
{
	CActiveScheduler::Add(this);
}

void CNwNameCheck::RunL()
{
    iObserver.NetworkNameL(iIdV1.iNetworkName);

}

void CNwNameCheck::DoCancel()
{
	iTelephony->CancelAsync(CTelephony::EGetCurrentNetworkNameCancel);
}

GetNetWorkName.h

#include <Etel3rdParty.h>

class MNwNameObserver
	{
	public:
		virtual void NetworkNameL(const TDesC& aNwName) = 0;
	};

class CNwNameCheck : public CActive
  {
public:
    CNwNameCheck(MNwNameObserver& aObserver);
    void ConstructL(void);
	~CNwNameCheck();
private:
    void RunL();
    void DoCancel();
private:
    MNwNameObserver& 			iObserver;
    CTelephony* 			iTelephony;
    CTelephony::TNetworkNameV1  	iIdV1;
    CTelephony::TNetworkNameV1Pckg 	iIdV1Pkg;
   };

GPS指南针

2009年09月2日,星期三
  • 详细描述

应用程序GPS指南针演示了如何接收坐标以便定义行进方向。同时程序允许你定义当前移动速度和最大移动速度。

Image:Gps_compass.PNG

这个应用程序只有在运动时才能正确显示,手机朝一个方向移动得越快,获得的结果就越精确。

CCompassEngine类允许计算运动方向和手机速度,指南针的实现和数据显示都是自定义控件实现的:CCompassDrawer和CCompassDataDrawer

AppView计算了位置和屏幕上自定义控件的大小。根据AppView尺寸自定义控件在中间显示。。

S60 3rd下如何使用HookLogger查找内存泄漏错误?

2009年09月2日,星期三

近日,在一个S60 3rd的项目里,调试一个内存泄漏错误,总也找不到是哪里出了问题。想到以前曾碰到过一个HookLogger的工具可以检测内存泄漏,于是就下载过来。 试用了一下效果相当不错,很快就找到了发生错误的位置。下面具体描述在S60 3rd环境下怎么安装与使用HookLogger:

1、下载:
http://developer.symbian.com/main/downloads/files/HookLogger_Setup.zip

2、安装:(假定使用的是S60 3rd MR版)
解压HookLogger_Setup.zip后运行安装程序,按默认安装。

在S60 3rd下使用HookLogger,稍微有些问题,修改如下:
1) 在系统的环境变量设置里,添加环境变量EPOCROOT,其值为/Symbian/9.1/S60_3rd_MR/
2) (可用记事本)打开文件
C:/Program Files/Common Files/Symbian/tools/HookEUSER.pl
替换
my $cmd = “copy $hooks_src”;

my $cmd = “copy /”$hooks_src/”";
以及替换
$cmd = “$Bin/AttachDll $euser $hooks $hooked_euser”;

$cmd = “/”$Bin/AttachDll/” $euser $hooks $hooked_euser”;
保存后退出。
3)打开一个控制台(DOS窗口),改变当前目录为:
C:/Program Files/Common Files/Symbian/tools
然后运行
hookeuser winscw

3、使用:
先 启动HookLogger,然后启动Emulator。运行你的程序,再现MemLeak直到异常退出。这时,转到HookLogger的Heap页,点 击下面的按钮“List All Allocs”将列出发生内存泄漏的地址。然后双击某条信息即可查看明细情况,甚至可以打开源代码文件,非常方便!

详情可参考[注2]。

4、卸载:
参考2.3,运行
hookeuser -r winscw

评:HookLogger是一个好工具,在对内存泄漏毫无头绪时,可帮你迅速找到问题之所在。

阅读更多
个人分类: Symbian
上一篇Symbian开发简述(描述符)
下一篇memcpy和memmove的区别
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭