×
Namespaces

Variants
Actions

用S60 Touch UI API创建自定义音乐播放器

From Nokia Developer Wiki
Jump to: navigation, search
Article Metadata

代码示例
兼容于
文章
dougcn 在 13 Mar 2009 创建
最后由 hamishwillee 在 15 Dec 2011 编辑

Contents

概述

本文中,我们将学习不同的S60 Touch UI API来创建自定义音乐播放器。你可以扩展它添加更多的功能。这里,本文使用了Generic Button API, Toolbar API, Stylus Popup List APILongTapDetector API,使你能了解到如何利用这些丰富API集来创建广阔的应用程序。

用到哪些API和为什么要用

  • Generic Button API: 创建按钮以便播放或停止音乐曲目。
  • Toolbar API: 创建工具条提供同样的功能。
  • Stylus Popup List API: 给出浮动的触笔弹出菜单做同样的功能:播放和停止音乐曲目。
  • LongTapDetector API: 处理按钮上的长点击事件,解释其用途。
  • MdaAudioPlayerUtility API: 播放和停止音乐曲目。

My Music Player


创建音乐播放器核心工具类

AudioPlayer.h

#ifndef AUDIOPLAYER_H_
#define AUDIOPLAYER_H_
#include <e32std.h>
#include <MdaAudioSamplePlayer.h>
class CAudioPlayerUtility : public CBase, public MMdaAudioPlayerCallback
{
public:
static CAudioPlayerUtility* NewL(const TDesC& aFileName);
static CAudioPlayerUtility* NewLC(const TDesC& aFileName);
~CAudioPlayerUtility();
private:
CAudioPlayerUtility();
void ConstructL(const TDesC& aFileName);
public:
void Play();
void Stop();
public: // from MMdaAudioToneObserver
void MapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds& aDuration);
void MapcPlayComplete(TInt aError);
private:
CMdaAudioPlayerUtility* iPlayUtility;
};
 
#endif /* AUDIOPLAYER_H_ */

AudioPlayer.cpp

#include "AudioPlayer.h"
#include <MdaAudioTonePlayer.h>
#include <eikmenup.h>
CAudioPlayerUtility* CAudioPlayerUtility::NewL(const TDesC& aFileName)
{
CAudioPlayerUtility* self = NewLC(aFileName);
CleanupStack::Pop(self);
return self;
}
CAudioPlayerUtility* CAudioPlayerUtility::NewLC(const TDesC& aFileName)
{
CAudioPlayerUtility* self = new (ELeave) CAudioPlayerUtility();
CleanupStack::PushL(self);
self->ConstructL(aFileName);
return self;
}
CAudioPlayerUtility::~CAudioPlayerUtility()
{
if(iPlayUtility)
{
iPlayUtility->Stop();
iPlayUtility->Close();
}
delete iPlayUtility;
}
CAudioPlayerUtility::CAudioPlayerUtility()
{
}
void CAudioPlayerUtility::ConstructL(const TDesC& aFileName)
{
iPlayUtility = CMdaAudioPlayerUtility::NewFilePlayerL(aFileName, *this);
}
void CAudioPlayerUtility::Play()
{
iPlayUtility->Play();
}
void CAudioPlayerUtility::Pause()
{
iPlayUtility->Pause();
}
void CAudioPlayerUtility::Stop()
{
iPlayUtility->Stop();
}
void CAudioPlayerUtility::MapcPlayComplete(TInt /*aError*/)
{
}
void CAudioPlayerUtility::MapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds& /*aDuration*/)
{
if(aError == KErrNone)
{
iPlayUtility->SetVolume(iPlayUtility->MaxVolume());
}
}


按钮资源

...
#include <avkon.mbg>
//Button resource
RESOURCE AVKON_BUTTON r_first_button
{
flags = KAknButtonTextInsideFrame;
states =
{
AVKON_BUTTON_STATE
{
helptxt = "Play";
bmpfile = AVKON_BITMAP_FILE;
bmpid = EMbmAvkonQgn_indi_navi_arrow_right;
bmpmask = EMbmAvkonQgn_indi_navi_arrow_right_mask;
},
AVKON_BUTTON_STATE
{
flags = KAknButtonStateHasLatchedFrame;
bmpfile = AVKON_BITMAP_FILE;
bmpid = EMbmAvkonQgn_indi_navi_arrow_right;
bmpmask = EMbmAvkonQgn_indi_navi_arrow_right_mask;
}
};
}
RESOURCE AVKON_BUTTON r_second_button
{
flags = KAknButtonTextInsideFrame;
states =
{
AVKON_BUTTON_STATE
{
bmpfile = AVKON_BITMAP_FILE;
bmpid = EMbmAvkonQgn_note_error;
bmpmask = EMbmAvkonQgn_note_error_mask;
helptxt = "Stop";
}
};
}


工具条资源

// Add following resource definition for toolbar declared in EIK_APP_INFO
// 将下面的工具条定义添加到EIK_APP_INFO中
RESOURCE EIK_APP_INFO_EXT r_toolbar_ext
{
popup_toolbar = r_test_toolbar;
}
 
RESOURCE AVKON_TOOLBAR r_test_toolbar
{
flags = KAknToolbarFixed;
items =
{
TBAR_CTRL
{
type = EAknCtButton;
id = ECommand1; // 本例中,我们使用的命令集与AppUi::HandleCommandL中所用的相同。
control = AVKON_BUTTON
{
flags = KAknButtonTextInsideFrame;
states =
{
AVKON_BUTTON_STATE
{
txt = "Play";
helptxt = "Play me";
}
};
};
},
TBAR_CTRL
{
type = EAknCtButton;
id = ECommand2; // 本例中,我们使用的命令集与AppUi::HandleCommandL中所用的相同。
control = AVKON_BUTTON
{
flags = KAknButtonTextInsideFrame;
states =
{
AVKON_BUTTON_STATE
{
txt = "Stop";
helptxt = "Stop me";
}
};
};
}
};
}


触笔弹出菜单资源

//For stylus
RESOURCE STYLUS_POPUP_MENU r_stylus_popup_menu
{
items =
{
STYLUS_POPUP_MENU_ITEM
{
txt = "Play";
command = ECommand1;
},
STYLUS_POPUP_MENU_ITEM
{
txt = "Stop";
command = ECommand2;
}
};
}


用S60 Touch UI API实现音乐播放器

  • MCoeControlObserver接口继承自己定义的类,实现其纯虚方法HandleControlEventL()来接收和处理按钮事件。
  • MAknToolbarObserver接口继承自己定义的类,实现其纯虚方法OfferToolbarEventL()以接收和处理工具条事件。
  • MAknLongTapDetectorCallBack接口继承自己定义的类,实现其纯虚方法HandleLongTapEventL()以接收和处理LongTap事件。
  • MEikMenuObserver接口继承自己定义的类,实现其纯虚方法ProcessCommandL()以接收和处理触笔弹出菜单(Stylus Popup Menu)命令。
  • 声明CAknButton型的对象,用它来为本类设置观察者,处理Play和Stop按钮事件。
  • 声明CAknLongTapDetector型的对象,用它来为本类设置观察者,处理长时间点击检测。
  • 为触笔弹出菜单(Stylus Popup Menu)声明CAknStylusPopUpMenu类型的对象。
  • 为Audio Player Utility声明CAudioPlayerUtility类型的对象。

MusicPlayerAppView.h

...
//For Toolbar API
#include <AknToolbar.h>
#include <akntoolbarobserver.h>
//For Longtap detection
#include <aknlongtapdetector.h>
//For Stylus
#include <aknstyluspopupmenu.h>
#include <EIKMOBS.H>
//For Generic Button
#include <aknbutton.h>
//For Audio Player Utility
#include "AudioPlayer.h"
....
// CLASS DECLARATION
class CMusicPlayerAppView : public CCoeControl, public MCoeControlObserver, public MAknToolbarObserver, public MAknLongTapDetectorCallBack, public MEikMenuObserver
{
....
virtual void HandleControlEventL(CCoeControl* aControl,TCoeEvent aEventType);
TInt CountComponentControls() const;
CCoeControl* ComponentControl(TInt aIndex) const;
void CreateButtonUsingResourceL();
 
//From MAknToolbarObserver
void OfferToolbarEventL(TInt aCommand);
 
virtual void HandleLongTapEventL(const TPoint& aPenEventLocation, const TPoint& aPenEventScreenLocation);
 
//For stylus
void ProcessCommandL(TInt aCommandId);
void SetEmphasis(CCoeControl* /*aMenuControl*/,TBool /*aEmphasis*/)
{
}
private:
//For Buttons
CAknButton* iPlayButton;
CAknButton* iStopButton;
 
//For Audio Player
CAudioPlayerUtility* iMyAudioPlayer;
 
//For Long Tap Detection
CAknLongTapDetector* iLongTapDetector;
 
//For Stylus Popup Menu
CAknStylusPopUpMenu* iStylusPopupMenu;
};

MusicPlayerAppView.cpp

  • ConstructL()调用创建按钮,如下所示。
  • 定义LongTapDetection对象
  • 定义Audio Player Utility对象
  • 为工具条设置观察者
// -----------------------------------------------------------------------------
// CMusicPlayerAppView::ConstructL()
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CMusicPlayerAppView::ConstructL(const TRect& aRect)
{
// Create a window for this application view
CreateWindowL();
 
iLongTapDetector = CAknLongTapDetector::NewL(this);
 
// Set the windows size
SetRect(aRect);
 
CreateButtonUsingResourceL();
 
iMyAudioPlayer = CAudioPlayerUtility::NewL(KMusicFile);
 
//Set this to toolbar observer - We will receive events in OfferToolbarEventL
if(STATIC_CAST(CMusicPlayerAppUi*, CEikonEnv::Static()->EikAppUi())->CurrentFixedToolbar())
{
STATIC_CAST(CMusicPlayerAppUi*, CEikonEnv::Static()->EikAppUi())->CurrentFixedToolbar()->SetToolbarObserver(this);
}
 
// Activate the window, which makes it ready to be drawn
ActivateL();
}


  • 创建通用按钮Play和Stop,给它们设置矩形框大小
  • 给按钮设置"this"为观察者,最终我们在HandleControlEventL()中接收到回调。
void CMusicPlayerAppView::CreateButtonUsingResourceL()
{
iPlayButton = CAknButton::NewL();
iPlayButton->ConstructFromResourceL(R_FIRST_BUTTON);
iPlayButton->SetContainerWindowL(*this);
iPlayButton->SetRect(TRect ( TPoint(100,130), TSize(80,80) ) );
iPlayButton->SetObserver(this);
iPlayButton->MakeVisible(ETrue);
iPlayButton->ActivateL();
 
iStopButton = CAknButton::NewL();
iStopButton->ConstructFromResourceL(R_SECOND_BUTTON);
iStopButton->SetContainerWindowL(*this);
iStopButton->SetRect(TRect ( TPoint(180,130), TSize(80,80) ) );
iStopButton->SetObserver(this);
iStopButton->MakeVisible(ETrue);
iStopButton->ActivateL();
}
  • 我们将处理按钮回调事件,如下面HandleControlEventL所示:
void CMusicPlayerAppView::HandleControlEventL( CCoeControl* aControl, 
TCoeEvent aEventType )
{
switch ( aEventType )
{
case EEventStateChanged:
{
if(aControl == iPlayButton)
{
if(iPlayButton->State()->Flags()!= KAknButtonStateHasLatchedFrame)
{
if(iMyAudioPlayer)
iMyAudioPlayer->Pause();
}
else
{
if(iMyAudioPlayer)
iMyAudioPlayer->Play();
}
 
if(iStopButton->State()->Flags()==KAknButtonStateHasLatchedFrame)
{
iStopButton->SetCurrentState(KAknButtonTextInsideFrame,ETrue);
}
}
else if(aControl ==iStopButton)
{
if(iMyAudioPlayer)
{
iMyAudioPlayer->Stop();
}
if(iPlayButton->State()->Flags()==KAknButtonStateHasLatchedFrame)
{
iPlayButton->SetCurrentState(KAknButtonTextInsideFrame,ETrue);
}
}
}
break;
default:
break;
}
}


  • 定义下面的函数以返回按钮控件
TInt CMusicPlayerAppView::CountComponentControls() const
{
return 2; // return number of controls inside this container
}
 
CCoeControl* CMusicPlayerAppView::ComponentControl(TInt aIndex) const
{
switch ( aIndex )
{
case 0:
return iPlayButton;
case 1:
return iStopButton;
default:
return NULL;
}
}


处理Long Tap Detection

从HandlePointerEventL函数传递事件到LongTap Detection

// -----------------------------------------------------------------------------
// CMusicPlayerAppView::HandlePointerEventL()
// Called by framework to handle pointer touch events.
// Note: although this method is compatible with earlier SDKs,
// it will not be called in SDKs without Touch support.
// -----------------------------------------------------------------------------
//
void CMusicPlayerAppView::HandlePointerEventL(
const TPointerEvent& aPointerEvent)
{
 
iLongTapDetector->PointerEventL(aPointerEvent);
// Call base class HandlePointerEventL()
CCoeControl::HandlePointerEventL(aPointerEvent);
}


处理Long Tap Detection事件

  • 这里我们演示长按检测中显示触笔弹出菜单(Stylus Popup menu),如下:
void CMusicPlayerAppView::HandleLongTapEventL( const TPoint& aPenEventLocation, 
const TPoint& aPenEventScreenLocation )
{
if(!iStylusPopupMenu)
{
iStylusPopupMenu = CAknStylusPopUpMenu::NewL( this , aPenEventLocation);
TResourceReader reader;
iCoeEnv->CreateResourceReaderLC(reader,R_STYLUS_POPUP_MENU);
iStylusPopupMenu->ConstructFromResourceL(reader);
CleanupStack::PopAndDestroy();
}
iStylusPopupMenu->ShowMenu();
iStylusPopupMenu->SetPosition(aPenEventLocation);
}


处理触笔弹出菜(Stylus Popup Menu)单命令

void CMusicPlayerAppView::ProcessCommandL(TInt aCommand)
{
if (aCommand == ECommand1)
{
if(iMyAudioPlayer)
{
iMyAudioPlayer->Play();
}
if(iPlayButton->State()->Flags()!=KAknButtonStateHasLatchedFrame)
{
iPlayButton->SetCurrentState(KAknButtonStateHasLatchedFrame,ETrue);
}
if(iStopButton->State()->Flags()==KAknButtonStateHasLatchedFrame)
{
iStopButton->SetCurrentState(KAknButtonTextInsideFrame,ETrue);
}
}
else if (aCommand == ECommand2)
{
if(iMyAudioPlayer)
{
iMyAudioPlayer->Stop();
}
if(iPlayButton->State()->Flags()==KAknButtonStateHasLatchedFrame)
{
iPlayButton->SetCurrentState(KAknButtonTextInsideFrame,ETrue);
}
}
else
{
CAknInformationNote* info = new (ELeave) CAknInformationNote;
info->ExecuteLD(_L("Outside Stylus Popup!!!"));
}
}

销毁

  • 确信在该类的析构函数中删除了按钮、长按检测、声音播放、触笔弹出菜单等对象。
// -----------------------------------------------------------------------------
// CMusicPlayerAppView::~CMusicPlayerAppView()
// Destructor.
// -----------------------------------------------------------------------------
//
CMusicPlayerAppView::~CMusicPlayerAppView()
{
delete iPlayButton;
delete iStopButton;
if(iMyAudioPlayer)
{
delete iMyAudioPlayer;
iMyAudioPlayer = NULL;
}
if(iLongTapDetector)
{
delete iLongTapDetector;
iLongTapDetector = NULL;
}
if(iStylusPopupMenu)
{
delete iStylusPopupMenu;
iStylusPopupMenu = NULL;
}
}


有用的函数

Generic Button API

  • ConstructFromResourceL()
  • SetCurrentState()
  • SetFlags()
  • Flags()

LongTapDetector API

  • PointerEventL()

Stylus Popup List API

  • ShowMenu()
  • SetPosition()

MAknToolbarObserver

  • OfferToolbarEventL()

MAknLongTapDetectorCallBack

  • HandleLongTapEventL()

MCoeControlObserver

  • HandleControlEventL()


关键点

头文件

  • #include <AknButton.h>
  • #include <akntoolbarobserver.h>
  • #include <AknToolbar.h>
  • #include <akntoolbarextension.h>
  • #include <aknlongtapdetector.h>
  • #include <aknstyluspopupmenu.h>
  • #include <EIKMOBS.H>
  • #include "AudioPlayer.h"

  • CAknButton
  • CAknButtonState
  • CAknLongTapDetector
  • CAknStylusPopUpMenu
  • CAudioPlayerUtility
  • MCoeControlObserver
  • MAknToolbarObserver
  • MAknLongTapDetectorCallBack

库文件

  • eikcoctl.lib
  • mediaclientaudio.lib

样例应用


相关链接


参考列表

This page was last modified on 15 December 2011, at 09:23.
73 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×