共用方式為


Get started on Live SDK for Windows Phone

[Update on 12/26/2012] Live SDK 5.3 is now available on Live Connect Developer Center ! Many new features in this release, most notably new .Net SDKs for both classic desktop and Asp.Net. It also include an updated Windows Phone SDK targeting the new Windows Phone 8. Even better, all our SDKs including the Windows and Windows Phone SDKs are now open source. Check out our LiveServices github depot, download the source code and party. This post is now updated to use code samples for Windows Phone 8. If you are looking for the starter guide for Windows Phone 7.x, please refer to the older post.

Live Connect provides developers a set of controls and APIs that enable applications to integrate sign-in with the user’s Microsoft account and access user information stored in Windows services such as SkyDrive and Hotmail. In this post, I will walk through the steps for creating a simple Live Connect powered Windows Phone application. Once you get you app started with the basic stuff, you can move on to learn more about our SkyDrive API and how to use it to cloud power your application.

A few words on the behind the scene stuff before I start the step-by-step guide. When building Windows Store apps on Windows 8, Single-Sign-On (SSO) is achieved with support from the OS. (To learn more about how to implement SSO for Windows Store apps, check out our //BUILD 2012 talk or my blog post for “Powering your apps and websites with Microsoft accounts”.) On Windows Phone, however, such support is not available for third party apps. To provide a good sign-in experience on mobile devices, Live Connect allows a mobile client to obtain a refresh token and use it to exchange for an access token. This provides a way for mobile clients to implement a Sign-In-Once experience and avoid the need to ask user for password every time the app is activated. To opt-in for this experience, your app needs to satisfy two criteria:

  1. The app must be provisioned as a mobile app.
  2. User must grant the app offline access permission.

We will discuss the details on how to meet these two criteria in the following step-by-step guide.

Pre-requisite:

Let’s start by creating a new Windows Phone application.

1. Create a new HelloWorldPhone Windows Phone application in Microsoft Visual Studio 2010 or Microsoft Visual Studio 2010 Express for Windows Phone using the Visual C# -> Silverlight for Windows Phone -> Windows Phone Application project template. Choose Windows Phone 8.0 as your target platform.

image_thumb2_thumb

2. Bring up the Add Reference dialog and go to the Assemblies –> extensions tab. Find the Microsoft.Live and Microsoft.Live.Controls assemblies. Add them to your project.

image_thumb4_thumb

3. Open MainPage.xaml in the designer. Bring the Toolbox in view and right-click to select Choose Items… Under Windows Phone Components tab, find the SignInButton control in the Microsoft.Live.Control namespace and add to your toolbox (You only need to do this once). You will see two entries here, choose the one that’s for Windows Phone 8 by examining the directory of the component dll. It should be something like C:\Program Files (x86)\Microsoft SDKs\Live\v5.0\Windows Phone 8.0\References.

image_thumb7_thumb

The SignInButton control should now show up in your toolbox.

PhoneToolBoxItem

4. Drag the SignInButton onto your designer surface. In your xaml file, change the generated xml for the SignInButton to the following:

 <Controls:SignInButton Name="btnLogin" Scopes="wl.signin wl.basic wl.offline_access" 
 SessionChanged="btnLogin_SessionChanged" HorizontalAlignment="Left" Margin="155,217,0,0" VerticalAlignment="Top"/>

5. Add a couple TextBlock elements to display the greeting and the error message (in case something goes wrong). Here’s the complete xaml for

 <phone:PhoneApplicationPage
     xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
     xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
     xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
     xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
     xmlns:Controls="clr-namespace:Microsoft.Live.Controls;assembly=Microsoft.Live.Controls"
     x:Class="HelloWorldPhone.MainPage"
     mc:Ignorable="d"
     FontFamily="{StaticResource PhoneFontFamilyNormal}"
     FontSize="{StaticResource PhoneFontSizeNormal}"
     Foreground="{StaticResource PhoneForegroundBrush}"
     SupportedOrientations="Portrait" Orientation="Portrait"
     shell:SystemTray.IsVisible="True">
  
     <!--LayoutRoot is the root grid where all page content is placed-->
     <Grid x:Name="LayoutRoot" Background="Transparent">
         <Grid.RowDefinitions>
             <RowDefinition Height="Auto"/>
             <RowDefinition Height="*"/>
         </Grid.RowDefinitions>
  
         <!--TitlePanel contains the name of the application and page title-->
         <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
             <TextBlock Text="Hello World" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
         </StackPanel>
  
         <!--ContentPanel - place additional content here-->
         <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
             <Controls:SignInButton ClientId="[Enter your Client ID]" Scopes="wl.signin wl.basic wl.offline_access" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" SessionChanged="btnLogin_SessionChanged"/>
             <TextBlock x:Name="tbGreeting" Text="Hello " HorizontalAlignment="Left" Margin="24,149,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Height="82" Width="394" FontSize="36"/>
             <TextBlock x:Name="tbError" HorizontalAlignment="Left" Margin="24,397,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Height="82" Width="394" FontSize="36"/>
         </Grid>
     </Grid>
  
 </phone:PhoneApplicationPage>

6. Add the following code in your MainPage.xaml.cs file.

 using System;
 using Microsoft.Phone.Controls;
  
 using Microsoft.Live;
 using Microsoft.Live.Controls;
  
 namespace HelloWorldPhone
 {
     public partial class MainPage : PhoneApplicationPage
     {
         private LiveConnectClient liveClient;
  
         public MainPage()
         {
             InitializeComponent();
         }
  
         private void btnLogin_SessionChanged(object sender, LiveConnectSessionChangedEventArgs e)        
         {            
             if (e != null && e.Status == LiveConnectSessionStatus.Connected)            
             {                
                 this.liveClient = new LiveConnectClient(e.Session);                
                 this.GetMe();            
             }            
             else            
             {                
                 this.liveClient = null;                
                 this.tbError.Text = e.Error != null ? e.Error.ToString() : string.Empty;            
             }        
         }        
         
         private async void GetMe()        
         {
             try
             {
                 LiveOperationResult operationResult = await this.liveClient.GetAsync("me");
                 var jsonResult = operationResult.Result as dynamic;
                 string firstName = jsonResult.first_name ?? string.Empty;
                 string lastName = jsonResult.last_name ?? string.Empty;
                 this.tbGreeting.Text = "Welcome " + firstName + " " + lastName;
             }
             catch (Exception e)
             {
                 this.tbError.Text = e.ToString();
             }
         }
     }
 }

Before proceeding, let’s take a look at what the above code does.

  • The xaml definition of the SignInButton control specifies the scopes that the app needs to ask user permissions for. We’re including 3 scopes here: wl.sign, wl.basic and wl.offline_access. Together these 3 scopes give the app access to user’s basic profile information and allows the app to access data even when the user is not actively using the app. For more information on Live Connect scopes, read here.
  • The xaml definition also adds an event handler for the SessionChanged event on the SignInButton. This event is fired when the sign-in process has finished.
  • If access is granted and the LiveConnectSession object indicates the LiveConnectSessionStatus as Connected, a new instance of the LiveConnectClient class is created with the current Session object.
  • In the function GetMe(), the code talks to the Live Connect REST API to retrieve user’s basic profile information by calling LiveConnectClient.GetAsync on “me”.LiveConnectClient.Async is implemented as an async operation using the Task async pattern. use the keyword “await” to call this API.
  • When the result comes back, the app can then obtain user’s first and last names through the operatonResult.Result IDictionary object. In this example, we cast operationResult.Result to a “dynamic” object so you can access the dictionary values through the .key syntax.

7. Before you can run the app, you need to provision it with Live Connect. Go to the application management site and click the Create Application link. Create an application called HelloWorldPhone.

PhoneNewApp

8. After you click “I accept”, an application is created for you with a client id and a client secret (values removed for discretion).

PhoneAppCreated

9. Go to Application Settings Page and click on the API Settings tab. Check “Yes” for “Mobile client app” and save.

PhoneAppCreated

10. The app is now provisioned and ready to go. Go back to your MainPage.xaml, and add the ClientId property on the SignInButton.

 <my:SignInButton Name="btnLogin" ClientId="[Your Client ID here]" HorizontalAlignment="Left" SessionChanged="btnLogin_SessionChanged" Scopes="wl.signin wl.basic wl.offline_access" />

11. You’re done. Hit F5 and run the app in the emulator. Click the “Sign In” button and type in a username and password to sign into Windows Live. Next you will see a screen asking user permission to access data.

image_thumb1

13. Click Yes. Notice that the SignInButton has changed to “Sign Out” state and a greetings with your name is displayed.

image_thumb2[1]

14. At this point, the app can continue to access user data until user signs out or until the refresh token is expired. A refresh token is valid for one year and is reset every time a new access token is issued. The user will not be asked for credentials again as long as the app is activated at least once a year.

For more Live Connect code samples, visit our github site at https://github.com/liveservices/livesdk.

Comments

  • Anonymous
    October 14, 2011
    Hi, i can't download the Live SDK with your link like this connect.microsoft.com/.../SelfNomination.aspx . If i use this like i get the message that i must register a live ID. But you can see i have a live id. Regards, Nico

  • Anonymous
    October 16, 2011
    Hi Nico, Live SDK is limited to Microsoft Connect partners.  A general final release will be available for all to download, but to use this preview, you need to register (it's free) to become a Microsoft Connect partner. Thanks. Shelly

  • Anonymous
    October 23, 2011
    Its a worth reading article. One quick question are these APIs are expected to change in Nov 2011 release as mentioned in help file ?

  • Anonymous
    October 27, 2011
    You mention the user has a refresh token, but how do you get the application to NOT need them to hit sign in again?  The refresh token is present after they signin, but I can't find any way to use the token the next time the application starts.  It always shows they have to login again.

  • Anonymous
    October 30, 2011
    @nishantcop, there will be minor API changes in the final release, but for the most part, it should not greatly affect existing code. @Jason, in order to use obtain the refresh token, the application must ask for the wl.offline_access scope.  Once user grants consent to wl.offline_access, a refresh token will be issued to the app.  The library takes care of storing the refresh token and uses it to obtain new access token automatically.

  • Anonymous
    December 01, 2011
    I am facing error "another async operation is already in progress", When the control loads second time. Here is the scenario.

  1. I am navigating to the page where the "SigninButton" is placed, but not doing any signing action.
  2. Go back
  3. Navigating to the same control and click Signin, now it is throwing above error (Unhandled error). Any help is appreciated.
  • Anonymous
    February 15, 2012
    Hello Shelly, I have a simple question: How to handle a scenario, where the SignInButton is placed on a secondary page, like a additional settings page? Thank you.

  • Anonymous
    April 17, 2012
    @Ragunathan, the question about the error "another async operation is already in progress", this is due to multiple login requests be processed at the same time.  When the sign-in button is initialized, it actually tries to talk to the server to get the latest sign status.  If that operation is not finished, clicking on the button would result in this error.  I do however agree that this might not be the best way to handle the situation.  We could have just ignored the second request.  We'll take this as feedback and see if we can improvement the experience.

  • Anonymous
    April 17, 2012
    @Ilija, you should be able to put the sign-in button on any page.  If you run into specific problems with placing the button, please visit our forum, we should be able to help you out with the support from our developer community.

  • Anonymous
    October 24, 2012
    Windows Mobile has the ability to reformat itself directly from its menu system. If you are giving your phone away or selling it, it is a good idea to format it first. Additionally, formatting is a quick way to free up storage if your phone is full on memory. Just be sure you back up your important files if you choose to do this. <a href="www.cdidesign.com/.../">mobile app development</a>

  • Anonymous
    November 03, 2012
    Hi, so I have succeeded in connecting my Windows Phone 8 Application to the Live API, I also succeeded in reading data from my hotmail account. But when I quit and restart my application, I lose all references to the session and the client objects and I have to start the process anew. I don't want to annoy the user with the web mask in which he has to agree again that he provides me with the needed permissions every time he is starting the application. But I also haven't found a way to get a reference to a session object without this step. The login mask is only shown the first time, afer that, only the interface mentioned in Picture 11 is shown. I already tried serializing the session object, which is not possible, because the class does not have a standard constructor. Any ideas? What am I doing wrong, I know that there is a way to login again without prompting the user. I'm thankful for every idea.

  • Anonymous
    January 02, 2013
    @ broadcastzero, did you add wl.offline_access to the list of scopes you request permission for?  Try that and if you still have problems, please consult our forum (social.msdn.microsoft.com/.../threads) for more technical support.

  • Anonymous
    January 25, 2013
    Thank you, Shelly for an excellent article!  It was thorough and didn't leave any steps out like so many articles these days.  I hope that in the future Windows Phone will be able to accomplish SSO to publish to SkyDrive by using the credentials already on the phone instead of prompting the user for them again, like the built-in phone apps (e.g. Camera app auto uploading to SkyDrive without prompting for credentials).  This article helped me so now I know it is possible to ask for credentials once and it will remember them.  The first impression by the end user however is that it is a poorly written app to not already know the credentials like the Microsoft apps.

  • Anonymous
    March 15, 2013
    Thanks a lot for writing such a great post :)

  • Anonymous
    February 06, 2014
    I'm noticing that if I leave the app (in emulator) running  [say >1 hour after Signing in the app], future calls [say to fetch skydrive files data] fail authentication even though I specified the wl.offline_access scope.  Is this scenario expected to work?