在论坛上看到这方面的几个帖子,想到已有好几天没写博了,最近在折腾MTK的东西,累啊。今天就抽空研究一下如何在S60第三版中做一个自启动应用吧。
参考这篇文章:How to autostart an application on boot up in 3rd- Startup List Management APIhttp://wiki.forum.nokia.com/index.php/How_to_autostart_an_application_on_boot_up_in_3rd-_Startup_List_Management_API
第一步:写一个RSS文件,就用自己的那个UID作为文件名即可,例如我的UniNews_0xE94DA878.exe,它的UID就是0xE94DA878,所以我作一个E94DA878.rss文件放在data目录下面,内容如下:
#include <startupitem.rh>
RESOURCE STARTUP_ITEM_INFO startexe
{
executable_name = "!:\sys\bin\UniNews_0xE94DA878.exe";
recovery = EStartupItemExPolicyNone;
}
第二步:修改MMP,加一个资源如下:
START RESOURCE E94DA878.rss
TARGET E94DA878.rsc
TARGETPATH resource\apps
END //RESOURCE
意思就是说将上面那个rss编译成同名的rsc放在目录resource\apps下面。
第三步:上面弄完了基本就可以了但是我在模拟器上没有跑起来,所以还是得放到真机上尝试,因此再改一下那个PKG文件吧,如下:
"$(EPOCROOT)Epoc32\data\z\resource\apps\E94DA878.rsc" -"!:private\101f875a\import\[E94DA878].rsc"
就是将生成的rsc拷入手机的相应目录下即可。
就这么要改动的地方,相当简单吧。随便拿个程序按上述方法改一下就可以了。
不过,最关键的一点是,自签名的SISX是不支持的!!!切记!!
原因是: Startup List Management API does not work with Self-Signed application。
所以,我们还需要去 https://www.symbiansigned.com/app/page 申请一个 Open Signed ,按界面上操作即可,选中所有能力,一会它会发一个邮件到你的邮箱中,确认一下,它再将生成的sisx文件下载地址发给你,就可以点击下载了,将这个sisx安装到手机里,重启手机,不错,我们的应用真得自己跑起来了。
再把这个Browser Control API也总结一下吧,只是做个引导,其实要掌握它的用法最好的方法是打开 9.1\S60_3rd\S60Ex\BrCtlSampleApp 这个例子来阅读,它几乎涵盖了这个API的所有使用方法。
而我在UniNews中只使用了它最基本的用法,下面给出代码:
首先,在H文件中声明一个控件成员:
#include <coecntrl.h>
#include <brctlinterface.h>
#include <brctldefs.h>
#include <brctllayoutobserver.h>
#include <brctllinkresolver.h>
class CUniNewsWebContainer : public CCoeControl, MCoeControlObserver,MBrCtlLoadEventObserver ...{
public:
// Constructors and destructor
~CUniNewsWebContainer();
static CUniNewsWebContainer* NewL(const TRect& aRect);
static CUniNewsWebContainer* NewLC(const TRect& aRect);
private:
// New functions
void ConstructL(const TRect& aRect);
CUniNewsWebContainer();
public:
// Functions from base classes
TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType);
void HandleBrowserLoadEventL(TBrCtlDefs::TBrCtlLoadEvent aLoadEvent,TUint aSize,TUint16 aTransactionId);
void LoadContentL(TInt id);
private:
// Functions from base classes
void SizeChanged();
TInt CountComponentControls() const;
CCoeControl* ComponentControl(TInt aIndex) const;
void Draw(const TRect& aRect) const;
void HandleControlEventL(CCoeControl* aControl, TCoeEvent aEventType);
HBufC8* ReadFileLC(const TDesC& aFileName);
private:
//data
CBrCtlInterface* iBrowser;
TUint iCapabilities;
TInt iCommandBase;
};
主要声明了三个成员,其中CBrCtlInterface是主要的browser控件,其它两个是构造时的所需要的参数。而这个类派生于接口MBrCtlLoadEventObserver,所以实现它的方法void HandleBrowserLoadEventL(TBrCtlDefs::TBrCtlLoadEvent aLoadEvent,TUint aSize,TUint16 aTransactionId);
在实现文件CPP中,我们需要构造它:
void CUniNewsWebContainer::ConstructL(const TRect& aRect) ...{
// Create a window for this application view
CreateWindowL();
SetRect(aRect);
//add your code here ...
iBrowser=CreateBrowserControlL(this
,aRect
,iCapabilities
,iCommandBase
,NULL //softkey observer
,NULL //link resolver
,NULL //special load observer
,NULL //layout observer
,NULL //dialog provider
);
iBrowser->ActivateL();
if(iBrowser)...{
iBrowser->AddLoadEventObserverL(this);
iBrowser->SetBrowserSettingL(TBrCtlDefs::ESettingsFontSize,TBrCtlDefs::EFontSizeLevelNormal);
}
ActivateL();
}
在构造函数中我们初始化那两个参数:
CUniNewsWebContainer::CUniNewsWebContainer() ...{
// No implementation required
iCapabilities=TBrCtlDefs::ECapabilityDisplayScrollBar|TBrCtlDefs::ECapabilityLoadHttpFw;
iCommandBase=TBrCtlDefs::ECommandIdBase;
iBrowser=NULL;
}
删除的时候记得将它的事件监听器都注销掉:
CUniNewsWebContainer::~CUniNewsWebContainer() ...{
// No implementation required
if(iBrowser)...{
iBrowser->RemoveLoadEventObserver(this);
}
delete iBrowser;
iBrowser=NULL;
}
此外,它跟其它控件一样,在Resize时要处理一下,并且它也需要声明自己是一个组件等等的。
而方法HandleBrowserLoadEventL只需要简单地重绘一下即可。
真正的使用在这儿呢,很简单:
void CUniNewsWebContainer::LoadContentL(TInt id)
.{
if(iBrowser){
TFileName fname;
fname.Format(KContentFile,id);
iBrowser->LoadUrlL(fname);
}
}
就是一句话 LoadUrlL就可以了,这个URL可以是http:// 也可以是 file://,很方便。
不过经常我们是需要将内存里的内容加载显示出来,那就稍稍多做一点工作:
void CUniNewsWebContainer::LoadContentL(TInt id)
{
if(iBrowser)...{
TFileName fname;
fname.Format(KContentFile,id);
HBufC8 * buf=ReadFileLC(fname);
_LIT(KURL,"data:%d");
TBuf<32> url;
url.Format(KURL,id);
_LIT8(KDataType, "text/html");
TDataType dataType(KDataType());
TUid uid;
uid.iUid = KCharacterSetIdentifierUtf8;
iBrowser->LoadDataL(url,*buf,dataType,uid);
CleanupStack::PopAndDestroy();
}
}
这里的URL用data:// 开头主要是用于历史记录作个标签罢了。而内容格式是text/html,不过要换成TDataType类型。而字符集使用UTF8。
我试了一下,觉得加载到内存再显示的效果比直接加载文件要快(主要是指切换页面时)。
另外,这个控件有个BUG,在退出时会有内存泄露,按网上的说法,在构造后激活它即可,但是我试了也没有效果?!