1. Problem
You have to add interaction between your application and external phone applications such as Phone, Search, and Marketplace.
2. Solution
You can add interaction between your application and your phone applications by using launchers and choosers classes.
3. How It Works
Windows Phone 7 applications
have their own private storage and cannot interact with other
applications installed on the phone. In some cases, you need to perform a
particular task in your application that requires use of existing
Windows Phone applications. In those cases you can use both launchers
and choosers to add interaction with particular Windows Phone
applications.
Indeed, there is no way to add
interaction between two applications with launchers and choosers. You
can only integrate into your application common tasks such as a phone
call, an e-mail composer, the Marketplace, the photo camera, the web
browser, and the search function.
The main difference
between launchers and choosers is that launchers don't return any kind
of data to the application caller. The choosers implement an
asynchronous event handler that is called after the operation is
completed, returning the data to the application caller.
After having used a
launcher or a chooser, the application caller is closed, so it's very
important to correctly manage tombstoning.
Indeed, when the launcher or chooser has completed its operations, the
application caller is launched again with the tombstoning feature.
In Table 1 and Table 2, you can find the names and descriptions of each launcher and chooser available from the Microsoft.Phone.Tasks namespace, respectively.
Table 1. launchers Available from the Windows Phone 7 SDK
Launcher | Description |
---|
EmailComposeTask | Launches the e-mail application and optionally fills an e-mail field such as Body, To, Cc, and so on. |
MarketplaceDetailTask | Launches
the Marketplace application, showing details either on the current
application or the application specified by its identifier. |
MarketplaceHubTask | Launches the Marketplace application, showing either the Application section or the Music section. |
MarketplaceReviewTask | Launches the Marketplace application, showing the review form to add a comment to your application. |
MarketplaceSearchTask | Launches the Marketplace application, showing the search form with results based on the text you provided. |
MediaPlayerLauncher | Launches the Media Player application playing the specified media file. |
PhoneCallTask | Launches the Phone application, showing the phone number and display name. The phone call is not automatically started. |
SearchTask | Launches the Search application, performing the query with the provided text. |
SmsComposeTask | Launches the Messaging application with a new SMS filled with provided arguments such as the Body and To data. |
WebBrowserTask | Launches the Internet Explorer application, displaying the provided URL. |
Table 2. Choosers Available from the Windows Phone 7 SDK
Chooser | Description |
---|
CameraCaptureTask | Launches the Camera application, and if the user takes the photo, the photo is returned to the application caller |
EmailAddressChooserTask | Launches the Contact application, allowing users to select a contact whose e-mail is returned to the application caller |
PhoneNumberChooserTask | Launches the Contact application, allowing users to select a contact whose phone number is returned to the application caller |
PhotoChooserTask | Launches the Photo Picker application, allowing users to pick a photo from the media library |
SaveEmailAddressTask | Saves the provided e-mail address into the Contact application |
SavePhoneNumberTask | Saves the phone number into the Contact application |
4. The Code
In this recipe, you will create a Silverlight for Windows Phone 7 application called LaunchersAndChoosersDemo that implements the Pivot control with two items, launchers and choosers. Every pivot item contains a ListBox
with an item for each launcher and for each chooser. After the user
selects a list box item the application will launch either the related
launcher or chooser.
In the MainPage.xaml file, the Pivot control contains two items, both of which fill a ListBox with the complete list of launchers and choosers. The SelectionChangedListBox is managed to retrieve the selected item and show the related launcher or chooser. event from the
. . .
<controls:Pivot Title="LAUNCHERS AND CHOOSERS">
<!--Pivot item one-->
<controls:PivotItem Header="Launchers">
<!--Double line list with text wrapping-->
<ListBox x:Name="FirstListBox" Margin="0,0,-12,0"
SelectionChanged="FirstListBox_SelectionChanged">
<ListBoxItem x:Name="iEmailComposeTask" Content="EmailComposeTask"
HorizontalAlignment="Center" Height="55"/>
<ListBoxItem x:Name="iMarketplaceDetailTask"
Content="MarketplaceDetailTask"
HorizontalAlignment="Center" Height="55" />
<ListBoxItem x:Name="iMarketplaceHubTask" Content="MarketplaceHubTask"
HorizontalAlignment="Center" Height="55"/>
<ListBoxItem x:Name="iMarketplaceReviewTask"
Content="MarketplaceReviewTask"
HorizontalAlignment="Center" Height="55"/>
<ListBoxItem x:Name="iMarketplaceSearchTask"
Content="MarketplaceSearchTask"
HorizontalAlignment="Center" Height="55"/>
<ListBoxItem x:Name="iMediaPlayerLauncher" Content="MediaPlayerLauncher"
HorizontalAlignment="Center" Height="55"/>
<ListBoxItem x:Name="iPhoneCallTask" Content="PhoneCallTask"
HorizontalAlignment="Center" Height="55"/>
<ListBoxItem x:Name="iSearchTask" Content="SearchTask"
HorizontalAlignment="Center" Height="55"/>
<ListBoxItem x:Name="iSmsComposeTask" Content="SmsComposeTask"
HorizontalAlignment="Center" Height="55"/>
<ListBoxItem x:Name="iWebBrowserTask" Content="WebBrowserTask"
HorizontalAlignment="Center" Height="55"/>
</ListBox>
</controls:PivotItem>
<!--Pivot item two-->
<controls:PivotItem Header="Choosers">
<ListBox x:Name="SecondListBox" Margin="0,0,-12,0"
SelectionChanged="SecondListBox_SelectionChanged">
<ListBoxItem x:Name="iCameraCaptureTask" Content="CameraCaptureTask"
HorizontalAlignment="Center"
Height="95" VerticalAlignment="Center" />
<ListBoxItem x:Name="iEmailAddressChooserTask"
Content="EmailAddressChooserTask"
HorizontalAlignment="Center" Height="95"
VerticalAlignment="Center" />
<ListBoxItem x:Name="iPhoneNumberChooserTask"
Content="PhoneNumberChooserTask" HorizontalAlignment="Center"
Height="95" VerticalAlignment="Center" />
<ListBoxItem x:Name="iPhotoChooserTask" Content="PhotoChooserTask"
HorizontalAlignment="Center" Height="95"
VerticalAlignment="Center" />
<ListBoxItem x:Name="iSaveEmailAddressTask"
Content="SaveEmailAddressTask" HorizontalAlignment="Center"
Height="95" VerticalAlignment="Center" />
<ListBoxItem x:Name="iSavePhoneNumberTask"
Content="SavePhoneNumberTask" HorizontalAlignment="Center"
Height="95" VerticalAlignment="Center" />
</ListBox>
</controls:PivotItem>
</controls:Pivot>
. . .
In the MainPage.xaml.cs file, there is the SelectionChanged
event handler for both list boxes. Within the event handlers, a switch
case is used to retrieve the selected item and execute the related
launcher or chooser. Let's start analyzing each launcher.
When the iEmailComposeTask list box item is selected, a new EmailComposeTask object is created and its own properties are filled with some values. You can specify the destination address by using the To property, the e-mail subject by using Subject, the e-mail body by using Body, and eventually a carbon copy address by using the Cc property. Finally, by calling the Show method, the launcher is executed and a new e-mail is created.
private void FirstListBox_SelectionChanged(object sender,
SelectionChangedEventArgs e)
{
switch ((e.AddedItems[0] as ListBoxItem).Name)
{
case "iEmailComposeTask":
EmailComposeTask ect = new EmailComposeTask();
ect.To = "[email protected]";
ect.Subject = "Some subject";
ect.Body = "email content here";
ect.Show();
break;
. . .
The next launchers are used to interact with the Marketplace. The MarketplaceDetailTask class provides two properties: the ContentType can be set only to the MarketplaceContentType.Applications value, and the ContentIdentifier can be either omitted to retrieve detail for the current application or set to an application identifier.
The MarketplaceHubTask class provides the ContentType property that can be set to either MarketplaceContentType.Applications or MarketplaceContentType.Music so that the Marketplace application starts by showing either the Applications section or the Music section, respectively.
The MarketplaceReviewTask class provides only the Show method, because it opens the Marketplace, allowing users to review the current application.
The MarketplaceSearchTask class provides the SearchTerms property for specifying the text that has to be searched in the context set by the ContentType property.
. . .
case "iMarketplaceDetailTask":
MarketplaceDetailTask mdt = new MarketplaceDetailTask();
mdt.ContentType = MarketplaceContentType.Applications;
mdt.Show();
break;
case "iMarketplaceHubTask":
MarketplaceHubTask mht = new MarketplaceHubTask();
mht.ContentType = MarketplaceContentType.Applications;
mht.Show();
break;
case "iMarketplaceReviewTask":
MarketplaceReviewTask mrt = new MarketplaceReviewTask();
mrt.Show();
break;
case "iMarketplaceSearchTask":
MarketplaceSearchTask mst = new MarketplaceSearchTask();
mst.ContentType = MarketplaceContentType.Music;
mst.SearchTerms = "Radiohead";
mst.Show();
break;
. . .
The MediaPlayerLauncher class provides the Media
property, which is used to specify the URL of the media file to be
played. The file has to be saved in the isolated storage either by the
application itself or when the application is deployed on the phone. The
Location property defines where the media file is located, either in the installation file or in the isolated storage. Finally, the Controls property is used to specify which buttons the media player has to show.
. . .
case "iMediaPlayerLauncher":
MediaPlayerLauncher mpl = new MediaPlayerLauncher();
mpl.Media = new Uri("video.wmv", UriKind.Relative);
mpl.Location = MediaLocationType.Data;
mpl.Controls = MediaPlaybackControls.Pause |
MediaPlaybackControls.Stop |
MediaPlaybackControls.Rewind;
mpl.Show();
break;
. . .
The PhoneCallTask launcher provides the PhoneNumber property used to specify the phone number to call and the DisplayName property to display the contact name.
. . .
case "iPhoneCallTask":
PhoneCallTask pct = new PhoneCallTask();
pct.DisplayName = "My contact";
pct.PhoneNumber = "55512345678";
pct.Show();
break;
. . .
The SearchTask launcher provides the SearchQuery property used to specify the text to search both on the Web and locally.
. . .
case "iSearchTask":
SearchTask st = new SearchTask();
st.SearchQuery = "Facebook";
st.Show();
break;
. . .
The SmsComposeTask launcher provides classic properties such as To and Body
to fill the message recipient and message content fields. If you don't
specify these properties, an empty message will be created. The message
will not be sent until the user sends it.
. . .
case "iSmsComposeTask":
SmsComposeTask sct = new SmsComposeTask();
sct.To = "My contact";
sct.Body = "sms content";
sct.Show();
break;
. . .
The WebBrowserTask class provides the URL property to specify which Internet address has to be shown in the web browser application.
. . .
case "iWebBrowserTask":
WebBrowserTask wbt = new WebBrowserTask();
wbt.URL = "http://www.apress.com";
wbt.Show();
break;
}
}
NOTE
Each launcher class and each chooser class provides the Show
method that is responsible for performing the related action, such as
showing the web browser, opening the e-mail composer, and so on.
In the other SelectionChanged
event handler of the Choosers list box, there is another switch case
that is executed by the code related to the user's choice.
private void SecondListBox_SelectionChanged(object sender,
SelectionChangedEventArgs e)
{
switch ((e.AddedItems[0] as ListBoxItem).Name)
{
case "iCameraCaptureTask":
MessageBox.Show("See recipe 7-1 for
CameraCaptureTask chooser explanation.");
break;
case "iPhotoChooserTask":
MessageBox.Show("See recipe 7-2 for
PhotoChooserTask chooser explanation.");
break;
. . .
The EmailAddressChooserTask executes the Contact application and raises the Completed event after the user has chosen a contact.
. . .
case "iEmailAddressChooserTask":
EmailAddressChooserTask eact = new EmailAddressChooserTask();
eact.Completed +=
new EventHandler<EmailResult>(EmailAddressChooserTask_Completed);
eact.Show();
break;
. . .
The Completed event handler provides the EmailResult parameter with the Email property containing the e-mail address of the selected contact.
void EmailAddressChooserTask_Completed(object sender, EmailResult e)
{
if (e.TaskResult == TaskResult.OK)
MessageBox.Show(e.Email);
}
Similar to the previous chooser, the PhoneNumberChooserTask class opens the Contact application and raises the Completed event when the user has finished selecting a contact. This time, the returning parameter of the Completed event handler will be the contact's phone number.
. . .
case "iPhoneNumberChooserTask":
PhoneNumberChooserTask pnct = new PhoneNumberChooserTask();
pnct.Completed +=
new EventHandler<PhoneNumberResult>(PhoneNumberChooserTask_Completed);
pnct.Show();
break;
. . .
void PhoneNumberChooserTask_Completed(object sender, PhoneNumberResult e)
{
if (e.TaskResult == TaskResult.OK)
MessageBox.Show(e.PhoneNumber);
}
Finally, the SaveEmailAddressTask and SavePhoneNumberTask
choosers save a new e-mail address and a new phone number when adding a
new contact, respectively. Neither chooser returns a value from the Completed event handler—just the result of whether the operation has been completed successfully or has been aborted by the user.
. . .
case "iSaveEmailAddressTask":
SaveEmailAddressTask seat = new SaveEmailAddressTask();
seat.Completed +=
new EventHandler<TaskEventArgs>(SaveEmailAddressTask_Completed);
seat.Email = "[email protected]";
seat.Show();
break;
case "iSavePhoneNumberTask":
SavePhoneNumberTask spnt = new SavePhoneNumberTask();
spnt.PhoneNumber = "55512345678";
spnt.Completed +=
new EventHandler<TaskEventArgs>(SavePhoneNumberTask_Completed);
spnt.Show();
break;
}
}
void SavePhoneNumberTask_Completed(object sender, TaskEventArgs e)
{
if (e.TaskResult == TaskResult.OK)
MessageBox.Show("Phone numeber saved correctly");
else if (e.TaskResult == TaskResult.Cancel)
MessageBox.Show("Save operation cancelled");
}
void SaveEmailAddressTask_Completed(object sender, TaskEventArgs e)
{
if (e.TaskResult == TaskResult.OK)
MessageBox.Show("Email saved correctly");
else if (e.TaskResult == TaskResult.Cancel)
MessageBox.Show("Save operation cancelled");
}
5. Usage
From Visual Studio 2010,
press Ctrl+F5. Depending on the target output, the application deploys
either on the physical device or the emulator.
The LaunchersAndChoosersDemo application will run, briefly showing the Launchers pivot item with its own list box filled with launchers (see Figure 1).
If you flick to the left, the application will show the second pivot item filled with all the available choosers (see Figure 2).
Now you can tap a list box item and see the related functionality. For example, Figure 3 shows the MarketplaceSearchTask launcher.
NOTE
The EmailComposeTask launcher cannot be tested on the emulator because it doesn't provide an e-mail composer application. Moreover, the MarketplaceDetailTask launcher doesn't work in either target output until the Marketplace accepts your application.