Georg fährt extra nach Berlin um Steve Ballmer zu treffen

31 Tage Mango | Tag #22: App Connect

Dieser Artikel ist Tag #22 der Serie 31 Tage Mango von Jeff Blankenburg.

Der Originalartikel befindet sich hier: Day #22: App Connect.

Dieser Artikel wurde in der Originalserie von Gastautor Matt Eland geschrieben. Bei Twitter kann Matt unter @integerman erreicht werden.

Was ist App Connect?

Windows Phone Mango hat zahlreiche Neuerungen und Erweiterungen für das Windows Phone Betriebssystem gebracht. Unter diesen sind auch einige für die Bing Suchmaschine auf dem Telefon. Während beispielsweise Visual Search und die verbesserten Wegbeschreibungen hauptsächlich den Endkunden nutzen, gibt es ein paar Features, mit denen Entwickler ihre Apps mit den Suchergebnissen integrieren können. Hierzu gibt es zwei Wege: mit Instant Answers werden relevante Apps zu einem Suchergebnis angezeigt; auf Quick Cards werden detaillierte Informationen und relevante Apps zu einem gesuchten Produkt, Ort oder einem Film angezeigt. Unten sehen Sie ein Beispiel für Suchergebnisse mit Quick Cards für alle Bücker, die der Suche des Benutzers entsprechen:

Wenn der Anwender auf einen der Einträge klickt, kommt er auf die Quick Card zum entsprechenden Produkt, wo er alle wichtigen Informationen zum Produkt an einer zentralen Stelle findet:

Mit dem neuen Mango-Feature App Connect können Anwendungen, die thematisch etwas mit der Suche zu tun haben, auf der „Anwendungen“ Pivot Seite der Quick Card angezeigt werden. Von dort kann der Anwender die App direkt starten. Basierend auf den Informationen der Quick Card kann die Anwendung nun selbst weitere relevante Informationen anzeigen.

Achtung: Die Quick Cards für Produkte und Filme werden derzeit nur in den USA unterstützt. Die Quick Card für Orte ist etwas mehr verbreitet (unter anderem auch in Deutschland). Unabhängig von dieser Einschränkung werden wir uns auch anschauen, wie der Text der Suchergebnisse lokalisiert werden kann.

Hier finden Sie eine aktuellere und detaillierte Liste zur Verfügbarkeit von Quick Cards: http://msdn.microsoft.com/en-us/library/hh202957(v=VS.92).aspx#BKMK_AppConnect

(Anm. leitning: Es ist soooo schade, dass die ganzen coolen Bing-Features in Europa nicht funktionieren. Local Scout, Visual Search und Search Extensibility sind für mich unter den geilsten Features von Windows Phone. Am liebsten würde ich sofort nach Redmond oder Unterschleißheim oder sonst wohin fahren und mithelfen, dass diese Features auch bei uns in Europa verfügbar werden.)

Ähnlich wie bei Quick Cards werden Apps auch unterrichtet, wenn Sie in Form einer Instant Answer (einer weiteren Erweiterung der Bing Suche in Mango) aufgerufen werden. Durch Bing Instant Answers können Apps in den Suchergebnissen angezeigt werden, wenn Bing diese für den spezifischen Suchbegriff als relevant erachtet.

In diesem Artikel werden wir eine Anwendung bauen, die Ihnen erlaubt, auf der Webseite eines Onlinehändlers nach einem Buch zu suchen. Hierzu verwenden wir die Erweiterungen der Suche für Bücher und Zeitschriften mittels Quick Cards. Weiterhin werden wir eine spezielle Ansicht anzeigen, wenn die App über Bing Instant Answers aufgerufen wurde.

Erste Schritte mit den Sucherweiterungen

Eigentlich ist die Einrichtung von App Connect für Ihre Anwendung relativ einfach. Es gibt aber einige Schritte, die Sie durchführen müssen damit alles funktioniert.

Wir beginnen, indem wir im Visual Studio eine neue Windows Phone Anwendung für Windows Phone 7.1 erstellen.

Sucherweiterungen registrieren

Damit Windows Phone weiß, dass Ihre Anwendung App Connect unterstützt, müssen Sie in der Manifest-Datei einen Eintrag hinzufügen, der beschreibt, welche Sucherweiterungen Ihre Anwendung unterstützt. Hier sollten Sie wirklich nur diejenigen Erweiterungen (zum Beispiel Produkttypen) angeben, die wirklich relevant für Ihre Anwendung sind.

Klappen Sie den Knoten Properties in Ihrem Projekt auf und öffnen Sie die Datei WMAppManifest.xml. Diese Datei definiert alle wichtigen Informationen über Ihre Anwendung. Innerhalb des App Elements müssen Sie einen Knoten Extensions hinzufügen, wie im folgenden Codebeispiel illustriert:

<Deployment xmlns="http://schemas.microsoft.com/windowsphone/2009/deployment" AppPlatformVersion="7.1">
    <App ="" >
        <IconPath IsRelative="true" IsResource="false">ApplicationIcon.jpg</IconPath>
        <Capabilities></Capabilities>
        <Tasks>
            <DefaultTask Name ="_default" NavigationPage="MainPage.xaml"/>
        </Tasks>
        <Tokens></Tokens>
        <Extensions>
            <!-- Beta extension, for development and testing only -->
            <Extension ExtensionName="Products"
            ConsumerID="{5B04B775-356B-4AA0-AAF8-6491FFEA5661}"
            TaskID="_default"
            ExtraFile="Extensions/Extras.xml" />
            <!-- Production extensions, for submission to Marketplace -->
            <Extension ExtensionName="Bing_Products_Books_and_Magazines"
            ConsumerID="{5B04B775-356B-4AA0-AAF8-6491FFEA5661}"
            TaskID="_default"
            ExtraFile="Extensions/Extras.xml" />
        </Extensions>
    </App>
</Deployment> 

Die wichtigen Bereiche sind hier die beiden Extension Elemente. ExtensionName gibt an, für welche Quick Card die Extension gilt. Für eine komplette Liste der verfügbaren Quick Cards sehen Sie hier nach: http://msdn.microsoft.com/en-us/library/hh202958(v=VS.92).

Im Emulator verhält sich App Connect anders als auf einem echten Telefon. Im Emulator haben alle Produkte die Kategorie „Products“ anstatt der detaillierteren ExtensionNames. Das heißt: wenn wir unsere App für Bücher und Zeitschriften registrieren, indem wir den ExtensionName „Bing_Products_Books_and_Magazines“ angeben, würde unsere App auf einem echten Telefon bei der Quick Card eines Buchs angezeigt werden aber nicht im Emulator. Wenn wir die App umgekehrt für „Products“ registrieren würden, würde im Emulator alles funktionieren aber auf einem echten Gerät würde unsere App nicht auftauchen. Aus diesem Grund empfiehlt es sich, sowohl die allgemeine „Products“ Kategorie als auch die spezifischen Kategorien durch Definition weiterer Extension Elemente zu unterstützen.

Die anderen Felder im Extension Element sind einfach: ConsumerID gibt an, dass die Extension sich auf das Feature Search Extensibility bezieht. Diese ID sollte nicht verändert werden. TaskID gibt an, was passieren soll, wenn die Erweiterung aufgerufen wird. ExtraFile sagt der App, wo die weiteren Daten zur Unterstützung der Sucherweiterungen liegen. Dies muss auf Extensions/Extras.xml verweisen. Andernfalls wird App Connect nicht funktionieren.

Konfiguration der weiteren Daten für App Connect

Da unser Projekt noch keine Datei Extensions/Extras.xml enthält, müssen wir diese zunächst erstellen. Klicken Sie mit rechts auf das Projekt und dann „Add > New Folder“. Geben Sie diesem Ordner den Namen „Extensions“. Klicken Sie mit rechts auf den Ordner und dann „Add > New Item“. Wählen Sie XML File aus der Liste und nennen Sie die Datei Extras.xml. Der Ordnername und der Dateiname müssen exakt so heißen – andernfalls werden die Sucherweiterungen nicht funktionieren.

Sie sollten jetzt eine Datei Extras.xml im Ordner Extensions haben. Wir fügen jetzt einen Knoten ExtrasInfo in der XML Datei hinzu. Durch diesen geben wir an, wie die App sich für die registrierten Erweiterungen verhalten soll.

<ExtrasInfo>
    <AppTitle>
        <!-- Neutral language application title. -->
        <default>Book Helper</default>
        <!-- Localized titles -->
        <es-ES>Libro Helper</es-ES>
        <fr-FR>Livre Helper</fr-FR>
        <zh-CN></zh-CN>
    </AppTitle>
    <Consumer ConsumerID="{5B04B775-356B-4AA0-AAF8-6491FFEA5661}">
        <ExtensionInfo>
            <Extensions>
                <!-- Corresponding product extension for books -->
                <ExtensionName>Bing_Products_Books_and_Magazines</ExtensionName>
                <!-- Beta extension, for all products. -->
                <ExtensionName>Products</ExtensionName>
            </Extensions>
            <CaptionString>
                <!-- Neutral language caption -->
                <default>Search vendors for books and eBooks</default>
                <!-- Localized captions -->
                <es-ES>Bsqueda de libros y libros electrnicos de varios proveedores</es-ES>
                <fr-FR>Recherche de livres et eBooks provenant de divers fournisseurs</fr-FR>
                <zh-CN></zh-CN>
            </CaptionString>
        </ExtensionInfo>
    </Consumer>
</ExtrasInfo> 

Das Element AppTitle und die Kindelemente geben an, wie unsere Anwendung heißen soll (mit verschiedenen, lokalisierten Namen). Im Knoten default geben wir den Namen an, der verwendet werden soll, wenn keiner der lokalisierten Strings passt. Dieser sollte dem Namen der App in der neutralen Sprache („neutral language“) des Assemblies entsprechen. Der Name in anderen Sprachen kann durch weitere Knoten angegeben werden. In unserem Beispiel geben wir beispielsweise einen Namen für die Sprache („language code“) es-ES (also Spanisch) an.

Der Knoten Consumer enthält eine ConsumerID, die der ConsumerID entspricht, die wir vorher in der Datei WMAppManifest.xml definiert haben. Innerhalb dieses Knotens gibt es einen Knoten ExtensionInfo, der wiederum einen Knoten Extensions enthält. Dieser enthält ExtensionName Elemente für die Extensions, von denen wir gesagt haben, dass wir sie unterstützen.

Das Element CaptionString definiert die kleine Nachricht, die unter dem Titel der Sucherweiterung angezeigt wird. Sie kann auf die selbe Weise lokalisiert werden wie das Element AppTitle. Ein Beispiel, wie diese Anwendung als Sucherweiterung aussieht, sehen Sie im folgenden Screenshot:

Beachten Sie, dass das Anwendungssymbol hier verwendet wird, und dass der Hintergrund hell oder dunkel sein kann. Sie sollten also keine transparenten Icons verwenden, wenn Sie Ihre App an App Connect angebunden haben. Weiterhin hat die Pivot Seite für App Connect im Emulator den Titel „extras“ während er auf einem echten Gerät „apps“ (bei uns „Anwendungen“) heißt.

Wenn Sie für unterschiedliche Typen von Produkten unterschiedliche Texte anzeigen wollen, können Sie das tun, indem Sie mehrere Elemente ExtensionInfo deklarieren und jeweils unterschiedliche ExtensionName Elemente verwenden. Dabei muss zu jedem unterstützten ExtensionName ein passendes ExtensionInfo vorhanden sein.

URI Mapping einrichten

Wenn ein Anwender die App über App Connect startet, wird die Laufzeitumgebung versuchen, zu einer Seite /SearchExtras zu navigieren. Um diesen Einstiegspunkt zu unterstützen, müssen wir eine Abbildung der URIs einrichten, die die Navigation auf die richtige Seite umleitet. Wir definieren hierzu eine Resource UriMapper in den Resourcen der App in der Datei App.xaml. Wir fügen die folgende Resource hinzu:

<Application.Resources>
    <nav:UriMapper x:Key="UriMapper" xmlns:nav="clr-namespace:System.Windows.Navigation;assembly=Microsoft.Phone">
        <nav:UriMapper.UriMappings>
            <nav:UriMapping Uri="/SearchExtras" MappedUri="/MainPage.xaml" />
        </nav:UriMapper.UriMappings>
    </nav:UriMapper>
</Application.Resources> 

Nur die Resource zu definieren ist aber nicht genug. Wir müssen der App noch mitteilen, wo sie den UriMapper findet, den sie zur Auflösung von Anfragen verwenden soll. Wir machen das, indem wir im Konstruktur in App.xaml.cs folgenden Code hinzufügen:

// Enable URI mapping for Search Extras deep link URIs

RootFrame.UriMapper = Resources["UriMapper"] as UriMapper; 

Jetzt werden alle über App Connect ankommenden Aufrufe korrekt an die MainPage umgeleitet. Wenn wir wollten, könnten wir in der Eigenschaft MappedUri eine spezielle Detailseite angeben, die nur beim Aufruf über App Connect sichtbar wird. Für unser Beispiel reicht es aber, auf die MainPage zu leiten.

App Connect in der App integrieren

Wenn Sie Ihre Anwendung jetzt im Emulator starten, dann zur Bing Suche wechseln, indem Sie den Suche Button drücken, sollten Sie Ihre Anwendung auf der „extras“ Pivot Seite einer Quick Card für Produkte sehen – vorausgesetzt, Sie haben Ihre App für Produkte registriert. Wie oben erwähnt, werden die einzelnen, detaillierteren Kategorien im Emulator nicht funktionieren. Umgekehrt wird eine App auf einem echten Gerät nicht angezeigt, wenn sie nur die zu allgemeine Kategorie „products“ unterstützt.

Unglücklicherweise macht unsere Anwendung noch nichts mit den Daten, die sie von App Connect bekommt. Wir beginnen mal wieder mit der Definition einer Benutzerschnittstelle. Wechseln Sie zur MainPage.xaml und ersetzen Sie das Grid mit dem Namen LayoutRoot (und alle seine Kinder) durch den folgenden Code:

<Grid Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <StackPanel Margin="12,17,0,28">
        <TextBlock Text="BOOK HELPER" Style="{StaticResource PhoneTextNormalStyle}" />
        <TextBlock Text="Welcome" x:Name="lblPageTitle" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}" />
    </StackPanel>
    <ScrollViewer Margin="12,0,12,0" Grid.Row="1">
        <StackPanel>
            <TextBlock TextWrapping="Wrap" x:Name="lblBookTitle" Visibility="Collapsed" Style="{StaticResource PhoneTextLargeStyle}" Text="Book title goes here" />
            <TextBlock TextWrapping="Wrap" x:Name="lblNoSearch" Text="To use this product, use your device's search functions to look for a book and then select this app from the apps section." Style="{StaticResource PhoneTextNormalStyle}" />
            <HyperlinkButton HorizontalContentAlignment="Left" Foreground="{StaticResource PhoneAccentBrush}" Margin="{StaticResource PhoneVerticalMargin}" Content="Search Amazon" Click="HandleSearchAmazonBooks" />
            <HyperlinkButton HorizontalContentAlignment="Left" Foreground="{StaticResource PhoneAccentBrush}" Margin="{StaticResource PhoneVerticalMargin}" Content="Search Barnes and Noble" Click="HandleSearchBarnesAndNoble" />
        </StackPanel>
    </ScrollViewer>
</Grid> 

Damit haben wir eine Benutzerschnittstelle, die sowohl als eigenständige App (also wenn sie normal aufgerufen wird) als auch als Detailseite funktionieren wird (wenn sie per App Connect aufgerufen wird). Standardmäßg sieht unsere Anwendung so aus:

Query Parameter verarbeiten

Wenn die Anwendung von einer Quick Card über App Connect aufgerufen wurde, wollen wir die Informationen von App Connect natürlich nutzen. Hierfür enthält der Navigationskontext zwei Query String Parameter, die uns wesentliche Informationen über die aufrufende Quick Card mitteilen. Das Query String Argument ProductName enthält den Namen des Produkts, das der Anwender auf der Quick Card gerade betrachtet hat und das Argument Category enthält den ExtensionName der Quick Card.

Es ist wichtig, das Laden der Seite abzuwarten, bevor man die Query String Parameter abfragt. Der NavigationContext wird nicht bereit sein, bevor die Seite komplett geladen ist.

Auch wenn die übergebenen Daten nur relativ grundlegende Informationen beinhalten, sind sie hilfreich, um Felder oder Controls schon mal mit Werten vorzubelegen, oder für Anwendungen, die mit mehreren Kategorien von Produkten umgehen. Denken Sie wieder daran, dass die Kategorie im Emulator immer „Products“ sein wird. Auf einem echten Gerät werden aber die richtigen Kategorien verwendet.

In unserer Beispielanwendung zeigen wir den Namen des Produkts auf der Seite an, wenn sie über App Connect gestartet wurde. Wir lassen die Benutzerschnittstelle unverändert, wenn die Anwendung normal gestartet wurde. Da der Einstieg in die Anwendung über die Sucherweiterungen in unserer Demo die selbe Seite verwendet wie der normale Einstieg in die App, ist es wichtig, dass wir zunächst prüfen, ob die Query String Argumente überhaupt vorhanden sind bevor wir diese verwenden.

Hier ist die überarbeitete MainPage.xaml.cs. Diese enthält jetzt die Logik zum Parsen der Query String Parameter und behandelt die Klicks auf die Hyperlinks:

public partial class MainPage : PhoneApplicationPage
{
   private string _book;
   // Constructor
   public MainPage()
   {
      InitializeComponent();
      // We need to wait until loaded before checking NavigationContext
      Loaded += HandleLoaded;
   }

   private void HandleLoaded(object sender, RoutedEventArgs e)
   {
      // Determine what the context of the app launch is
      if (NavigationContext.QueryString.ContainsKey("ProductName"))
      {
         _book = NavigationContext.QueryString["ProductName"];
         lblPageTitle.Text = "Book Details";
      }
      else
      {
         _book = null;
      }

      // In a "real" application we'd want to use binding and converters
      if (!string.IsNullOrWhiteSpace(_book))
      {
         lblBookTitle.Text = _book;
         lblNoSearch.Visibility = Visibility.Collapsed;
         lblBookTitle.Visibility = Visibility.Visible;
      }
      else
      {
         lblNoSearch.Visibility = Visibility.Visible;
         lblBookTitle.Visibility = Visibility.Collapsed;
      }
   }

   private void HandleSearchBarnesAndNoble(object sender, RoutedEventArgs e)
   {
      if (string.IsNullOrWhiteSpace(_book))
      {
         BrowseTo("http://www.barnesandnoble.com/ebooks/index.asp");
      }
      else
      {
         BrowseTo("http://productsearch.barnesandnoble.com/search/results.aspx?store=BOOK&keyword=\"" + _book.Replace(" ", "+") + "\"");
      }
   }

   private void HandleSearchAmazonBooks(object sender, RoutedEventArgs e)
   {
      if (string.IsNullOrWhiteSpace(_book))
      {
         BrowseTo("http://www.amazon.com/gp/aw/sb.html/sn=Books");
      }
      else
      {
         BrowseTo("http://www.amazon.com/gp/aw/s/?k=" + _book.Replace(" ", "+"));
      }
   }

   private static void BrowseTo(string address)
   {
      var webTask = new Microsoft.Phone.Tasks.WebBrowserTask { Uri = new Uri(address) };
      webTask.Show();
   }
}

Wenn wir unsere Anwendung jetzt über App Connect starten, sehen wir beispielsweise das folgende:

App Instant Answers unterstützen

Ein weiteres neues Mango Feature sind die App Instant Answers. Dieses ist ein automatisches Feature der Bing Suche, durch das Apps, die Bing als relevant für eine spezielle Suche betrachtet, oben in der Ergebnisliste der Suche angezeigt werden. Sie müssen nichts machen, um den Start über Instant Answers zu unterstützen. Sie sollten aber die Informationen nutzen, die in diesem Fall an die Anwendung übergeben werden. Diese werden in Form eines Query String Parameters mit dem Namen „bing_query“ übergeben. Der Zugriff darauf erfolgt genau wie oben auf die Query String Parameter ProductName und Category.

Die Anwendung zur Nutzung von App Instant Answers zu erweitern ist also sehr einfach. Im folgenden Codebeispiel habe ich die obere Hälfte der Methode HandleLoaded überarbeitet:

// Determine what the context of the app launch is
if (NavigationContext.QueryString.ContainsKey("ProductName"))
{
   _book = NavigationContext.QueryString["ProductName"];
   lblPageTitle.Text = "Book Details";
}
else if (NavigationContext.QueryString.ContainsKey("bing_query"))
{
   _book = NavigationContext.QueryString["bing_query"];
   lblPageTitle.Text = "Related Search";
} 

Mit dieser Modifikation kann die Anwendung den Namen des Buchs entweder aus dem von einer Quick Card übergebenen ProductTitle oder aus der über Instant Answers übergebenen Bing Suchanfrage auslesen. Das Bild unten illustriert den Einstieg in die App über Instant Answers wenn der Suchbegriff „Sphere by Michael Crichton“ war.

App Connect testen

Sie werden sich vielleicht fragen, wie man App Connect testen kann oder wie man den Debugger mit den Sucherweiterungen verwenden kann. Das ist in der Tat eine gute Frage, da es momentan erstens keine Möglichkeit gibt, die Bing Suchergebnisse zu manipulieren und da zweitens die Kategorie im Emulator nicht die selbe ist wie auf einem tatsächlichen Gerät. Weiterhin kann es auf Dauer lästig werden, immer erst zu Bing zu navigieren, einen Suchbegriff einzugeben um dann die Anwendung über App Connect zu starten. Zum Glück kann man den Aufruf über die Sucherweiterungen oder über Instant Answers recht leicht simulieren.

Wir wissen, welche Query String Parameter im Falle des Aufrufs aus einer Quick Card übergeben werden. Wir können uns dieses Wissen zunutze machen, indem wir die entsprechenden Werte zum Testen im Einstiegspunkt der App hart kodieren. Die Adresse der Einstiegsseite einer Windows Phone Anwendung wird in der Datei WMAppManifest.xml definiert. Öffnen Sie die Datei und suchen Sie nach dem Element DefaultTask in der Tasks Collection. Dieses sollte etwa so aussehen:

<DefaultTask Name ="_default" NavigationPage="MainPage.xaml"/>

Dieses Element legt fest, wohin die Anwendung beim Start navigieren soll. Sie können hier angeben, was Sie wollen. Insbesondere können wir das Element so verändern, dass es den Aufruf über die Sucherweiterungen oder über Instant Answers simuliert, indem wir die entsprechenden Query String Parameter angeben. Den folgenden Code habe ich beispielsweise benutzt, um den Aufruf über Instant Answers aus dem obigen Screenshot zu simulieren:

<DefaultTask Name ="_default" NavigationPage="MainPage.xaml?bing_query=Sphere by Michael Crichton"/>

Die Änderungen zur Simulation eines Aufrufs über die Sucherweiterungen sind sehr ähnlich. Da wir in diesem Fall zwei Query String Parameter haben, müssen wir das trennende & mit &amp; maskieren:

<DefaultTask Name ="_default" NavigationPage="MainPage.xaml?Category=Bing_Products_Books_and_Magazines&amp;ProductName=Sphere"/>

Natürlich sollten Sie nicht vergessen, die hardkodierten Query String Parameter nach dem Testen und vor der Veröffentlichung wieder zu entfernen, damit der DefaultTask wieder so funktioniert wie er soll.

Wenn Sie die Datei WMAppManifest.xml bearbeiten, kann es manchmal zu Fehlern bei der Installation der Anwendung im Emulator kommen. Wenn die Installation im Emulator mit der Nachricht „Installation of the application failed. Run time error has occurred. Fix the Capabilities in WMAppManifest.xml file.“ fehlschlägt, der Abschnitt Capabilities aber in Ordnung ist, bauen Sie die Anwendung einfach neu und probieren es noch einmal.

Zusammenfassung

Damit sind wir am Ende unseres Artikels zu App Connect und Instant Answers – zwei einfachen Möglichkeiten, Ihre Anwendung mit der Bing Suchmaschine in Windows Phone Mango zu integrieren.

Um eine komplette Solution mit dem Code dieses Artikels herunterzuladen, klicken Sie auf den Download Code Button unten:

Morgen kommt Samidip Basu zurück und wird uns das Ausführungsmodell von Windows Phone näherbringen. Er wird dabei auf Fast App Switching und Tombstoning (welches bereits hier behandelt wurde: Day #14 of 31 Days of Windows Phone) und auf die Änderungen seit Windows Phone 7.5 eingehen.

Bis dahin!

Kommentare sind geschlossen.