如何调用S60的系统摄像头功能进行拍照与摄像?zz

nokia的论坛上提供了调用S60系统摄像头的示例代码,但在使用中我们发现,(1)需要指定系统摄像头appUID,因为不同型号的S60手机系统摄像头appUID可能不同,就需要开发者跟据不同手机的摄像头ID进行适配;(2)没有提供拍照后的文件信息,当完成拍照或录像后没法知道所对应的影像文件;(3)完成摄像后没有关闭摄像头,这样在某些手机上(如N70)无法第二次启动摄像头;针对存在的这三个问题,我们做了如下工作:

Ø        自动查找摄像头appUID

Ø        打开摄像头

Ø        查找完成操作后的相关影像文件;

Ø        关闭摄像头的系统调用;

 

一、自动查找摄像头appUID

 

    通过RApaLsSessionGetAllApps接口可以得到所有系统上应用程序的信息,包括UIDFull path nameCaption ,在其中一一比对系统摄像头所在的文件路径,找到其UID

 

具体代码见附录二中的CLaunchCamera::FindCamera

 

其中对KCameraAppString定义说明如下:

1KCameraAppString定义了系统摄像头在设备上的路径

模拟器及大部分S60手机上定义如下(测试通过了6681,7610):

_LIT(KCameraAppString , "z://system//apps//camcorder//camcorder.app") ;

N70手机上,要定义如下:

_LIT(KCameraAppString , "z://system//apps//cammojave//cammojave.app") ;       

2、如果FindCamera返回TURE,则找到系统摄像头

 

二、打开摄像头
 

通过系统调用,打开设备的摄像头,具体的代码见附录二中的CLaunchCamera::OpenCamera()

 

三、查找完成操作后的相关影像文件
 

    当用户完成摄像功能后,会通过MApaEmbeddedDocObserver类的回调函数NotifyExit进行通知,改函数具体定义如下:

    void NotifyExit(TExitMode aMode)

其中:

enum TExitMode {

   EKeepChanges,

   ERevertToSaved,

   ENoChanges,

   EEmpty

  };

EKeepChanges表示用户进行了拍照或摄像操作,ENoChanges表示用户取消了拍照或摄像操作,其它两个不用处理。

 

在这个唯一可以知道用户进行了操作的通知函数中,没有所拍照的图像文件路径信息,因此我们只有通过遍例设备上的图像文件来找到最新的拍照文件。遍例包括对设备存储分区和存储卡分区(即C盘与E盘),PathInfo类提供了对这两个分区的图像文件与影像文件的访问路径,分别是:

 

        TFileName PhoneIamgePath ;

        TFileName PhoneVideoPath ;

 

        TFileName MemoryIamgePath ;

        TFileName MemoryVideoPath ;

 

        PhoneIamgePath.Append(PathInfo::PhoneMemoryRootPath()) ;

        PhoneIamgePath.Append(PathInfo::ImagesPath());

 

        PhoneVideoPath.Append(PathInfo::PhoneMemoryRootPath()) ;

        PhoneVideoPath.Append(PathInfo::VideosPath()) ;

 

        MemoryIamgePath.Append(PathInfo::MemoryCardRootPath()) ;

        MemoryIamgePath.Append(PathInfo::ImagesPath()) ;

 

        MemoryVideoPath.Append(PathInfo::MemoryCardRootPath()) ;

        MemoryVideoPath.Append(PathInfo::VideosPath()) ;

 

同时还要注意有些手机可能会对拍的图片上边的文件夹中再进行分类存储,所以查找的时候查找到以上目录的二级子目录就可以满足要求。

查找使用RFs类的GetDir接口,具体定义如下:

 TInt GetDir(const TDesC& aName,TUint anEntryAttMask,TUint anEntrySortKey,CDir*& anEntryList) const;

 TInt GetDir(const TDesC& aName,TUint anEntryAttMask,TUint anEntrySortKey,CDir*& anEntryList,CDir*& aDirList) const;

 

其中:

aName:文件夹的完整路径

anEntryAttMask:查找文件选项,这里使用KEntryAttNormal

anEntrySortKey:查找结果的排序选项,这里使用ESortByDate|EDescending,即按时间进行降序排序

anEntryList:查找到的文件例表;

aDirList:查找到的文件目录例表;

 

具体查找代码见附录二中的CLaunchCamera::GetLastFileLaunchCamera::GetLastNewFile

 

四:关闭摄像头的系统调用
 

   在使用完摄像头后要调用CEikProcessDestroyDocument接口,删除对系统摄像头的调用,否则在有些手机上无法第二次调用摄像,但要注意的时DestroyDocument接口不能在回调通知函数NotifyExit中调用,否则程序会crash,我们的变通方法是CLaunchCamera的外部调用启动一下timer,在timer中轮询调用EnableCloseCamera来判断当前的摄像头是否可以关闭。

 

附录一:CLaunchCamera的类定义:

 

#include  < e32std.h >
#include 
< apparc.h >   // for MApaEmbeddedDocObserver
#include  < eikproc.h >   // for CEikProcess
//

enum  Camera_File_Type
{
        CFT_NoFind 
= 0x0,
        CFT_Image 
= 0x1 ,
        CFT_Video 
= 0x2 ,
}
;

typedef Camera_File_Type   enCameraFileType ;

class  MCameraEvenCallBack
{
public:
    
virtual void Camera_HandleFile(enCameraFileType enFileType , const TDesC & aFilePath) = 0 ;
        
virtual void Camera_UpdateData(TBool bUpdate = TRUE ) = 0;
}
;

//

class  CApaDocument ;
class  CEikonEnv ;

class  CLaunchCamera  :  public  MApaEmbeddedDocObserver
{
public:
        CLaunchCamera();
        
virtual ~CLaunchCamera();

    
static CLaunchCamera * NewL(MCameraEvenCallBack * pEvenCallBack,CEikonEnv * pEikonEnv );
    
static CLaunchCamera * NewLC(MCameraEvenCallBack * pEvenCallBack,CEikonEnv * pEikonEnv);
        TBool OpenCamera() ;

        
//注意些接口不能在MCameraEvenCallBack的回调中调用,否则设备会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类实现

#include <eikenv.h> //for CEikProcess

#include <eikproc.h> //for CEikProcess

#include <PathInfo.h> //for PathInfo

#include <apgcli.h>  //for RApaLsSession

#include <apacln.h>  // for TApaDocCleanupItem

 

#include "LaunchCamera.h"

 

CLaunchCamera* CLaunchCamera::NewL(MCameraEvenCallBack * pEvenCallBack,CEikonEnv * pEikonEnv )

{

        CLaunchCamera* self = NewLC(pEvenCallBack ,pEikonEnv);

        CleanupStack::Pop(self);

        return self;

}

 

CLaunchCamera* CLaunchCamera::NewLC(MCameraEvenCallBack * pEvenCallBack,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 ;

}

 

CLaunchCamera::CLaunchCamera()

{

        m_pAppdoc = NULL ;       

}

 

CLaunchCamera::~CLaunchCamera()

{

        //CloseCamera() ;

        m_pEikonEnv = NULL ;

        m_pCallBack = NULL ;

}

 

 

// Function name        : CLaunchCamera::OpenCamera

// Description            : Open camera and review

// Return type                : TURE if successful, otherwise FALSE

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);

        ASSERT( m_pAppdoc != NULL ) ;

       

        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 ;

}

 

void CLaunchCamera::CloseCamera()

{

        if( m_pProcess )

        {

                m_pProcess->DestroyDocument(m_pAppdoc) ;

                m_pProcess = NULL ;

                m_pAppdoc = NULL ;

        }

 

        m_bCloseCamera = TRUE ;

}

 

TBool CLaunchCamera::FindCamera(TApaAppInfo & appInfo)

{

        RApaLsSession apaTmpLs;

 

         User::LeaveIfError(apaTmpLs.Connect());

         CleanupClosePushL(apaTmpLs);

 

        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(); // apaTmpLs

 

        return bFindCamera ;

}

 

// Function name        : CLaunchCamera::NotifyExit

// Description            : when selected "select", frame will call this function

// Return type                : void

// Argument         : TExitMode aMode

void CLaunchCamera::NotifyExit(TExitMode aMode)

{

        if( aMode == EKeepChanges )

        {

                //不能在这里调,否则设备为crash

                //m_pProcess->DestroyDocument(m_pAppdoc) ;

                FindNewFile() ;

        }

    else

    {

                //m_pProcess->DestroyDocument(m_pAppdoc) ;

                if( m_pCallBack )

                        m_pCallBack->Camera_HandleFile(CFT_NoFind, _L("FileNotSelect"));

    }

 

        m_bCloseCamera = TRUE ;

}

 

TBool CLaunchCamera::EnableCloseCamera()

{

        return m_bCloseCamera ;

}

 

// 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) ;

                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 )

        {

                //ASSERT(FALSE) ;

                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 ;

}

  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值