Archiv für Development

XDA comet: UMTS/GPRS Bandwechsel / Anwendungsentwicklung Fortschritt

Letzte Woche ist mir an meinem XDA comet aufgefallen, dass er sich relativ häufig abgeschaltet hatte, sprich, dass ein Druck auf den Power-Knopf das Gerät mit der Meldung „Device booting…“ gestartet hatte. Zuvor hatte ich bemerkt, dass beim Gespräch ein „Knacken“ in der Leitung war. Ein kurzer Blick nach dem Gespräch auf das Display zeigte wenig UMTS Empfang, danach vollen GPRS Empfang. Dieser Wechsel erfolgte innerhalb dieser Funkzelle häufiger. Ich persönlich vermute hier, dass weniger die Hardware denn mehr die Software (sprich Windows Mobile 6) unter ungünstigen Umständen Probleme mit diesem Szenario hat. Das trübt aber den bisher durchweg positiven Eindruck von meinem Gerät keineswegs 🙂

Ansonsten bin ich derzeit in meinem „normalen“ Job gefangen, d.h. wir liefern Ende der Woche ein Hauptrelease aus und entsprechend viel Stress und Termindruck wabert durch die Luft. Daher bin ich in der letzten Zeit nur schleppend mit der Anwendungsentwicklung mit dem Compact Framework für Windows Mobile weitergekommen. Jetzt steht aber ab nächster Woche erst einmal Urlaub an und dann sehen wir weiter 😉

Compact Framework Design Time Attribute

Wenn man unter dem .Net Framework entwickelt, kann man Properties in visuellen Klassen (UserControls, Forms, Controls, …) mit Attributen versehen, so dass diese gewisse Eigenschaften haben. Zum Beispiel ist es so möglich ein Property „AlternateText“ in ein eigenes Control einzufügen. Dieses Property ist im Designer auch sichtbar, nachdem man es auf die gerade zu designende Oberfläche per Drag & Drop gezogen hat. Standardmäßig taucht dieses Property in der Kategorie „Misc“ auf. Man kann nun beeinflussen, dass das Property im Properties-Browser im Designer nicht sichtbar ist ([Browsable(false)]), man kann einen Default-Wert festlegen ([DefaulValue(„Not set“)]) oder auch eine eigene Kategorie definieren ([Category(„Advins – Control Visual Properties“)]).

Leider hat man genau diese Annehmlichkeiten nicht im Compact Framework zur Verfügung. Man kann sich aber behelfen, indem man eine XMTA Datei dem Projekt hinzufügt und darin diese Eigenschaften in XML-Form festlegt. Eine solche XML-Datei (DesignTimeAttributes.xmta) kann wie folgt aussehen:

<?xml version="1.0" encoding="utf-16"?>
<Classes xmlns="http://schemas.microsoft.com/VisualStudio/2004/03/SmartDevices/XMTA.xsd">
 <Class Name="AdvControls.ImageButton">
  <Property Name="ButtonText">
   <Browsable>true</Browsable>
   <Category>AdvControls - Properties</Category>
   <Description>Set the text to be displayed in the button here.</Description>
  </Property>
  <Property Name="Image">
   <Browsable>true</Browsable>
   <Category>AdvControls - Properties</Category>
   <Description>Set the image to be displayed in the button here.</Description>
  </Property>
 </Class>
</Classes>

Der Compiler erkennt die Datei und erzeugt daraus eine AdvControls.WindowsCE.asmmeta.dll. So kann man seine Control-Properties doch wie gewohnt (leider nur etwas umständlicher) mit Attributen versehen.

Entwickelt man Code sowohl für den Desktop als auch ein Mobile Device kann man seine Attribute mittels

#if Desktop

#endif

über das Property schreiben ohne Compile-Fehler zu bekommen.

Wiedergabe von Sounds mit dem Compact Framework

Vor einiger Zeit schon stieß ich auf das Problem unter Windows Mobile Sounds wiedergeben zu wollen. Nahezu ohne Weiteres unterstützt wird das Abspielen von WAV-Sounds, aber wie sieht es mit MP3 und/oder WMA aus ? Nun dazu später mehr, hier erst einmal die Lösung von Microsoft, wie man WAV-Sounds unter Windows Mobile abspielen kann:

public class Sound {
private byte[] m_soundBytes;
private string m_fileName;
private enum Flags
{
SND_SYNC = 0x0000, /* play synchronously (default) */
SND_ASYNC = 0x0001, /* play asynchronously */
SND_NODEFAULT = 0x0002, /* silence (!default) if sound not found */
SND_MEMORY = 0x0004, /* pszSound points to a memory file */
SND_LOOP = 0x0008, /* loop the sound until next sndPlaySound */
SND_NOSTOP = 0x0010, /* don’t stop any currently playing sound */
SND_NOWAIT = 0x00002000, /* don’t wait if the driver is busy */SND_ALIAS = 0x00010000, /* name is a registry alias */
SND_ALIAS_ID = 0x00110000, /* alias is a predefined ID */
SND_FILENAME = 0x00020000, /* name is file name */
SND_RESOURCE = 0x00040004 /* name is resource name or atom */
}

[DllImport(„CoreDll.DLL“, EntryPoint=“PlaySound“, SetLastError=true)]
private extern static int WCE_PlaySound(string szSound, IntPtr hMod, int flags);
[DllImport(„CoreDll.DLL“, EntryPoint=“PlaySound“, SetLastError=true)]
private extern static int WCE_PlaySoundBytes (byte[] szSound, IntPtr hMod, int flags);

/// <summary>
/// Construct the Sound object to play sound data from the specified file.
/// </summary>
public Sound (string fileName)
{
m_fileName = fileName;
}

/// <summary>
/// Construct the Sound object to play sound data from the specified stream.
/// </summary>
public Sound(Stream stream)
{
// read the data from the stream
m_soundBytes = new byte [stream.Length];
stream.Read(m_soundBytes, 0,(int)stream.Length);
}

/// <summary>
/// Play the sound
/// </summary>
public void Play ()
{
// if a file name has been registered, call WCE_PlaySound,
// otherwise call WCE_PlaySoundBytes
if (m_fileName != null)
WCE_PlaySound(m_fileName, IntPtr.Zero, (int) (Flags.SND_ASYNC | Flags.SND_FILENAME));
else
WCE_PlaySoundBytes (m_soundBytes, IntPtr.Zero, (int) (Flags.SND_ASYNC | Flags.SND_MEMORY));
}
}

Wie bewerkstelligt man es aber nun, MP3 und WMA-Sounds abzuspielen ? Hierzu fand ich folgende Lösung im Netz:

  • Hinzufügen einer Referenz auf C:\Windows\System32\wmp.dll (man benutzt also den Windows Media Player)
  • Folgenden Code zum Abspielen verwenden:

    WMPLib.WindowsMediaPlayer player = new WMPLib.WindowsMediaPlayer();
    player.URL = „\\Amazing.mp3“;
    player.settings.volume = 100;
    player.controls.next();
    player.controls.play();

Ich greife dieses Thema hier auf, weil mich jüngst Martin per Mail nach einer Lösung fragte und dies vielleicht auch noch für andere interessant sein könnte.

.Net Compact Framework: ImageButton ??

Nach langer Funkstille zum Thema Anwendungsentwicklung für Windows Mobile mit dem .Net Compact Framework (CF), möchte ich heute nochmals einen Zwischenbericht abgeben.

Mein Fazit bisher: das CF ist wirklich auf das Nötigste reduziert, fast schon um zu viele Dinge reduziert, wenn man von dem vollen Umfang des normalen Frameworks verwöhnt ist. Weniger Umfang hat wohl nur noch das .Net Micro Framework… Erste Erfahrungen durfte ich ja bereits mit dem OpenFileDialog sammeln, nun habe ich weitere Lücken gefunden, die ich gerade am Schließen bin. So ist es bspw. bei einem Button im CF nicht möglich ein Bild neben einem Label zu platzieren; das normale Framework bietet hier ein Image Property am Button an. Was also tun ? Richtig, neben der Entwicklung der Dialoge zur Erledigung einfachster Ordner- bzw. Dateiauswahloperationen habe ich begonnen eine eigene Controls-Library zu bauen. Diese beinhaltet bisher zwar nur eine Klasse „ImageButton“ (s. Bild), aber das kann ja noch wachsen.

ImageButton

ImageButton

Bzgl. der SimpleFileRequesterDialogs ist der Stand der, dass der Ordnerauswahldialog (DirectoryChooserDialog) funktioniert (s. Bild) und ich nun an dem OpenFileDialog arbeite. Aus dieser Arbeit heraus entstand auch die Notwendigkeit die eigene Controls-Library zu schreiben.

Verzeichnisauswahldialog

Verzeichnisauswahldialog

Alles in allem komme ich aus Zeitgründen nur langsam voran, aber es geht stetig weiter 😉

OpenFileDialog im .Net Compact Framework

Am Wochenende bin ich über eine Sache gestolpert, wo ich nicht so recht glauben wollte, dass das wahr sein könnte. Ich habe ja mehrfach berichtet, dass ich mich derzeit daran versuche eine Windows Mobile Applikation zu entwerfen. Mit genau diesem Thema habe ich mich auch am Wochenende befasst, als ich aber an die Stelle kam, an der es darum ging Sounds abzuspielen, bin ich über eine – meines Erachtens nach – Basisfunktionalität gestolpert: System.Windows.Forms.OpenFileDialog.

Angefangen hat die Geschichte mit der Implementierung der Sound-Funktionalität, wobei ich mich hierbei des Windows Media Players (wmp.dll) bediente und diese in den Code einband. Die Klasse für den Sound war an sich schnell umgesetzt – nur wie testen ? Also habe ich auf dem Einstellungen-Tabreiter einen „Sound auswählen“ Button hinzugefügt und wollte dann einen einfachen Dateiauswahl-Dialog öffnen. .Net bietet wie gesagt hier die Klasse OpenFileDialog an. Diese habe ich dann auch genutzt und die Anwendung im Debug gestartet. Im Emulator kam dann die Anwendung nach vorne und ich drückte auf den Button und was erschien ? Dieses „Ding“:

.Net CompactFramework OpenFileDialog

In der Combobox „Folder“ tauchen bspw. völlig unnütze Einträge auf, kurz gesagt ich war nicht in der Lage intuitiv und wie gewohnt durch die Ordnerstruktur zu navigieren und eine einfache Datei auszuwählen. Zuerst dachte ich, ich würde etwas falsch machen und habe mich dann im Internet auf die Suche nach einer Lösung begeben. Das erste worauf ich stieß waren Drittanbieter-Komponenten, die sie sich äußerst fürstlich entlohnen ließen. Langsam stieg in mir ein leiser Verdacht auf: sollte ich hier etwa auf die erste der von einem Kollegen viel beschworenen Lücken im Compact Framework gestoßen sein ??? In der Tat sah es nach einer weiteren viertel Stunde Suche äußerst düster aus. Entweder fand ich nur besagte Dritthersteller-Controls oder Dialoge mit Quelltext, die aber nicht sonderlich ansprechend oder funktional waren. Jeder kocht hier sein eigenes Süppchen und programmiert diese Funktionalität selbst aus. Das ist das Fazit meiner Recherche 🙁

Daher muss ich nun meinem Projekt „PhoneEventNotifier“ noch eine anderes Projekt vorschalten: „SimpleFileRequesterDialogs“, d.h. ich werde mich nun zuerst hinsetzen und folgende Dinge nachbauen:

  • Verzeichnisauswahldialog
  • Dateiauswahldialog (Öffnen, Speichern, Mehrfach-Selektion, …)

Dies werde ich als DLL erstellen und separat bereitstellen. Im Prinzip sind alle Funktionalitäten im Compact Framework vorhanden, es fehlt nur die Vereinigung dieser in Form eines Dialogs, der sich „wie gewohnt“ bedienen lässt. Danach geht dann die Arbeit am „PhoneEventNotifier“ weiter.

Sachdienliche Hinweise können in Form von Kommentaren hinterlassen werden 😉

Windows Mobile – PhoneEventNotifier Status

Die Entwicklung des PhoneEventNotifier schreitet voran 🙂 Folgende Fähigkeiten hat das Programm bis dato:

  • Registrierung am System Event PhoneMissedCall (und somit automatischer Start der Anwendung bei Auftreten des Events)
  • Anzeige der Rufnummer des zuletzt verpassten Anrufs

Als nächstes ist geplant:

  • dem Einstellungs-Tab Leben einzuhauchen
  • Auswahl und Abspielen von Sounds

Es wird also so langsam und es macht wirklich Spaß 😉

Hier noch die vorangegangen Artikel zu diesem Thema:

Entwickeln für Windows Mobile – Fortschrittsbericht

Nach einer kleineren Pause möchte ich heute kurz ein Update zum Stand der Entwicklung einer Windows Mobile Applikation geben. Nach längerem Zaudern habe ich mich dazu entschlossen die Applikation für Windows Mobile 5 und höher auszulegen, da dass Windows Mobile 5 SDk bereits anständige Benachrichtigungs-Mechanismen mitbringt. Diese lassen sich ganz einfach mittels der im WM 5 SDK enthaltenen Managed DLLs einbinden. Benötigt werden die Namespaces Microsoft.WindowsMobile sowie Microsoft.WindowsMobile.Status. Damit kann man dann schon eine ganze Menge machen, u.a. kann man sich so auf einen verpassten Anruf-Event registrieren (PhoneMissedCall).

Die Oberfläche ist soweit entworfen, die Registrierung der Events ist auch funktionsfähig. Erste Tests sind auch bereits erfolgreich verlaufen, so zeigte das Programm in seiner Logausgabe an: „verpasster Anruf: +49xxxxxxxxxxx“ (die Zahlen wurden bewusst durch x ersetzt). Hier noch zwei Screenshots der Anwendung im Emulator:

Ansonsten gab es doch einige Anlaufschwierigkeiten, so muss man leider sagen, dass man ab einem gewissen Grad nicht um Microsofts Visual Studio herumkommt, da hier die Integration von Deployment und Device Emulator einfach runder wirkt als mit SharpDevelop o.ä. Oder etwas anders formuliert: Microsoft hat seine SDK Installer Files derart mit Voraussetzungen gepflastert (Visual Studio, ActiveSync, …), dass man wohl erst die Chance hat die Installation durchzuführen, wenn man den Orca MSI Editor von Microsoft zum patchen dieser Installer Dateien nutzt. So wollte ich zum Beispiel auf meiner virtuellen Maschine nicht unbedingt ActiveSync installieren (man müllt ja nicht sein Produktiv-System zu 😉 ), also wurde ein Patch der „Windows Mobile 5.0 Pocket PC SDK.msi“ Installer Datei fällig, dass es ActiveSync nicht zwingend erfordert etc. Irgendwann hatte ich dann aber keine Lust mehr die Steine aus dem Weg zu räumen, die Microsoft bereit legt…

Dies nun nur als kleiner Appetit-Anreger und als Zeichen dafür, dass es voran geht. Sobald die erste lauffähige Version fertig wird, werde ich diese hier veröffentlichen.

Idee zur Windows Mobile Applikation

Es gibt Neuigkeiten an der Entwicklungsfront mit dem Compact Framework 2.0 SP 1 und SharpDevelop. Anfangs sträubte sich SharpDevelop noch etwas das Compact Framework zu erkennen, aus irgendeinem Grund hat es sich dann aber nach diversen Versuchen und Forenbesuchen anders entschieden. Genau sagen, woran es lag, kann ich nicht. Ich denke, dass es an der Installationsreihenfolge liegt.

Man sollte zuerst die CompactFramework Runtimes installieren, danach das Windows Mobile 6 SDK und im Anschluß die gewünschten SDKs für das jeweilige Framework.

Achtung: Wenn man sich auf die Suche nach dem CompactFramework SDK begibt, wird man viele Treffer finden. Es sei hier aber gesagt, dass man das CompactFramework SDK mit den „normalen“ SDKs bekommt. So wird bei der Installation des .Net 2.0 SDK auch das zugehörige CompactFramework SDK auf die Platte kopiert.

Die erste kleine Demo-Applikation (klassisch >Hello World< im Fenster) war in 2 Minuten mit .Net 2.0 geschrieben. Ältere Versionen von Windows Mobile müssen zuerst mit dem .Net Framework in der richtigen Version versorgt werden (Deployment über ActiveSync), Windows Mobile 6 bringt aber bereits alles mit.

Was ist nun die Idee für meine erste Anwendung unter Windows Mobile ? Sie nennt sich „PhoneEventNotifier“ und soll die akustische Signalisierung eines verpassten Ereignisses übernehmen. Der XDA comet signalisiert ein solches Ereignis über eine Status-LED oben am Gerät, diese blinkt dann rot. Dies soll nun noch durch eine Software unterstützt werden, die einen einstellbaren Ton in einem einstellbaren Intervall wiedergibt. So machte das nämlich mein Motorola V3i (habe ich übrigens verkauft mittlerweile) – auch wenn ansonsten recht wenig innovativ war – meiner Meinung nach. An diese Art der Benachrichtigung hatte ich mich im Laufe der zwei Jahre, in denen ich das V3i hatte, gewöhnt und vermisse diese Funktionalität nun etwas bei meinem comet.

Wie soll die Software nun aussehen ? Nun, sie soll im natürlich Hintergrund laufen und mittels eines Timers gesteuert werden. Es soll natürlich immer nur auf ein einziges verpasstes Ereignis reagiert werden, nicht dass sich verpasste Ereignisse kumulieren und das Gerät zig-Mal in verschiedenen Intervallen akustische Signale ausgibt. Ebenso soll eine Zeitspanne einstellbar sein, in der das Gerät keine Signale ausgeben soll (quiet period), bspw. nachts. Die Einstellungen sollen ganz unspektakulär in einem kleinen Fenster (Tab) im Programm vorgenommen werden können.

Ansonsten reift die Idee und ich hoffe, dass ich bald erste Ergebnisse respektive Screenshots liefern kann (Hauptproblem ist wie immer die Zeit für so etwas zu erübrigen 🙁 ). Ich halte die geneigten Leser natürlich auf dem Laufenden 😉

Akkulaufzeit XDA comet / Anwendungsentwicklung [Update]

Generell möchte ich noch sagen, dass es natürlich stark von der Dauer eines Telefonats, von WLAN oder anderen Schnittstellen abhängt, wie lange das XDA comet durchhalten kann. Ich persönlich bin nicht der Dauertelefonierer, wobei ein Gespräch durchaus einmal 30-45 Minuten dauern kann. Das ist aber eher die Ausnahme. Zusätzlich schalte ich immer alle Schnittstellen ab, die ich nicht brauche (etwa WLAN und Bluetooth).

Wer das natürlich nicht macht bzw. längere Telefonate führt, wird meinen bisherigen Rekord von 6 Tagen nicht erreichen. Also betrachtet meine Aussagen bitte realistisch und mit Augenmaß. Es ist lediglich ein Wert, was machbar ist, wenn man gewisse Dinge berücksichtigt 😉

Gestern habe ich übrigens mein erstes Programm auf dem comet zum Laufen gebracht 😀 Es ist zwar nur ein einfaches „Hello World“, aber für 2 Minuten Arbeit ist es ausreichend 😉 Details folgen noch…

Akkulaufzeit XDA comet / Anwendungsentwicklung

Anfangs war ich ja etwas von der Akkulaufzeit meines XDA comet enttäuscht, aber dann erinnerte ich mich an die „Konditionierung“ von Akkumulatoren. Es steht natürlich auch so im Handbuch drin, aber wer liest das denn schon genau durch ? Learning-by-doing oder „rumspielen“ lautet die Devise 😉

Nun nach ca. 2 Wochen mit meinem comet und mehreren Ladezyklen muss ich sagen, dass sich die Laufzeit bei normalem Gebrauch deutlich verbessert hat. Am Anfang hatte ich es nämlich geschafft durch häufiges Spielen mit dem Gerät und seinen Möglichkeiten den Akku innerhalb eines Tages zu leeren. Ok, ich muss dazu sagen, dass ich bei der ersten Warnung etwas die Nerven verloren hatte und den comet gleich an die Stromversorgung angestöpselt habe. Man muss sich aber keinerlei Gedanken machen vor Datenverlust o.ä., da die Daten erhalten bleiben. Daher habe ich das Gerät auch schon zweimal komplett entladen und neu aufgeladen. Mittlerweile hält der comet so um die 6 Tage durch – bei normalem Gebrauch wie gesagt.

Normaler Gebrauch heißt:

  • Telefonieren
  • SMS
  • MMS
  • WLAN/Surfen
  • GPRS für die Synchronisation mit dem o2 Server
  • Kalender
  • Radio
  • Spielen

Der Schwerpunkt der Nutzung liegt natürlich auf Telefonieren, SMS und Kalender 🙂

Zum Thema Anwendungsentwicklung muss ich leider sagen, dass ich noch nicht weiter gekommen bin, da gestern die Download-Server bei Microsoft wohl gesponnen haben 🙁 So war es mir nicht möglich das .Net 2.0 SDK geschweige denn das Windows SDK (für .Net 3.5) herunter zu laden. Ich werde es aber erneut versuchen, wenn ich die Zeit dazu finde…