在Windows Phone 8中使用Live Connect并保持登陆状态
Live Connect可以让各种客户端访问Live账号、获取好友列表、访问One Drive的文件等,官方地址在此:http://msdn.microsoft.com/zh-cn/live/ff519582
贴几个有用的地址,实在是太难找了:
Live SDK下载:http://msdn.microsoft.com/zh-CN/live/ff621310
应用管理地址:https://account.live.com/developers/applications/index
Github上的代码:https://github.com/liveservices/,https://github.com/liveservices/LiveSDK
MSDN代码示例:http://code.msdn.microsoft.com/SkyDrive-Photo-API-sample-f06778ae
作用域和权限说明,感觉这个是比较重要的:http://msdn.microsoft.com/zh-cn/library/live/hh243646.aspx
在Windows Phone中使用的代码示例:http://msdn.microsoft.com/zh-cn/library/live/hh826550.aspx
一、使用前的准备
对于Windows Phone应用来说,首先需要在应用管理添加应用。URL貌似不填也没关系。需要注意的是,在API设置里一定,“移动或桌面客户端应用”一定要选择“是”,才能使用OAuth2.0验证流程。根域、重定向URL根据需要填写。我需要的只是获取用户身份,访问One Drive文件,因此没填。
二、使用方式
基本上使用有两种方式,SDK里提供了现成的登陆控件,可以直接用,如果不用这个控件的话也可以自己写登陆过程。
使用控件的方式可参考http://msdn.microsoft.com/zh-cn/library/live/hh826550.aspx的代码示例,拖一个SignInButton进来,设置好SessionChanged事件就可以了,不需要管Click事件,点击的时候控件自己会调用相应的处理程序。
如果自己写的话,可以采用这里的方式:http://lancelarsen.com/persisting-skydrive-login-on-windows-phone-8-via-livesdk/ 主要代码如下:
private static readonly string[] _scopes = new[] { "wl.signin", "wl.basic" }; private LiveConnectClient _connection; private LiveLoginResult _login; public LiveLogin() { this.Loaded += this.OnLoaded; } private async void OnLoaded(object sender, RoutedEventArgs routedEventArgs) { //---------------------------------------------------------------------- // Login to skydrive //---------------------------------------------------------------------- await SkydriveLogin(); } private async Task SkydriveLogin() { try { //---------------------------------------------------------------------- // Initialize our auth client with the client Id for our specific application //---------------------------------------------------------------------- LiveAuthClient authClient = new LiveAuthClient("**your client id here**"); //---------------------------------------------------------------------- // Using InitializeAsync we can check to see if we already have an connected session //---------------------------------------------------------------------- _login = await authClient.InitializeAsync(_scopes); //---------------------------------------------------------------------- // If not connected, bring up the login screen on the device //---------------------------------------------------------------------- if (_login.Status != LiveConnectSessionStatus.Connected) { _login = await authClient.LoginAsync(_scopes); } //---------------------------------------------------------------------- // Initialize our connection client with our login result //---------------------------------------------------------------------- _connection = new LiveConnectClient(_login.Session); } catch (Exception ex) { //TODO: Add connection specific exception handling } }
注意一下作用域与权限,一般来说wl.signin wl.basic这两个是必须的,我在第一次用的时候发现即使用户登录了,下次打开应用还需要再次点击授权一次,很麻烦,后来发现必须要加上wl.offline_access这个作用域,下次登陆就默认是登陆状态了。
三、参考文章
http://igrali.com/2012/12/11/live-connect-sdk-for-windows-phone-8authenticating-and-basic-info/
http://stackoverflow.com/questions/10946629/wp7-how-to-store-liveconnectsession-during-tombstoning
四、实践
我的目的是,用户可以不必登陆即可浏览,但如果要发布评论的话必须登陆Live账号,用户登录一次后,下次打开应用应该就可以直接获取用户信息而不必再次登陆了。
首先在App.xaml.cs里添加一个静态变量,用来保存当前Live连接,也可以直接保存获取到的用户信息
/// <summary> /// live client /// </summary> public static LiveConnectClient CurrentLiveConnectClient { get; set; }
在程序运行时先看看当前的连接状态,如果已经登陆过了,则设置当前的Live连接,否则就什么也不用做了,等需要用户登录操作的时候再提示:
try { string[] _scopes = new string[] { "wl.signin", "wl.basic", "wl.offline_access", "wl.skydrive", "wl.skydrive_update" }; LiveAuthClient authClient = new LiveAuthClient("your client id"); LiveLoginResult _login = await authClient.InitializeAsync(_scopes); #region 如果要强制用户为登陆状态则使用以下代码 //if (_login.Status != LiveConnectSessionStatus.Connected) //{ // _login = await authClient.LoginAsync(_scopes); //} //App.CurrentLiveConnectClient = new LiveConnectClient(_login.Session); #endregion if(_login.Status == LiveConnectSessionStatus.Connected) { //如果为登陆状态 则设置LiveConnectClient供以后调用 否则就等到需要用户登录的时候再提示登陆 App.CurrentLiveConnectClient = new LiveConnectClient(_login.Session); } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); }
然后在需要用户登录操作的地方,放上一个登陆按钮,设置SessionChanged事件
private async void btnSignin_SessionChanged(object sender, LiveConnectSessionChangedEventArgs e) { if (e.Status == LiveConnectSessionStatus.Connected) { if (App.CurrentLiveConnectClient == null) { App.CurrentLiveConnectClient = new LiveConnectClient(e.Session); } LiveOperationResult operationResult = await App.CurrentLiveConnectClient.GetAsync("me"); try { dynamic meResult = operationResult.Result; if (meResult.first_name != null && meResult.last_name != null) { infoTextBlock.Text = "Hello " + meResult.first_name + " " + meResult.last_name + "!"; } else { infoTextBlock.Text = "Hello, signed-in user!"; } } catch (LiveConnectException exception) { this.infoTextBlock.Text = "Error calling API: " + exception.Message; } } else { infoTextBlock.Text = "Not signed in."; } }
我这里保存的是LiveConnectClient,貌似直接保存用户信息更方便一些,随便了。等写完这个文章再改。
还可以在VM里设置评论框和登陆区域的显示方式,比如绑定到某个属性上,如果登陆了则显示评论框,没登陆显示登陆按钮。