//通过RApaLsSession的GetAllApps接口可以得到所有系统上应用程序的信息,包括UID,Full path name,Caption ,在其中一一比对系统摄像头所在的文件路径,找到其UID。 _LIT(KCameraAppString , "z:\\sys\\bin\\cameraapp.exe") ; //Nokia 5800上测试通过,其他型号这个路径可能不一样 class CApaDocument; class CEikonEnv; /**************************** // sylar // 2010.4.22 PM 12:18:21 // cug@live.cn // CLaunchCamera 照相类 用于打开照相机和拍照后的处理 //调用方法: // CLaunchCamera *camera_launcher = CLaunchCamera::NewL(CEikonEnv::Static()); camera_launcher->OpenCamera(); //当用户完成摄像功能后,会通过 MApaEmbeddedDocObserver 类的回调函数NotifyExit进行通知,所以这里进行继承 ****************************/ class CLaunchCamera: public MApaEmbeddedDocObserver { public: CLaunchCamera(); virtual ~CLaunchCamera(); static CLaunchCamera * NewL(MCameraEvenCallBack * pEvenCallBack, CEikonEnv * pEikonEnv); static CLaunchCamera * NewLC(MCameraEvenCallBack * pEvenCallBack, CEikonEnv * pEikonEnv); TBool OpenCamera(); //启动照相机程序 //NOTE: some class functions should not be used in MCameraEvenCallBack, they lead crash void CloseCamera(); TBool EnableCloseCamera(); private: void ConstructL(MCameraEvenCallBack * pEvenCallBack, CEikonEnv * pEikonEnv); //From MApaEmbeddedDocObserver void NotifyExit(TExitMode aMode); //回调函数,照相后处理 void FindNewFile(); TBool GetLastFile(TFileName & filePath, TTime & fileTime); TBool GetLastNewFile(TFileName & filePath, TTime & fileTime); TBool FindCamera(TApaAppInfo & appInfo); private: CEikonEnv * m_pEikonEnv; //MCameraEvenCallBack * m_pCallBack; 这个没用 CApaDocument * m_pAppdoc; CEikProcess * m_pProcess; TBool m_bCloseCamera; }; /************************ 二级构造函数 &析构 *****************/ CLaunchCamera* CLaunchCamera::NewL(CEikonEnv * pEikonEnv) { CLaunchCamera* self = NewLC(pEikonEnv); CleanupStack::Pop(self); return self; } CLaunchCamera* CLaunchCamera::NewLC(CEikonEnv * pEikonEnv) { CLaunchCamera* self = new (ELeave) CLaunchCamera; CleanupStack::PushL(self); self->ConstructL(pEvenCallBack, pEikonEnv); return self; } void CLaunchCamera::ConstructL(MCameraEvenCallBack * pEvenCallBack, CEikonEnv * pEikonEnv) { m_pProcess = NULL; m_pAppdoc = NULL; m_pCallBack = pEvenCallBack; m_pEikonEnv = pEikonEnv; m_bCloseCamera = FALSE; } void CLaunchCamera::CloseCamera() { if (m_pProcess) { m_pProcess->DestroyDocument(m_pAppdoc); m_pProcess = NULL; m_pAppdoc = NULL; } m_bCloseCamera = TRUE; } /************************ 函数作用:找到照相机对应的进程 *****************/ static TBool CLaunchCamera::FindCamera(TApaAppInfo & appInfo) { RApaLsSession apaTmpLs; User::LeaveIfError(apaTmpLs.Connect()); CleanupClosePushL(apaTmpLs); //压入自动清理栈,请看symbian错误处理机制 User::LeaveIfError(apaTmpLs.GetAllApps()); TBool bFindCamera = FALSE; appInfo.iFullName.FillZ(appInfo.iFullName.MaxLength()); appInfo.iFullName.Zero(); while (apaTmpLs.GetNextApp(appInfo) == KErrNone) { appInfo.iFullName.LowerCase(); TInt nTmpID = appInfo.iFullName.Compare(KCameraAppString); if (nTmpID == 0) { bFindCamera = TRUE; //找到 break; } appInfo.iFullName.FillZ(appInfo.iFullName.MaxLength()); appInfo.iFullName.Zero(); } CleanupStack::PopAndDestroy(); // 清理 return bFindCamera; } //供外部调用 TBool CLaunchCamera::OpenCamera() { if( m_pEikonEnv == NULL ) return FALSE ; TApaAppInfo appInfo; if( FindCamera( appInfo) == FALSE ) return FALSE ; m_pProcess = m_pEikonEnv->Process(); m_pAppdoc = m_pProcess->AddNewDocumentL(appInfo.iFullName, appInfo.iUid);//启动照相机 TApaDocCleanupItem cleanup(m_pProcess, m_pAppdoc); CleanupStack::PushL(cleanup); m_pAppdoc->NewDocumentL(); CleanupStack::Pop(); // cleanup m_bCloseCamera = FALSE ; m_pAppdoc->EditL(this, EFalse ); return TRUE ; } //这个是系统的回调函数,如果用户进行了拍照/摄像/取消操作之后都会运行到这里。 static void CLaunchCamera::NotifyExit(TExitMode aMode) { if (aMode == EKeepChanges) //拍照或者摄像 { //不能在这里调,否则设备crash //m_pProcess->DestroyDocument(m_pAppdoc) ; FindNewFile(); } m_bCloseCamera = TRUE; } //下面的函数作用是找到照片所在的路径 // Function name : CLaunchCamera::FindNewFile // Description : Search the last new files //if find the last new file, call Camera_HandleFile to caller // Return type : void void CLaunchCamera::FindNewFile() { if (m_pCallBack == NULL) return; TFileName PhoneIamgePath; TFileName MemoryIamgePath; TFileName PhoneVideoPath; TFileName MemoryVideoPath; //需要查找的路径 PhoneIamgePath.Append(PathInfo::PhoneMemoryRootPath()); PhoneIamgePath.Append(PathInfo::ImagesPath()); MemoryIamgePath.Append(PathInfo::MemoryCardRootPath()); MemoryIamgePath.Append(PathInfo::ImagesPath()); PhoneVideoPath.Append(PathInfo::PhoneMemoryRootPath()); PhoneVideoPath.Append(PathInfo::VideosPath()); MemoryVideoPath.Append(PathInfo::MemoryCardRootPath()); MemoryVideoPath.Append(PathInfo::VideosPath()); TTime tFileTime(0); TTime tLastFileTime(0); TInt nIndex = -1; //查找最新时间的文件 //find phone card image if (GetLastFile(PhoneIamgePath, tFileTime) == TRUE) { if (tFileTime > tLastFileTime) { tLastFileTime = tFileTime; nIndex = 0; } } //find memory card image if (GetLastFile(MemoryIamgePath, tFileTime) == TRUE) { if (tFileTime > tLastFileTime) { tLastFileTime = tFileTime; nIndex = 1; } } //find phone memory video file if (GetLastFile(PhoneVideoPath, tFileTime) == TRUE) { if (tFileTime > tLastFileTime) { tLastFileTime = tFileTime; nIndex = 2; } } //find memory card video files if (GetLastFile(MemoryVideoPath, tFileTime) == TRUE) { if (tFileTime > tLastFileTime) { tLastFileTime = tFileTime; nIndex = 3; } } //判断是那个目录下的文件 switch (nIndex) { case 0: m_pCallBack->Camera_HandleFile(CFT_Image, PhoneIamgePath); ////想怎么处理就怎么处理去把。就是把图片传给了另一个类m_pCallBack的方法Camera_HandleFile去处理而已。不用想的太麻烦 break; case 1: m_pCallBack->Camera_HandleFile(CFT_Image, MemoryIamgePath); break; case 2: m_pCallBack->Camera_HandleFile(CFT_Video, PhoneVideoPath); break; case 3: m_pCallBack->Camera_HandleFile(CFT_Video, MemoryVideoPath); break; default: m_pCallBack->Camera_HandleFile(CFT_NoFind, TFileName(0)); break; } } ////////////////////////////////////////////////////////////////////////// //查找最新的图像文件,只查找到二级目录 // ////////////////////////////////////////////////////////////////////////// TBool CLaunchCamera::GetLastFile(TFileName & filePath , TTime & fileTime) { RFs sessionRFs; User::LeaveIfError(sessionRFs.Connect()); CDir* FileList; CDir* dirList ; //读出文件夹下文件信息,并对所有的文件进行降序排列 TInt nError = sessionRFs.GetDir(filePath,KEntryAttNormal, ESortByDate|EDescending , FileList , dirList); if( nError != KErrNone ) { sessionRFs.Close() ; return FALSE; } else if( nError == KErrNone ) { TFileName tmpFileName(0) ; TTime tmpTime(0) ; TTime tLastFileTime(0) ; TFileName tLastFile(0) ; //file if( FileList->Count() > 0 ) { tmpFileName.FillZ(KMaxFileName) ; tmpFileName.Zero() ; tmpFileName.Append(filePath) ; tmpFileName.Append((*FileList)[0].iName) ; //get file modification time sessionRFs.Modified(tmpFileName , tmpTime ) ; if( tmpTime > tLastFileTime ) { tLastFileTime = tmpTime ; tLastFile.FillZ(KMaxFileName) ; tLastFile.Zero() ; tLastFile.Append(tmpFileName) ; } } delete FileList ; //dir TInt nDirCount = dirList->Count() ; for( int i = 0 ; i< nDirCount ; i++ ) { tmpFileName.FillZ(KMaxFileName) ; tmpFileName.Zero() ; tmpFileName.Append(filePath) ; tmpFileName.Append((*dirList)[i].iName) ; tmpFileName.Append(_L("\\")) ; if( GetLastNewFile( tmpFileName , tmpTime ) == TRUE ) { if( tmpTime > tLastFileTime ) { tLastFileTime = tmpTime ; tLastFile.FillZ(KMaxFileName) ; tLastFile.Zero() ; tLastFile.Append(tmpFileName) ; } } } delete dirList; //是否找到新的文件 if( tLastFileTime > TTime(0) ) { filePath.FillZ(KMaxFileName) ; filePath.Zero() ; filePath.Append(tLastFile) ; fileTime = tLastFileTime ; } else { sessionRFs.Close() ; return FALSE ; } } sessionRFs.Close() ; return TRUE ; } //用KEntryAttNormal只查找目录中的文件 TBool CLaunchCamera::GetLastNewFile(TFileName & filePath , TTime & fileTime) { RFs sessionRFs; User::LeaveIfError(sessionRFs.Connect()); CDir* dirList; //读出文件夹下文件信息,并对所有的文件进行降序排列 TInt nError = sessionRFs.GetDir(filePath,KEntryAttNormal, ESortByDate|EDescending,dirList); if( nError != KErrNone ) { sessionRFs.Close() ; return FALSE; } else if( dirList->Count() > 0 ) { //get filename filePath.Append((*dirList)[0].iName) ; //get file modification time sessionRFs.Modified(filePath , fileTime ) ; delete dirList; } else { sessionRFs.Close() ; return FALSE; } sessionRFs.Close() ; return TRUE ; }