3…2…1…
by Maddin on Mar.01, 2009, under Technik
Hallo zusammen!
Nein, ich habe keineswegs die Absicht den Werbeslogan eines gewissen Online-

Windows Mobile Logo
Auktionshauses zu kopieren. Der Titel hat rein praktische Bedeutung und bezieht sich auf meine neueste Spielerei mit dem Windows Mobile 6 Professional SDK.
Es handelt sich dabei um einen kleinen Timer. Bevor jetzt einige vor Erstaunen gleich vom Bürostuhl fallen, möchte ich doch kurz die Hintergründe erläutern.
Mein HTC Touch Diamond besitzt alle möglichen Spielereien und Tools, die das mobile Leben leichter machen sollen. Jedoch ein simpler Timer, z.B. um mich zu erinnern, wann der Tee fertig gezogen ist oder ein Teig genügend geruht hat, den gibt es nicht. Natürlich brauch man nur die entsprechenden Schlagworte bei Google eintippen und findet entsprechende Timer kostenlos zum Download. Aber zum Einen dachte ich mir: “Hey, so schwer kann das net sein!” und zum Anderen stellte es genau die richtige Schwierigkeitsstufe für einen weiteren Schritt beim Erkunden der Windows Mobile Programmierung dar. Ein dritter Grund ist der, dass der einfache Timer nur die Grundlage für ein recht nützliches Tool sein soll, das schonmal alle wichtigen Schlüsseltechniken besitzt.
So, was hab ich nun getan? Zunächst einmal galt es eine einfache und übersichtliche GUI zu erstellen. Mit Microsoft Visual Studio 2008 war auch gar kein Problem. Die grundlegenden Eventhandlings für die einzelnen Menüpunkte stellte auch keine große Schwierigkeit dar. Der Timer bietet die Möglichkeit eine Zeit einzustellen, auszuwählen, ob man nach deren Ablauf per Vibration oder Klingeln erinnert werden möchte, sowie eine Resetfunktion.
Doch betrachten wir mal die Kernfunktion. Die eingestellte Zeit soll sekundenweise herunterzählen, bis man bei 00:00:00 angelangt ist. Demnach benötigt man ein Ereignis, das im Intervall von einer Sekunde auftritt. Das .NET-Framework bietet dazu die Klasse System.Windows.Forms.Timer, deren Instanzen mit einer Intervalllänge konfiguriert werden können. Sobald eine Timer-Instanz in den Zustand “Enabled” gesetzt wurde, wird immer im konfigurierten Intervall ein entsprechendes Event gefeuert. Den Eventhandler, der dieses Ereignis behandeln soll, kann man bei der Konfiguration angeben.

Zeiteinstellung beim Timer
Damit ist schonmal das erste Grundproblem gelöst, denn nun kann man den eingegebenen Wert in eine Menge von Sekunden umrechnen und diesen im Eventhandler der Timer-Instanz dekrementieren. Wenn er den Wert 0 erreicht, soll dann eine Vibration oder ein Sound ausgelöst werden. Doch da ergibt sich das nächste Problem: Wie?
Das Thema Sound hatte sich relativ schnell erübrigt, da es passende Beispiele im Internet gibt. Ich habe eine separate Sound-Klasse nach diesem Beispiel erstellt. Diese greift direkt über DLL-Import auf die CoreDLL zu. Nach außen (zu meinem SimpleTimer) bietet sie eine einfache Schnittstelle, der man den Dateinamen übergeben kann. Schwieriger war die Handhabung der Vibration. Hierbei kam ich nach einem Studium entsprechender Blogeinträge zu dem Schluss, dass ich mich eines zusätzlichen SDKs bedienen sollte.
Das OpenNETCF SDK bietet für derartige Bedürfnisse eine weitere umfangreiche Klassenbibliothek. Die entsprechende Bibliothek muss in Visual Studio verständlicherweise in die References hinzugefügt werden, damit die entsprechenden dll-Dateien beim Release mit in den Ordner gepackt werden. Allerdings hatte ich nun das Problem, dass ich verschiedene Beispiele fand. Zum Einen benutzte man die Vibrate-Klasse unter OpenNETCF.WindowsMobile. Dies probierte ich auch zunächst aus. Der Erfolg blieb aus. Ein anderes Beispiel nutze eine virtuelle Notification-LED. In Klassen ausgedrückt heißt das: OpenNETCF.WindowsCE.Notification.Led
Mit einer Instanz dieser Klasse konnte ich über vier simple Zeilen meine Vibration auslösen und stoppen.
OpenNETCF.WindowsCE.Notification.Led vibra = new OpenNETCF.WindowsCE.Notification.Led();
vibra.SetLedStatus(1, OpenNETCF.WindowsCE.Notification.Led.LedState.Blink);
System.Threading.Thread.Sleep(1000);
vibra.SetLedStatus(1, OpenNETCF.WindowsCE.Notification.Led.LedState.Off);
Hierbei sei angemerkt, dass die 1 die ID der LED darstellt. Gegebenenfalls muss man etwas probieren, bis man die richtige LED ermittelt hat.

Menüstruktur des Timers
Mit diesem scheinbar fertigen Timer machte ich nun einen Praxistest. Ich habe Nudeln gekocht und die angegebene Kochzeit eingestellt. Als mein Handy noch ca. 5 verbleibende Minuten (von ursprünglich 10) anzeigte, war meine Pasta aber schon Al-Dente. Das machte mich etwas stutzig. Eingehende Tests (natürlich nach dem Essen) brachten die Erkenntnis: sobald sich das Handydisplay ausschaltet, wechselt das Handy in eine Art Ruhezustand, die Berechnung des Timers stoppt.
Am Abend des selben Tages habe ich mich nun eingehend mit den System Power States unter Windows Mobile 6 Professional beschäftigt. Dank der MSDN Library fand ich auch die passenden Informationen. Der Übeltäter nannte sich “Suspended State”. Ein Systemzustand, in dem keine Threads laufen. Dank der übersichtlichen Zustandstabelle fand ich dann auch den Zustand, den ich brauchte: “Unattended State”. Dieser ist für Threads die Berechnungen durchführen, die keine direkte Userinteraktion erfordern. Ähnlich der Sound-Klasse hab ich mir eine PowerManager Klasse geschrieben, die mir die nötige Schnittstelle in die CoreDLL bietet. Dies funktionierte auch ganz gut, wenn nicht dann trotzdem irgendwann das Handy im Suspended State gelandet wäre. Ich schaute nun nochmal in die “State Transition”-Tabelle. Der SystemIdle Timeout war schuld, dass mein Timer dennoch stoppte. Doch eine Zeile darunter war die Lösung auf dem Silbertablett: Mittels SystemIdleTimerReset kann man diesen Timeout verhindern.
Somit habe ich in meinen PowerManager eine weitere Funktion eingefügt, die diesen Reset ausführt. Diese Funktion wird von meinem EventHandler der Timer-Instanz alle 30 Sekunden aufgerufen. Nun läuft der Timer problemlos auf 0 herunter. Das Display schaltet sich dabei aber auch nicht mehr vollständig ab, sondern reduziert nur das Backlight auf ein Minimum.
Nun gibt’s hier im Blog eine Software-Sektion ähnlich dieser einfüge, wo ihr euch dann auch direkt den Timer als Quellcode herunterladen könnt. Oben am rechten Rand findet ihr den Link “Software“.


March 1st, 2009 on 14:05
Da isser also, der Timer. Sieht gut aus und ist sicherlich auch brauchbar… vielleicht liefere ich den Timer dann für eine andere Plattform ;)
Und sogar ein Link auf meine Softwareseite, fein fein fein. :D