Posts tagged: autostart

Symbian – Autostart di un applicazione su serie 9

symbian_logoTempo fa in questo post ho scritto come realizzare un programma starter per Symbian serie 8, cioè un launcher di un’applicazione al boot del cellulare. Oggi invece volevo farvi vedere l’analogo su serie 9, la nuova serie di Symbian installata su molti dei cellulari Nokia attualmente in commercio. Premesso che al momento del post precedente la documentazione sull’argomento non era molta, oggi invece esistono molti siti dove è possibile trovare informazioni sull’argomenti, a partire dallo wiki della nokia dove c’è praticamente tutto, per finire sulla pagine di google ;) .
Ma siccome le risorse in italiano non sono mai abbastanza allora volevo illustrare comunque la soluzione

A differenza della precedente versione con Symbian 9 è possibile realizzare l’autostart di un’applicazione usando il meccanismo dello "Startup Management List API" consultabile qui. L’idea di base di questa gestione consiste nel definire un file di risorse attribuendogli come nome l’UID del package che contiene l’applicazione. Tale file conterrà al suo interno alcuni dati di configurazione al fine di poter eseguire l’applicazione indicata all’avvio del programma. Vediamo in cosa consistono questi dati di configurazione:
 

1
2
3
4
5
6
#include <startupitem.rh> 
RESOURCE STARTUP_ITEM_INFO devme 
{ 
    executable_name = "!:\\sys\\bin\\devme.exe"; 
    recovery = EStartupItemExPolicyNone; 
}

Bene. Subito una piccola precisazione. Come vedete il valore di executable_name coincide con un path, quello di installazione dell’applicazione. Ha all’inizio un punto esclamativo che sta ad indicare la destinazione intesa come unità di installazione. Chi ha installato un’applicazione per symbian sa che ad un certo punto viene chiesto di indicare la destinazione su cui installare il programma, se la memoria del telefono o eventuali memorie esterne. Ecco il ! riferisce quella destinazione. Se si vuole, ad esempio, imporre l’installazione sulla memoria del telefono il ! verrà sostituito con C. 
Come vedete i dati di configurazione sono pochi e il commento viene da se.

Prossimo step consiste nell’aggiungere il riferimento del file appena creato all’interno del file di configurazione .mmp.

1
2
START RESOURCE ..\DATA\APP_UID.rss
END

Ed infine aggiungere le informazioni di configurazione nel file .pkg.

1
"$(EPOCROOT)Epoc32\data\z\private\101f875a\import\apps\APP_UID.rsc" -"c:\private\101f875a\import\[APP_UID].rsc"

Dove la prima parte della riga di configurazione indica il percorso delle SDK che si stanno utilizzando per la build corrente. Nel mio caso siccome sto usando Carbide come IDE posso utilizzare le variabili d’ambiente che mette a disposizione. Da notare che, mentre per un qualunque altro programma posso usare il ! per indicare la destinazione, per quanto riguarda l’autostart su serie 9 devo indicare C come destinazione…non solo, in aggiunta l’intero percorso dove vengono memorizzati questi tipi di file "C:\private\101f875a\import\".
Stay tuned, a presto.

Symbian – Auto start di un applicazione

phoneSalve a tutti quei pochi, spero ancora per poco, che leggono il blog…ogni tanto un commentino potreste anche lasciarlo, siamo qui per quello :P !!! Volevo cominciare una, spero lunga serie di post su symbian, il famoso sistema operativo che gira su molti dei cellulati di ultima generazione (nokia, samsung, etc). Per il momento tralasciamo tutto quello che concerne il preliminare di symbian, e vediamo subito, senza perdere tempo, un programmino, o meglio uno scorcio di codice che permette di lanciare un applicazione al boot, ovvero quando si va ad accendere il cellulare.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <apmrec.h>
#include <apmstd.h>
#include "cl_autostart.h" 
const TUid KUidemAclAutostart={0x09A770B5}; CclAutostart::CclAutostart():CApaDataRecognizerType(KUidemAclAutostart, CApaDataRecognizerType::ENormal) {
    iCountDataTypes = 1; 
} 
TUint CclAutostart::PreferredBufSize() { 
    // no buffer recognition yet 
    return 0; 
} 
TDataType CclAutostart::SupportedDataTypeL(TInt /*aIndex*/) const { return TDataType(); } 
void CclAutostart::DoRecognizeL(const TDesC& /*aName*/, const TDesC8& /*aBuffer*/) {} 
void CclAutostart::StartThread() { 
    TInt res = KErrNone; 
    //create a new thread for starting our application 
    RThread * startAppThread; 
    startAppThread = new RThread(); 
    User::LeaveIfError( res = startAppThread->Create(
        _L("Autostart starter"), CclAutostart::StartAppThreadFunction, KDefaultStackSize,
        KMinHeapSize, KMinHeapSize, NULL, EOwnerThread) );
    startAppThread->SetPriority(EPriorityNormal/*EPriorityLess*/); 
    startAppThread->Resume(); 
    startAppThread->Close(); 
} 
TInt CclAutostart::StartAppThreadFunction(TAny* /*aParam*/) { 
    //wait 5 seconds... 
    RTimer timer; 
    // The asynchronous timer and ... 
    // ... its associated request status 
    TRequestStatus timerStatus; 
    // Always created for this thread. 
    timer.CreateLocal(); 
    // get current time 
    TTime time; 
    time.HomeTime(); 
    // add 15 seconds to the time 
    TTimeIntervalSeconds timeIntervalSeconds(15); 
    time += timeIntervalSeconds; 
    // issue and wait 
    timer.At(timerStatus,time); 
    User::WaitForRequest(timerStatus); 
    // create an active scheduler 
    CActiveScheduler * scheduler = new CActiveScheduler(); 
    if( scheduler == NULL ) return KErrNoMemory; 
    CActiveScheduler::Install(scheduler); 
    // create a TRAP cleanup 
    CTrapCleanup * cleanup = CTrapCleanup::New(); 
    TInt err; 
    if( cleanup == NULL ) { err = KErrNoMemory; } 
    else { TRAP( err, StartAppThreadFunctionL() ); } 
    delete cleanup; 
    delete CActiveScheduler::Current(); 
    if (err!=KErrNone) User::Panic(_L("autostart"), err); return err; 
} 
 
void CclAutostart::StartAppThreadFunctionL() { 
    #ifdef __WINS__ 
    // This is the uid of the starter application, 
    // which you want to autostart. 
    const TUid starter_uid= { 0x05CCC0B0 }; 
    RApaLsSession ls; 
    User::LeaveIfError(ls.Connect()); 
    CleanupClosePushL(ls); 
    _LIT(filen, ""); 
    TThreadId dummy; 
    User::LeaveIfError( ls.StartDocument(filen, starter_uid, dummy) ); 
    CleanupStack::PopAndDestroy(); 
    #else 
    // Replace this starter.app with the app which 
    // you want to autostart. 
    TFileName fnAppPath = _L("\\system\\apps\\myapp\\myapp.app"); 
    RFs fsSession; 
    //file server session 
    User::LeaveIfError(fsSession.Connect()); 
    CleanupClosePushL(fsSession); 
    TFindFile findFile( fsSession ); 
    User::LeaveIfError( findFile.FindByDir(fnAppPath, KNullDesC) ); 
    CApaCommandLine* cmdLine = CApaCommandLine::NewLC(); 
    cmdLine->SetLibraryNameL( findFile.File() ); 
    cmdLine->SetCommandL( EApaCommandOpen ); 
    RApaLsSession ls; 
    User::LeaveIfError(ls.Connect()); CleanupClosePushL(ls); 
    User::LeaveIfError( ls.StartApp(*cmdLine) ); 
    // Destroy fsSession, ls and cmdLine 
    CleanupStack::PopAndDestroy(3); #endif 
} 
EXPORT_C CApaDataRecognizerType* CreateRecognizer()  { 
    CApaDataRecognizerType* thing = new CclAutostart(); 
    //start thread for our application 
    CclAutostart::StartThread(); return thing; 
} 
// DLL entry point 
GLDEF_C TInt E32Dll(TDllReason /*aReason*/) { 
	return KErrNone; 
}

Lo scorcio di codice di sopra, descrive una classe scritta in C++ per symbian, e realizza quello che tecnicamente si chiama un MDL, ovvero un particolare tipo di programma che viene riconosciuto da symbian e lanciato subito dopo la fase di boot con un ritardo che viene impostato da codice. Nel nostro esempio il ritardo è di 15 secondi. Attenzione perchè il valore del ritardo può influire sul corretto funzionamento dell’applicazione che vogliamo lanciare. Ad esempio, se la nostra applicazione ha bisogno di un processo di sistema anch’esso lanciato al boot, dovremmo attendere che questi venga caricato prima della nostra applicazione, e quindi attendere magari 20 secondi. Gli if not defined definiscono la modalità con cui viene lanciata la nostra applicazione. #ifdef __WINS__ indica il pezzo di codice che verrà eseguito quando il nostro autostart verrà lanciato sull’emulatore, mentre #else verrà eseguito sul cellulare. Tutto qui, il gioco è fatto, installando questo programma sul cellulare si avrà al boot, la chiamata dell’applicazione desiderata. Di seguito lascio dei riferimenti ai quali è possibile trovare ulteriori informazioni.

WordPress Themes