code it

Martins Tech Blog

InvalidOperationException in WebBrowserTask.Show

In Windows Phone 7 hat man mit Hilfe der Launcher und Chooser die Möglichkeit, auf im System integrierte Funktionen zuzugreifen - sei es nun die Kamera, der Emailclient oder wie in meinem Fall der Browser. Meine Anwendung hat mehrere Buttons über die zu unterschiedlichen Webseiten weiternavigiert werden kann - hauptsächlich als weiterführende Information im Impressum.

Dafür hab ich abstrakt gesehen folgende zentrale Methode:

public static void OpenInWebBrowser(string url)
{
    var openBrowserTask = new WebBrowserTask { Uri = new Uri(url) };
    openBrowserTask.Show();
}

Diese Methode wird direkt in dem Command aufgerufen, das an dem Button hängt - alles kein Hexenwerk. Was mich nun wunderte: Gelegentlich bekam ich Error-Reports mit diesem Inhalt:

Navigation is not allowed when the task is not in the foreground. Error: -2147220990

Da stellte sich mir folgende Frage: Wie kann jemand den Button klicken, wenn die Anwendung nicht im Vordergrund ist?

Die Lösung ist ganz einfach: Der Benutzer hat kurz nacheinander auf den Button geklickt - sei es nun weil er so aufgeregt war, eine schöne Webseite zu sehen oder weil er gerade unterwegs auf einer holprigen Straße war - die Möglichkeiten sind da ja sehr vielfältig. Das ist möglich, weil der Launcher eine Weile braucht, um den Browser in den Vordergrund zu holen. Der Nutzer kann also dafür sorgen, dass der Click-Event zweimal ausgelöst wird - der zweite Event wird aber erst dann verarbeitet, wenn der erste WebBrowserTask den Browser geöffnet hat und damit die eigentliche Anwendung nicht mehr im Vordergrund ist. Und dann kommt es zu dieser Exception.

Wie geht man nun damit um? Es gibt mehrere Ansätze. Zum einen kann man natürlich mit Try-Catch-Blöcken arbeiten und genau diesen Exception-Typ abfangen. Da diese Exception bei dieser Methode bisher in der MSDN nicht dokumentiert ist, ist es etwas schwierig hier von allein auf die Idee zu kommen, diesen speziellen Typ abzufangen, aber nachher weiß man es immer besser. Zusätzlich könnte man noch den Click-Handler abhängen bzw. den Button oder das Command deaktivieren. 

Ich bin nicht der einzige, dem dieses Problem untergekommen ist - und Niko hat einen sehr ausführlichen Blogpost zum Thema geschrieben, der auch alle hier genannten Lösungsmöglichkeiten aufführt.

Neue Version von "Sag's anders" released

Vor etwa einem Jahr ging meine App Sag's anders im Windows Phone Marketplace live. Die Idee dazu kam mir, als ich zufällig bei der Suche nach einem Synonym über das Projekt OpenThesaurus gestolpert bin.

Was ist OpenThesaurus?

OpenThesaurus ist ein freies deutsches Synonymwörterbuch. Das bedeutet in erster Linie, dass man hier Wörter gleicher oder ähnlicher Bedeutung nachschlagen kann. Aber Nachschlagen ist nicht alles. Ähnlich einem Wiki kann man sich auf der Webseite auch anmelden und selbst Synonyme eintragen.

Was ist Sag's anders?

Sag's anders ist ein Windows Phone 7 Client, der die API von OpenThesaurus anbindet. Damit kann man nun direkt im Phone eine Synonymsuche anstoßen. Leider bietet die API von OpenThesaurus keinen schreibenden Zugriff, so dass man zum Eintragen von Synonymen weiterhin über die Webseite gehen muss.

Seit über einem Jahr nun ist Sag's anders im Windows Phone Marketplace vertreten und war damit eine der ersten Apps. Inzwischen wurde die App über 28.000 mal heruntergeladen. Was als Lernprojekt für eine neue Technologie begann ist damit über die Zeit ein voller Erfolg geworden. Inzwischen ist die Zeit für ein Update gekommen - und was soll ich sagen: Sag's anders Version 1.2 ist jetzt im Marketplace verfügbar.

Und abgesehen vom Upgrade der Frameworkversion von Windows Phone 7 zu Windows Phone 7.1 gibt es auch einige neue Features:

  • Nachschlagen: Wurde eine Synonymsuche durchgeführt, kann das Suchwort in der deutschsprachigen Wikipedia-Seite nachgeschlagen werden.
  • Weitersuchen: Ein gefundenes Synonym kann markiert und durch Aktivieren von Weitersuchen als neues Suchwort übernommen werden.
  • Kopieren: Nicht immer möchte man sich nur in der Anwendung aufhalten, sondern braucht das Wort vielleicht, weil man gerade einen Text schreibt. Das gefundene Synonym kann in die Zwischenablage kopiert und in der Zielanwendung wieder eingefügt werden.

Sag's anders bleibt nach wie vor eine kostenlose App. Sie kann im Marketplace heruntergeladen werden (Deeplink) - befindet sich die Anwendung im Hochformat wird lediglich am unteren Bildschirmrand ein kleines Werbebanner eingeblendet.

Databinding mit der Windows Phone Application Bar

Für Silverlight-Anwendungen hat sich das MVVM-Pattern sehr gut bewährt, bietet es doch einige Vorteile. Und viele Entwickler machen sogar einen Sport daraus, die Trennung zwischen View und ViewModel so konsequent durchzuziehen, dass überhaupt kein Code mehr in der Codebehind-Datei steht, denn Commands im ViewModel sind wesentlich besser testbar als Code in irgendwelchen Codebehinds. Entwickelt man für Windows Phone, so stößt man spätestens dann an seine Grenzen, wenn man die Application Bar verwenden möchte und die Buttons oder Menüeinträge an Commands aus dem ViewModel binden möchte. Den Grund dafür findet man auch relativ schnell in der MSDN.

Because the Application Bar is not a Silverlight control, it does not support some of the common control features, such as data-binding.

Damit ist man zunächst einmal darauf beschränkt, die Events wieder in der Codebehind-Datei abzufangen und dann gleich dort zu verarbeiten oder an das ViewModel weiterzugeben. So richtig schön sind beide Möglichkeiten nicht.

Mehr...

AdControl ohne Werbung

Das Microsoft Advertising SDK bietet auf einfach Art und Weise die Möglichkeit, in die Apps, die man kostenfrei im Marketplace anbietet oder in Apps im Trial-Mode Werbung einzublenden. Im einfachsten Fall befolgt man die Anleitung, und hat mit wenigen Schritten Erfolg. Was tut man aber, wenn man trotz der Anleitung keine Werbung sieht?

Ist das AdControl auf der Seite auch eingebunden?

Um das AdControl einzubinden ist eine Referenz auf Microsoft.Advertising.Mobile.UI notwendig. Die entsprechende Assembly liegt dem SDK bei. Beim Einbinden muss man darauf achten, die Eigenschaften Width und Height auf die Werte zu setzen, die man bei der Einrichtung des Werbeblocks angegeben hat.

<UI:AdControl Height="80" Width="480" ApplicationId="test_client" AdUnitId="Image480_80"/>

Abgesehen davon sollte man auch ApplicationId und AdUnitId setzen, aber das bemängelt das Control ja direkt als Exception. Zu Testzwecken kann man die Applikations-Id "test_client" und die Werbeblock-Id "Image480_80" (alternativ: "TextAd" oder "Image300_50") verwenden. Nun sollte ein Testbild angezeigt werden. Für das Release sollte man hier dann auf jeden Fall seine registrierten Ids eintragen.

Stimmen die Voraussetzungen?

Wird immer noch nichts angezeigt, sollte man noch einen Blick in die WMAppManifest werfen. Damit das Control funktioniert, sind mindestens folgende Einträge notwendig:

<Capabilities>
  <Capability Name="ID_CAP_NETWORKING" />
  <Capability Name="ID_CAP_MEDIALIB" />
  <Capability Name="ID_CAP_PHONEDIALER" />
  <Capability Name="ID_CAP_WEBBROWSERCOMPONENT" />
  <Capability Name="ID_CAP_IDENTITY_USER"/>
</Capabilities>

Wozu das AdControl die Telefonie-Voraussetzung braucht ist mir zwar nicht klar, aber es ist so. Bei mir war das Problem im übrigen der fehlende Eintrag für User-Identity.

Shake it!

Zugegeben, für den unbedarften Zuschauer sieht es etwas lustig aus, wenn man jemanden sieht, der sein Smartphone in der Hand hält und einmal kräftig schüttelt. Aber im Grunde gibt es diese Geste ja schon in vielen Systemen. In Windows 7 minimieren sich daraufhin alle anderen Fenster (Aero Shake), iTunes spielt daraufhin das nächste Lied und auch unter Windows Phone 7 Apps setzt sich diese Geste durch - hier wird sie meist zum Aktualisieren des aktuellen Screens eingesetzt - den meisten wird das wohl aus der Facebook-App bekannt sein.

Wer selbst die Shake-Geste in seiner Anwendung verwenden wollte, stand vor dem Problem, dass zwar alle Windows Phone 7 Geräte über einen Beschleunigungssensor verfügen und dieser auch per API anprogrammierbar ist, dass aber eine einfache Möglichkeit diese Geste zu ermitteln eben nicht gegeben ist. Das Silverlight-Toolkit bringt zwar einige Gesten mit, so z.B. Flip, Pinch und Tap, aber Shake fehlt auch hier.

Eine Abhilfe schafft die Shake Gesture Helper Library, die seit vergangenen Freitag im App Hub zu finden ist. Damit steht ein Helper zur Verfügung, der Events feuert, sobald eine Shake-Geste erkannt wird. Dabei ist frei konfigurierbar, wie häufig das Smartphone geschüttelt werden muss - und wer die Unterscheidung braucht, kann auch noch erkennen entlang welcher Achse geschüttelt wurde. Im beigefügten Beispiel ist hier die Anzahl notwendiger Richtungsänderungen auf 5 gesetzt - ich denke das ist etwas hoch gegriffen. Ich selbst höre nach 3 mal auf, zu hoffen, dass beim Schütteln mehr passiert als dass potenziell mein Smartphone aus der Hand fällt.

Auf jeden Fall ist es ein interessanter Helfer, der wohl dafür sorgen könnte, dass man demnächst wieder häufiger Anwender sieht, die ihr Windows Phone schütteln, denn den Entwicklern ist es damit sehr einfach gemacht, auch dieses Feature zu verwenden.

Advent, Advent.... - oder: eine App wurde geboren

Das letzte Treffen der .NET Usergroup Dresden ist nun schon ein paar Tage her. Durch den Abend hat uns Peggy Reuter geführt und der gesamten Entwicklerschar wieder einmal ein paar Tipps und Tricks zu Expression Blend gezeigt. Der Fokus lag dieses Mal auf UI Prototyping mit der Hilfe von Sketchflow. Und auch wenn die Gemüter sich streiten, ob von den entstandenen und vom Kunden abgenommenen Prototypen nun 90, 50 oder noch weniger Prozent direkt als Grundlage für das endgültige Produkt genommen werden können, so ist in meinen Augen Sketchflow ein gutes Mittel, um dem Kunden die eigenen Visionen etwas näher zu bringen und schon einmal einen Geschmack auf das zu machen, was dann das finale Produkt können wird.

Der zweite Teil des Abends drehte sich um Designprinzipien in Windows Phone 7 - und damit um das Metro-Design. Doch das Metro-Design ist nicht so starr vorgegeben, wie es auf viele den Eindruck macht. Auch hier sind Anpassungen möglich, die es uns Entwicklern erlaubt, individuelle Software zu erstellen.

Alle Anwesenden werden sich sicher an die Anwendung erinnern, anhand der Peggy die Erweiterungsmöglichkeiten demonstriert hat. Und wie sollte es anders sein: Unser Baby hat heute offiziell das Licht der Welt erblickt. Seit 18:59 Uhr sind wir Eltern eines kleinen Adventskalenders. Die Anwendung kann man im Marketplace herunterladen. An dieser Stelle noch einmal vielen Dank an Peggy, Lars und Torsten, die es ermöglicht haben, dass wir vier gemeinsam diese App auf die Beine gestellt haben.

Windows Phone 7 - It's time for a phone to save us from our phones

Nun ist es so ziemlich genau eine Woche her, seitdem ich mein neues Windows Phone 7 Device das erste Mal in die Hände nehmen konnte. Es gab ein paar Kritikpunkte, die ich in meinem ersten Post zu diesem Thema veröffentlicht habe. Dank der vielen Kommentare habe ich gemerkt, dass einige der von mir angemerkten Punkte in der Verantwortung meines Mobilfunkpoviders liegen (z.B. der Suchprovider im Internet Explorer), einige Punkte mit dem nächsten Softwareupdate behoben sein werden (z.B. das fehlende Copy & Paste) und an einige Punkte muss ich mich wohl gewöhnen, wenn ich die Vorteile alle nutzen will (z.B. komplette Kontaktliste in der Cloud).

Zusammengefasst bin ich aber nach wie vor begeistert. In meinen Augen kann es Microsoft damit endlich schaffen, wieder realistisch im Smartphone-Geschäft Fuß zu fassen. Und mit Silverlight und XNA als Basis ist den Entwicklern Handwerkszeug gegeben wurden, um für den Endanwender interessante Anwendungen zu entwickeln. Inzwischen gibt es Devices sowohl auf dem europäischen als auch dem us-amerikanischen Markt und die Registrierung für neue Apps ist freigegeben für alle Entwickler. Auch stolpere ich immer häufiger wieder über Werbeclips für das Betriebssystem, so dass auch Nicht-Nerds angefüttert werden.

In diesem Sinne: "It's time for a new phone...."

Windows Phone 7 - meine ersten Eindrücke

Seit gestern kann ich mich nun auch in die Reihe derer einreihen, die einem Windows Phone 7 ein Zuhause bieten. Die Gründe sind recht vielschichtig: Bisher war ich Nutzer eines Mobiltelefons, das auf Windows Mobile 6.5 basierte, das nur mit Hilfe von HTC Sense bedienbar wurde. Nun scheint Microsoft mit diesem Betriebssystem endlich den Sprung in Richtung Smartphones geschafft zu haben. Andererseits finde ich es faszinierend, auch mit meiner bevorzugten Programmiersprache Anwendungen schreiben zu können, die Spaß machen - und seit Mai 2010 bin ich mit dabei, wenn es um WP7-App-Entwicklung geht.

Nun aber genug der Lobhudeleien. Wo es Sonnenseiten gibt, gibt es auch Schattenseiten.

Geplanter Start von Windows Phone 7 in Deutschland sollte der 21.10. sein und sehr erwartungsvoll wartete ich wie viele in der Community auf den Startschuss - aber nichts passierte. Nun kann man sich mit Wortspielereien aus der Affaire ziehen, aber in meinen Augen ist der Start - aus Entwicklersicht - in die Hose gegangen. Aus Anwendersicht mag das anders sein: Seit Beginn dieser Woche laufen die Windows Phone 7 Spots in den Medien und auch die Anbieter haben neben den Plakaten für das jetzt frei verfügbare iPhone 4 auch die Plakete für jegliche Art von Windows Phone 7 Geräten aufgehängt.

Aber so richtig "verfügbar" ist es trotzdem nicht. Amazon hat die Geräte so ziemlich als erster im Shop gehabt - allerdings kann man es hier nach wie vor nur reservieren, nicht aber bestellen. O2 bietet mir die Bestellung an - jedoch werde ich (wie auch schon bei der Bestellung des HD2 vor knapp einem Jahr) gefühlt hingehalten. Mit Aussagen wie "Es ist schon losgeschickt, aber wir wissen nicht mit welchem Paketdienst.", "Es ist schon losgeschickt mit DHL, aber eine Sendungsverfolgungsnummer haben wir nicht." und quasi täglichen Versprechen "...spätestens übermorgen ist es bei Ihnen..." wurde ich knapp 2 Wochen hingehalten. In den O2 Shops sieht es auch nicht anders aus: Meinen Erfahrungen zufolge dürfen die Händler nur jeweils ein Gerät bestellen und erst sobald dieses verkauft ist, ein neues nachbestellen - heißt es gibt de facto nur alle 2 Tage ein Gerät zu verkaufen. Service sieht anders aus.

Inzwischen ist trotz aller Widrigkeiten ein HTC HD7 meins. Alles in allem macht es einen guten Eindruck. Einzig: Am Gerät selbst finde ich die Abdeckung für das Akku-Fach etwas billig. Das kann HTC besser und das haben sie auch beim HD2 gezeigt. Das Betriebssystem und auch die Apps laufen flüssig. Die Registrierung als Entwicklergerät ging super. Telefonieren, SMS schreiben funktioniert wie man es von einem Telefon erwarten kann. Auch die Einrichtung der Email-Konten war recht einfach und funktionierte (zumindest bei den bekannten Providern) automatisch.

Dummerweise hat auch dieses Betriebssystem - so cool es sein mag - seine Mankos. Viele davon liegen bei Microsoft, einige könnten auch bei meinem Provider liegen: Zum einen wäre da das fehlende Copy & Paste. Ja, ich möchte gern Kopieren und Einfügen - Informationen aus Kontakten in Nachrichten, Informationen aus Internetseiten in Browser-Adressleisten oder Notizen. Zum anderen fehlt mir die Synchronisationsmöglichkeit meiner Mails und Kontakte mit Outlook. Strategie ist, "der Benutzer steht im Mittelpunkt". Ich bin ein Benutzer und ich benutze Outlook und das auch im privaten Bereich. Und nun soll ich einen Exchange-Server installieren und hosten, um meine Kontakte und Kalendereinträge sowohl auf dem Device als auch auf meinem heimischen Rechner zu haben? Das kann doch nicht euer Ernst sein! Die Alternative ist der Outlook-Connector zu meinem Live-Account. Dann habe ich zwei Kalender und zwei Kontaktlisten, die ich manuell synchron halten muss. Der Benutzer steht bei beiden Ansätzen nicht im Vordergrund, sondern wohl eher die Marketingabteilung bei Microsoft, die sowohl die Live-Dienste als auch die Umsätze mit Exchange pushen will. Schade, denn hier könnte man mit wenig Aufwand viel erreichen.

Ein weiteres Manko ist der Standard-Suchprovider im Browser. Dass es nicht Google ist, war mir fast klar - schließlich will Microsoft seine Suchmaschine Bing vorantreiben und wenn mehr Leute in Deutschland Bing verwenden (müssen), dann wird wohl auch der Crawler häufiger mal auch deutsche Seiten crawlen und die Ergebnisse besser. Aber es ist nicht Bing! Nein: Der Standard-Suchprovider ist Yahoo. Wann hat jemand von euch eigentlich das letzte Mal mit Yahoo gesucht? Und natürlich ist diese Einstellung nicht änderbar...

Dieser Post hört sich sehr kritisch an? Das scheint nur so. Alles in allem bin ich sehr zufrieden mit dem Device bisher. Es gibt ein paar Mankos, von denen ich mir hoffe, dass sie sich in irgend einer Art und Weise beheben lassen - aber hier vertraue ich darauf, dass die Hersteller einsichtig werden und auf die Anwender hören - denn ist nicht der Kunde König?

[Update 03.11.2010]: Nachdem ich mich nun etwas näher mit den Hotmail-/Live-Diensten beschäftigt habe, hab ich herausgefunden, dass man seine Kontakt-Daten als CSV exportieren kann. Und somit mein Ich-lösch-versehentlich-meine-Kontakte-Problem lösen kann. Damit hab ich zumindest eine Backup-Möglichkeit - auch wenn mich an dieser stört, dass sie manuell ist.

[Update 04.11.2010]: Inzwischen hab ich auch herausgefunden, dass das Suchprovider-Problem durch meinen Mobilfunkanbieter O2 erzeugt wurde. die Devices haben zwar mehr Speicher als der Standard, dafür aber auch Yahoo statt Bing.

Verwirrendes NotFound

Das Szenario ist recht schnell umrissen: Abstrakt gesehen gibt es einen Webservice: Unter einer Url ist ein Endpunkt registriert, über den per Get-Parameter gesteuert die Daten gefiltert abgerufen werden können. Auf der Client-Seite gibt es eine Windows Phone 7 Anwendung, die mit Hilfe eines asynchronen WebRequest diese Url abfragt und die in der Response enthaltenen Daten deserialisiert und der Anwendung bereitstellt - also alles recht trivial.

Etwas überrascht war ich, als ich bei der Ausführung im Callback beim Aufruf von EndGetResponse dann eine WebException mit der Meldung "NotFound" bekam. Auch die Details der WebException waren nicht aussagekräftiger.

 

Beim Zugriff auf entfernte Inhalte bedeutet NotFound ja eigentlich, dass die angeforderte Ressource nicht da ist - eine Datei, ein Endpunkt oder was auch immer. Meist lässt sich dann auch mit einer Überwachung der http(s)-Anforderungen überprüfen, ob der Server irgendwo einen Statuscode 404 geliefert hat.

Genau das war aber bei mir nicht der Fall. Im Browser war die Url problemlos aufrufbar und lieferte Daten und die von mir an den WebRequest übergebenen Credentials waren auch die gleichen wie die, die ich im Browser eingegeben hatte. Auch die Überwachung des Traffics (wenn ich die Seite im Browser aufrief) zeigte nie einen Http-Statuscode im 400er oder 500er Bereich an.

Was war nun eigentlich das Problem? Ganz einfach: Ein selbst ausgestelltes Zertifikat. Was man im Browser bei bekannten Seiten recht schnell wegklickt, machte hier nun ein so großes Problem, dass der Zugriff ganz unterbunden wurde.

 

Da das Windows Phone 7 auch über keinen Certificate Store verfügt, im man mal eben Zertifikate ablegen kann und so Vertrauensstellungen definiert, war in diesem Fall der einfachere Weg, wieder auf http umzustellen.

Gewünscht hätte ich mir von der API eine aussagekräftigere Fehlermeldung, damit man gleich in der richtigen Richtung suchen kann. Jetzt weiß ich, dass NotFound bedeutet, dass irgend etwas schief gegangen ist.

VirtualBox und VERR_SVM_IN_USE

Vor einigen Monaten bin ich zu VirtualBox als Virtualisierungsumgebung gewechselt. Heute nun wollte ich eine virtuelle Maschine starten und wurde begrüßt mit einer schönen Fehlermeldung:

VirtualBox schien sich also mit irgend einer anderen Virtualisierungssoftware um Ressourcen zu streiten. Da ich mir sicher war, dass keine andere Software dieser Art lief, machte ich mich auf die Suche nach anderen laufenden Prozessen. 

Nach einigem Probieren wurde ich dann auch fündig: VirtualBox und der Windows Phone 7 Emulator können nicht zur gleichen Zeit auf einem Host laufen - und irgendwie ist der Emulator ja auch eine Art der Virtualisierung.