根据以往Symbian设计的经验,Recognizer将被用来识别与文件绑定的MIME类型。这是用来处理特殊类型数据的步骤之一。相关知识可以参考Nokia那篇著名的《guide for application developer on document handler》文档,在symbian sdk安装目录下面的Series60Doc目录下面可以找到他。 Recognizer也能够用来实现应用程序的开机自启动,当然这不是Recognizer的本意。但是,很危险的是,如果recognizer出了问题,手机将无法正常启动,而且你必须要重新到当地的Nokia客服部门重新刷机。 下面的代码是用于EZBoot应用的,这些代码本身有很好的说明,所以我不再详细解释。 注意,出现在头文件和mmp文件中的0x101Fxxxx这个值需要用你自己项目的UID替换。
头文件源码:
////////////////////////////////////////////////////////////////////////////// // // EZ-Boot // ////////////////////////////////////////////////////////////////////////////// // Boot & Recognizer Module // by NewLC (http://www.newlc.com) ////////////////////////////////////////////////////////////////////////////// // File : ezrecog.h // Compatibility: Symbian OS v6.1 // History: // 2003.07.26: EBS : Creation // 2003.08.12: EBS : Integration in EZBoot // 2003.09.01: EBS : Add boot file recognition // 2003.10.28: EBS : Cleanup and comment //////////////////////////////////////////////////////////////////////////////
#include <apmrec.h> // CApaDataREcognizerType
#define KUidRecog 0x1xxxxxxx // Use your own value here !!!
class CRecog : public CApaDataRecognizerType { public: CRecog(); TUint PreferredBufSize(); TDataType SupportedDataTypeL(TInt aIndex) const; static void BootUp(); static TInt BootUpKick(TAny *aParam); static void BootUpKickL(); private: void DoRecognizeL(const TDesC& aName, const TDesC8& aBuffer); TBool HeaderRecognized(const TDesC8& aBuf); TBool NameRecognized(const TDesC& aName); };
实现的源代码:
////////////////////////////////////////////////////////////////////////////// // // EZ-Boot // ////////////////////////////////////////////////////////////////////////////// // Boot & Recognizer Module // by NewLC (http://www.newlc.com) ////////////////////////////////////////////////////////////////////////////// // File : ezrecog.cpp // Compatibility: Symbian OS v6.1 // History: // 2003.07.26: EBS : Creation // 2003.08.12: EBS : Integration in EZBoot // 2003.09.01: EBS : Add boot file recognition // 2003.10.28: EBS : Cleanup and comment //////////////////////////////////////////////////////////////////////////////
#include <e32std.h> #include <e32base.h> #include <e32def.h> #include <f32file.h> #include <apacmdln.h> #include <apgcli.h> #include <apmrec.h> #include <apmstd.h> #include "ezrecog.h"
////////////////////////////////////////////////////////////////////////////// // // Recognition Definitions // /////////////////////////////////////////////////////////////////////////////
// The MIME Type that will be recognized _LIT8(KEzbMimeType,"text/vnd.newlc.ezboot");
// The file extension that shall be used by data we are recognizing _LIT(KEzbFileExtension,".boot"); // The data header that identifies EZBoot data _LIT8(KEzbDataHeader,"EZBoot:");
// The priority of the recognizer, can be EHigh, ENormal, ELow #define KEzRecognizerPriority CApaDataRecognizerType::ENormal
// The size of the data buffer that will be passed to the recognizer // so that it performs the recognition #define KEzRecognizerBufferSize 7
// The recognizer UID const TUid KUidEzBoot={KUidRecog};
////////////////////////////////////////////////////////////////////////////// // // Boot Definitions // /////////////////////////////////////////////////////////////////////////////
// The application we want to boot (here the EZBoot server) _LIT(KEzBootExe,"\\system\\programs\\ezboot\\ezbootsrv.exe");
// The thread name that will used to launch the above EXE _LIT(KBootUpThreadName,"EzBootThr");
////////////////////////////////////////////////////////////////////////////// /// DLL entry point. /// \param aReason can be ignored. /// \return Always KErrNone ///////////////////////////////////////////////////////////////////////////// GLDEF_C TInt E32Dll(TDllReason /*aReason*/) { return(KErrNone); }
////////////////////////////////////////////////////////////////////////////// /// Recognizer instanciation. This function MUST be the first one defined /// for the recognizer. /// \return a pointer on a new allocated recognizer instance ////////////////////////////////////////////////////////////////////////////// EXPORT_C CApaDataRecognizerType *CreateRecognizer() { // Create a recognizer instance CApaDataRecognizerType *me = new CRecog(); // Start all the boot code under a trap harness // This is pure boot code and has (normally) nothing to do // in a recognizer CRecog::BootUp(); return(me); }
////////////////////////////////////////////////////////////////////////////// /// Recognizer Constructor. /// Initialise the internal data member iCountDataTypes with the number of /// MIME types that will be recognized. Set the recognizer priority. ////////////////////////////////////////////////////////////////////////////// CRecog::CRecog() :CApaDataRecognizerType(KUidEzBoot,KEzRecognizerPriority) { iCountDataTypes=1; }
////////////////////////////////////////////////////////////////////////////// /// Returns the size of the data buffer that will be passed to the recognition /// function (used by the recognition framework) /// \see DoRecognizeL() /// \return size of the data buffer ////////////////////////////////////////////////////////////////////////////// TUint CRecog::PreferredBufSize() { return(KEzRecognizerBufferSize); }
////////////////////////////////////////////////////////////////////////////// /// Returns the MIME type that our recognizer is able to manage /// (used by the recognition framework) /// \param aIndex: the index of the MIME type to return (will be always 1 for /// a recognizer that handles a single MIME type) /// \return a MIME type ////////////////////////////////////////////////////////////////////////////// TDataType CRecog::SupportedDataTypeL(TInt /*aIndex*/) const { return(TDataType(KEzbMimeType)); }
///////////////////////////////////////////////////////////////////////////// /// The recognition function. The result of the recognition is stored in /// the iConfidence data member. /// \param aName: the name of the file that contain the data to analyze /// \param aBuffer: the data buffer /// \see PreferredBufSize() ///////////////////////////////////////////////////////////////////////////// void CRecog::DoRecognizeL(const TDesC& aName, const TDesC8& aBuffer) { // Initialise the result status iConfidence = ENotRecognized; iDataType = TDataType(KEzbMimeType); // Check that we got the required amount of data if(aBuffer.Length()<KEzRecognizerBufferSize) return;
// Check that the file name corresponds to our criteria TBool nameOK(EFalse); nameOK=NameRecognized(aName); // Check that the data corresponds to our criteria TBool headerOK(EFalse); headerOK=HeaderRecognized(aBuffer); // Conclude: // - if file name and data are OK then the data are certainly recognized // - if only the data are recognized, then this is only a possibility // - else the data have not been recognized if( nameOK && headerOK) { iConfidence=ECertain; } else if(!nameOK && headerOK) { iConfidence=EPossible; } else return; }
///////////////////////////////////////////////////////////////////////////// /// The file name recognition function. This functions checks whether the /// provided filename matches our criteria (here we want it to have the .boot /// extension) /// \param aName: the name to check /// \return ETrue if the file is OK ///////////////////////////////////////////////////////////////////////////// TBool CRecog::NameRecognized(const TDesC& aName) { TBool res=EFalse; if(aName.Length()>5) { TInt dotPos = aName.LocateReverse( '.' ); if (dotPos != KErrNotFound) { TInt extLength = aName.Length() - dotPos; HBufC* ext = aName.Right( extLength ).AllocL(); CleanupStack::PushL( ext ); if ( ext->CompareF(KEzbFileExtension) == 0 ) { res = ETrue; } CleanupStack::PopAndDestroy(); // ext } } return(res); }
///////////////////////////////////////////////////////////////////////////// /// The data recognition function. This functions checks whether the /// provided data starts with our data header /// extension /// \param aBuf: the data buffer to check /// \return ETrue if the data are OK ///////////////////////////////////////////////////////////////////////////// TBool CRecog::HeaderRecognized(const TDesC8& aBuf) { if(aBuf.Find(KEzbDataHeader)==0) return ETrue; return EFalse; }
///////////////////////////////////////////////////////////////////////////// /// The Boot code (non leaving). Create a new thread and kicks the real /// boot code. /// \see BootUpKick() ///////////////////////////////////////////////////////////////////////////// void CRecog::BootUp() { // Create a new thread RThread* bootThread = new RThread(); if(bootThread) { TInt res=KErrNone; // and Start it res=bootThread->Create(KBootUpThreadName, CRecog::BootUpKick, KDefaultStackSize, KMinHeapSize, KMinHeapSize, NULL, EOwnerThread); if(res==KErrNone) { bootThread->Resume(); bootThread->Close(); } else { delete bootThread; } } }
///////////////////////////////////////////////////////////////////////////// /// The threaded boot code (non leaving). Actually just create a cleanup /// stack and call a non-leaving implementation of the boot code /// \see BootUp() /// \see BootUpKickL() /// \param aParam: not used but required as a thread entry point /// \return thread result ///////////////////////////////////////////////////////////////////////////// TInt CRecog::BootUpKick(TAny* /*aParam*/) { TInt err=KErrNoMemory; // Create a cleanup stack CTrapCleanup *cleanup=CTrapCleanup::New(); if(cleanup) { // and Kick under a trap harness TRAP(err,CRecog::BootUpKickL()); delete cleanup; } return err; }
///////////////////////////////////////////////////////////////////////////// /// The Boot code. ///////////////////////////////////////////////////////////////////////////// void CRecog::BootUpKickL() { // Get the full path (including drive letter) // to the boot server RFs fs; User::LeaveIfError(fs.Connect()); CleanupClosePushL(fs); TFindFile findFile(fs); User::LeaveIfError(findFile.FindByDir(KEzBootExe,KNullDesC));
// Connect to the Apparc server // and start our server RApaLsSession ls; User::LeaveIfError(ls.Connect()); CleanupClosePushL(ls); CApaCommandLine *cmd = CApaCommandLine::NewLC(); cmd->SetLibraryNameL(findFile.File()); cmd->SetCommandL(EApaCommandOpen); User::LeaveIfError(ls.StartApp(*cmd));
// Delete all stuff on the cleanup stack CleanupStack::PopAndDestroy(3); }
MMP文件的源代码:
TARGET ezrecog.mdl TARGETTYPE mdl TARGETPATH \system\recogs
UID 0x10003A19 0x101Fxxxx
USERINCLUDE ..\inc SYSTEMINCLUDE \epoc32\include
SOURCEPATH ..\src SOURCE ezrecog.cpp
LIBRARY euser.lib LIBRARY apmime.lib apparc.lib apgrfx.lib LIBRARY efsrv.lib
|