Namespaces

Variants
Actions

Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries over the next few weeks. Thanks for all your past and future contributions.

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

From 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 06:23.
64 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.

×