Windows phone 8 和 Unity 5 支持 Facebook SDK
Windows phone 8 and Unity 5 support for Facebook SDK
这是对 Facebook SDK 支持 WP8 和 Unity 5 的请求。
我是一名开发人员,想要制作跨多个平台的游戏,并且能够将游戏发布到 Windows Phone 8 商店是我议程的重要组成部分。
是否计划很快发布对该平台的支持?如果是这样,您打算什么时候发布它?
此外,是否即将发布专为 Unity 5 设计的 Unity SDK?我已经设法让当前版本正常工作,但由于它尚未得到完全支持,我不知道什么可以,什么不能。
如能提供有关这些问题的任何信息,我们将不胜感激!
更新:我运行进入了这个解释"AndContinue"方法如何在windows 10中消失的视频,所以我们可以使用一种方法; windows 8/8.1 api 上已经存在的异步方法。在 https://youtu.be/aFVAP3fNJVo?t=23m34s
查看
我和你在同一个地方,但设法让它工作了。有时间我可能会把我的经历写成博客。
下面是直接调用WebAuthenticationBroker的部分主要代码:-
static bool isTryingToRegister { get; set; }
private static string _FbToken;
public static string response;
static bool isLoggedIn { get; set; }
static private string AppID { get { return "000000000000000000"; } }
static private Uri callback { get; set; }
static private string permissions { get { return "public_profile, user_friends, email, publish_actions, user_photos"; } }
public static System.Action<object> AuthSuccessCallback;
public static System.Action<object> AuthFailedCallback;
public static string fbToken
{
get
{
return _FbToken;
}
}
static Uri loginUrl
{
get
{
return new Uri(String.Format("https://www.facebook.com/v2.0/dialog/oauth/?client_id={0}&display=popup&response_type=token&redirect_uri={1}&scope={2}",
AppID,
callback,
permissions));
}
}
public static IEnumerator _Run_ConnectWithFacebook()
{
yield return new WaitForEndOfFrame();
#if UNITY_EDITOR
UnityDebugAuthentication();
#endif
#if NETFX_CORE
WindowsStoreAuthenticate();
#endif
}
#if NETFX_CORE
static void WindowsStoreAuthenticate()
{
#if UNITY_WP_8_1 && !UNITY_EDITOR
AuthSuccessCallback = _Run_ConnectWithFacebook_SuccessResponse;
AuthFailedCallback = _Run_ConnectWithFacebook_FailedResponse;
UnityEngine.WSA.Application.InvokeOnUIThread(
() =>
{
callback = WebAuthenticationBroker.GetCurrentApplicationCallbackUri();
WebAuthenticationBroker.AuthenticateAndContinue(loginUrl, callback, null, WebAuthenticationOptions.None);
}, true);
#endif
#if UNITY_METRO_8_1 && !UNITY_EDITOR
AuthSuccessCallback = _Run_ConnectWithFacebook_SuccessResponse;
AuthFailedCallback = _Run_ConnectWithFacebook_FailedResponse;
UnityEngine.WSA.Application.InvokeOnUIThread(
async () =>
{
callback = WebAuthenticationBroker.GetCurrentApplicationCallbackUri();
WebAuthenticationResult authResult = await WebAuthenticationBroker.AuthenticateAsync(WebAuthenticationOptions.None, loginUrl);
}, true);
#endif
}
#endif
请注意我如何将 WebAuthenticationBroker.AuthenticateAndContinue 用于 windows phone 和 WebAuthenticationBroker.AuthenticateAsync 用于 windows 8. 这对于它们各自的平台是必需的。您可能想要研究获取 WebAuthenticationBroker,它是一个适用于 WP8 和 WSA 的 Microsoft class(我猜您的目标是 WSA,我也是):-
您还需要统一构建一个 c# 项目,以便您可以实施其中的第 2 部分,其中包括在将令牌详细信息返回到应用程序时进行处理。这是我的 App.xaml.cs 代码示例,其灵感来自 https://msdn.microsoft.com/en-us/library/dn631755.aspx:-
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Core;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using UnityPlayer;
using Template.Common;
using Windows.Security.Authentication.Web;
// The Blank Application template is documented at http://go.microsoft.com/fwlink/?LinkId=234227
namespace Template
{
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
sealed partial class App : Application
{
private WinRTBridge.WinRTBridge _bridge;
private AppCallbacks appCallbacks;
#if UNITY_WP_8_1
public ContinuationManager continuationManager { get; private set; }
#endif
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App()
{
this.InitializeComponent();
appCallbacks = new AppCallbacks();
appCallbacks.RenderingStarted += RemoveSplashScreen;
#if UNITY_WP_8_1
this.Suspending += OnSuspending;
continuationManager = new ContinuationManager();
#endif
}
/// <summary>
/// Invoked when application is launched through protocol.
/// Read more - http://msdn.microsoft.com/library/windows/apps/br224742
/// </summary>
/// <param name="args"></param>
protected override void OnActivated(IActivatedEventArgs args)
{
#if UNITY_WP_8_1
var continuationEventArgs = args as IContinuationActivatedEventArgs;
if (continuationEventArgs != null)
{
ContinueWebAuthentication(args as WebAuthenticationBrokerContinuationEventArgs);
return;
//}
}
#endif
string appArgs = "";
Windows.ApplicationModel.Activation.SplashScreen splashScreen = null;
switch (args.Kind)
{
case ActivationKind.Protocol:
ProtocolActivatedEventArgs eventArgs = args as ProtocolActivatedEventArgs;
splashScreen = eventArgs.SplashScreen;
appArgs += string.Format("Uri={0}", eventArgs.Uri.AbsoluteUri);
break;
}
InitializeUnity(appArgs, splashScreen);
}
#if UNITY_WP_8_1
public void ContinueWebAuthentication(WebAuthenticationBrokerContinuationEventArgs args)
{
WebAuthenticationResult result = args.WebAuthenticationResult;
if (result.ResponseStatus == WebAuthenticationStatus.Success)
{
string responseData = result.ResponseData.Substring(result.ResponseData.IndexOf("access_token"));
String[] keyValPairs = responseData.Split('&');
string access_token = null;
string expires_in = null;
for (int i = 0; i < keyValPairs.Length; i++)
{
String[] splits = keyValPairs[i].Split('=');
switch (splits[0])
{
case "access_token":
access_token = splits[1]; //you may want to store access_token for further use. Look at Scenario5 (Account Management).
break;
case "expires_in":
expires_in = splits[1];
break;
}
}
AppCallbacks.Instance.UnityActivate(Window.Current.CoreWindow, CoreWindowActivationState.CodeActivated);
AppCallbacks.Instance.InvokeOnAppThread(() =>
{
// back to Unity
//function to call or variable that accepts the access token
}, false);
//OutputToken(result.ResponseData.ToString());
//await GetFacebookUserNameAsync(result.ResponseData.ToString());
}
else if (result.ResponseStatus == WebAuthenticationStatus.ErrorHttp)
{
//OutputToken("HTTP Error returned by AuthenticateAsync() : " + result.ResponseErrorDetail.ToString());
AppCallbacks.Instance.InvokeOnAppThread(() =>
{
// back to Unity
//function to call indicating something went wrong
}, false);
}
else if(result.ResponseStatus == WebAuthenticationStatus.UserCancel)
{
//OutputToken("Error returned by AuthenticateAsync() : " + result.ResponseStatus.ToString());
AppCallbacks.Instance.InvokeOnAppThread(() =>
{
// back to Unity
//function to call indicating something went wrong
}, false);
}
}
#endif
/// <summary>
/// Invoked when application is launched via file
/// Read more - http://msdn.microsoft.com/library/windows/apps/br224742
/// </summary>
/// <param name="args"></param>
protected override void OnFileActivated(FileActivatedEventArgs args)
{
string appArgs = "";
Windows.ApplicationModel.Activation.SplashScreen splashScreen = null;
splashScreen = args.SplashScreen;
appArgs += "File=";
bool firstFileAdded = false;
foreach (var file in args.Files)
{
if (firstFileAdded) appArgs += ";";
appArgs += file.Path;
firstFileAdded = true;
}
InitializeUnity(appArgs, splashScreen);
}
/// <summary>
/// Invoked when the application is launched normally by the end user. Other entry points
/// will be used when the application is launched to open a specific file, to display
/// search results, and so forth.
/// </summary>
/// <param name="args">Details about the launch request and process.</param>
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
InitializeUnity(args.Arguments, args.SplashScreen);
}
private void InitializeUnity(string args, Windows.ApplicationModel.Activation.SplashScreen splashScreen)
{
#if UNITY_WP_8_1
ApplicationView.GetForCurrentView().SuppressSystemOverlays = true;
#pragma warning disable 4014
StatusBar.GetForCurrentView().HideAsync();
#pragma warning restore 4014
#endif
appCallbacks.SetAppArguments(args);
Frame rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null && !appCallbacks.IsInitialized())
{
var mainPage = new MainPage(splashScreen);
Window.Current.Content = mainPage;
Window.Current.Activate();
// Setup scripting bridge
_bridge = new WinRTBridge.WinRTBridge();
appCallbacks.SetBridge(_bridge);
#if !UNITY_WP_8_1
appCallbacks.SetKeyboardTriggerControl(mainPage);
#endif
appCallbacks.SetSwapChainPanel(mainPage.GetSwapChainPanel());
appCallbacks.SetCoreWindowEvents(Window.Current.CoreWindow);
appCallbacks.InitializeD3DXAML();
}
Window.Current.Activate();
#if UNITY_WP_8_1
SetupLocationService();
#endif
}
private void RemoveSplashScreen()
{
// This will fail if you change main window class
// Make sure to adjust accordingly if you do something like this
MainPage page = (MainPage)Window.Current.Content;
page.RemoveSplashScreen();
}
#if UNITY_WP_8_1
// This is the default setup to show location consent message box to the user
// You can customize it to your needs, but do not remove it completely if your application
// uses location services, as it is a requirement in Windows Store certification process
private async void SetupLocationService()
{
if (!appCallbacks.IsLocationCapabilitySet())
{
return;
}
const string settingName = "LocationContent";
bool userGaveConsent = false;
object consent;
var settings = Windows.Storage.ApplicationData.Current.LocalSettings;
var userWasAskedBefore = settings.Values.TryGetValue(settingName, out consent);
if (!userWasAskedBefore)
{
var messageDialog = new Windows.UI.Popups.MessageDialog("Can this application use your location?", "Location services");
var acceptCommand = new Windows.UI.Popups.UICommand("Yes");
var declineCommand = new Windows.UI.Popups.UICommand("No");
messageDialog.Commands.Add(acceptCommand);
messageDialog.Commands.Add(declineCommand);
userGaveConsent = (await messageDialog.ShowAsync()) == acceptCommand;
settings.Values.Add(settingName, userGaveConsent);
}
else
{
userGaveConsent = (bool)consent;
}
if (userGaveConsent)
{ // Must be called from UI thread
appCallbacks.SetupGeolocator();
}
}
#endif
/// <summary>
/// Invoked when Navigation to a certain page fails
/// </summary>
/// <param name="sender">The Frame which failed navigation</param>
/// <param name="e">Details about the navigation failure</param>
void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
{
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
}
/// <summary>
/// Invoked when application execution is being suspended. Application state is saved
/// without knowing whether the application will be terminated or resumed with the contents
/// of memory still intact.
/// </summary>
/// <param name="sender">The source of the suspend request.</param>
/// <param name="e">Details about the suspend request.</param>
private async void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
await SuspensionManager.SaveAsync();
deferral.Complete();
}
}
}
您还需要 ContinuationManager.cs class 和 SuspensionManager.cs class 但主要用于 WP8.1 Universal。这对于 W8.1 是不需要的,因此您应该确保您使用#defines 将它们保持在它们自己的上下文中
如果您愿意,可以直接调用 facebook 应用程序而不是调用 WebAuthenticationBroker,但我不知道所有细节。您可以在 facebook 的网站 developers.facebook.com/docs/facebook-login/login-for-windows-phone 上阅读相关内容。如果用户没有安装该方法,则不推荐使用该方法。
长话短说,调用 WebAuthenticationBroker,处理 OnActivated 事件中的延续事件以捕获通过的 WebAuthenticationBrokerContinuationEventArgs 对象并使用您认为合适的数据。如果您想在统一端调用任何代码,请务必使用以下内容。请注意,您可以直接从 App.xaml.cs:-
访问 c# 代码
AppCallbacks.Instance.InvokeOnAppThread(() =>
{
// back to Unity
//your code here
}, false);
还要注意,这里主要是为了获取access token。一旦我们有了它,我们就可以直接向 facebook 进行基本的 WWW 调用并从中获取数据。数据将以 JSON 格式返回(ps 这是一种非常干净的格式!)您可以使用 .NET json 库将其序列化为 class .我使用 json2csharp.com 将任何示例输出转换为 class,我只是将其解析到 json 库中。
这是对 Facebook SDK 支持 WP8 和 Unity 5 的请求。 我是一名开发人员,想要制作跨多个平台的游戏,并且能够将游戏发布到 Windows Phone 8 商店是我议程的重要组成部分。
是否计划很快发布对该平台的支持?如果是这样,您打算什么时候发布它?
此外,是否即将发布专为 Unity 5 设计的 Unity SDK?我已经设法让当前版本正常工作,但由于它尚未得到完全支持,我不知道什么可以,什么不能。
如能提供有关这些问题的任何信息,我们将不胜感激!
更新:我运行进入了这个解释"AndContinue"方法如何在windows 10中消失的视频,所以我们可以使用一种方法; windows 8/8.1 api 上已经存在的异步方法。在 https://youtu.be/aFVAP3fNJVo?t=23m34s
查看我和你在同一个地方,但设法让它工作了。有时间我可能会把我的经历写成博客。
下面是直接调用WebAuthenticationBroker的部分主要代码:-
static bool isTryingToRegister { get; set; }
private static string _FbToken;
public static string response;
static bool isLoggedIn { get; set; }
static private string AppID { get { return "000000000000000000"; } }
static private Uri callback { get; set; }
static private string permissions { get { return "public_profile, user_friends, email, publish_actions, user_photos"; } }
public static System.Action<object> AuthSuccessCallback;
public static System.Action<object> AuthFailedCallback;
public static string fbToken
{
get
{
return _FbToken;
}
}
static Uri loginUrl
{
get
{
return new Uri(String.Format("https://www.facebook.com/v2.0/dialog/oauth/?client_id={0}&display=popup&response_type=token&redirect_uri={1}&scope={2}",
AppID,
callback,
permissions));
}
}
public static IEnumerator _Run_ConnectWithFacebook()
{
yield return new WaitForEndOfFrame();
#if UNITY_EDITOR
UnityDebugAuthentication();
#endif
#if NETFX_CORE
WindowsStoreAuthenticate();
#endif
}
#if NETFX_CORE
static void WindowsStoreAuthenticate()
{
#if UNITY_WP_8_1 && !UNITY_EDITOR
AuthSuccessCallback = _Run_ConnectWithFacebook_SuccessResponse;
AuthFailedCallback = _Run_ConnectWithFacebook_FailedResponse;
UnityEngine.WSA.Application.InvokeOnUIThread(
() =>
{
callback = WebAuthenticationBroker.GetCurrentApplicationCallbackUri();
WebAuthenticationBroker.AuthenticateAndContinue(loginUrl, callback, null, WebAuthenticationOptions.None);
}, true);
#endif
#if UNITY_METRO_8_1 && !UNITY_EDITOR
AuthSuccessCallback = _Run_ConnectWithFacebook_SuccessResponse;
AuthFailedCallback = _Run_ConnectWithFacebook_FailedResponse;
UnityEngine.WSA.Application.InvokeOnUIThread(
async () =>
{
callback = WebAuthenticationBroker.GetCurrentApplicationCallbackUri();
WebAuthenticationResult authResult = await WebAuthenticationBroker.AuthenticateAsync(WebAuthenticationOptions.None, loginUrl);
}, true);
#endif
}
#endif
请注意我如何将 WebAuthenticationBroker.AuthenticateAndContinue 用于 windows phone 和 WebAuthenticationBroker.AuthenticateAsync 用于 windows 8. 这对于它们各自的平台是必需的。您可能想要研究获取 WebAuthenticationBroker,它是一个适用于 WP8 和 WSA 的 Microsoft class(我猜您的目标是 WSA,我也是):-
您还需要统一构建一个 c# 项目,以便您可以实施其中的第 2 部分,其中包括在将令牌详细信息返回到应用程序时进行处理。这是我的 App.xaml.cs 代码示例,其灵感来自 https://msdn.microsoft.com/en-us/library/dn631755.aspx:-
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Core;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using UnityPlayer;
using Template.Common;
using Windows.Security.Authentication.Web;
// The Blank Application template is documented at http://go.microsoft.com/fwlink/?LinkId=234227
namespace Template
{
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
sealed partial class App : Application
{
private WinRTBridge.WinRTBridge _bridge;
private AppCallbacks appCallbacks;
#if UNITY_WP_8_1
public ContinuationManager continuationManager { get; private set; }
#endif
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App()
{
this.InitializeComponent();
appCallbacks = new AppCallbacks();
appCallbacks.RenderingStarted += RemoveSplashScreen;
#if UNITY_WP_8_1
this.Suspending += OnSuspending;
continuationManager = new ContinuationManager();
#endif
}
/// <summary>
/// Invoked when application is launched through protocol.
/// Read more - http://msdn.microsoft.com/library/windows/apps/br224742
/// </summary>
/// <param name="args"></param>
protected override void OnActivated(IActivatedEventArgs args)
{
#if UNITY_WP_8_1
var continuationEventArgs = args as IContinuationActivatedEventArgs;
if (continuationEventArgs != null)
{
ContinueWebAuthentication(args as WebAuthenticationBrokerContinuationEventArgs);
return;
//}
}
#endif
string appArgs = "";
Windows.ApplicationModel.Activation.SplashScreen splashScreen = null;
switch (args.Kind)
{
case ActivationKind.Protocol:
ProtocolActivatedEventArgs eventArgs = args as ProtocolActivatedEventArgs;
splashScreen = eventArgs.SplashScreen;
appArgs += string.Format("Uri={0}", eventArgs.Uri.AbsoluteUri);
break;
}
InitializeUnity(appArgs, splashScreen);
}
#if UNITY_WP_8_1
public void ContinueWebAuthentication(WebAuthenticationBrokerContinuationEventArgs args)
{
WebAuthenticationResult result = args.WebAuthenticationResult;
if (result.ResponseStatus == WebAuthenticationStatus.Success)
{
string responseData = result.ResponseData.Substring(result.ResponseData.IndexOf("access_token"));
String[] keyValPairs = responseData.Split('&');
string access_token = null;
string expires_in = null;
for (int i = 0; i < keyValPairs.Length; i++)
{
String[] splits = keyValPairs[i].Split('=');
switch (splits[0])
{
case "access_token":
access_token = splits[1]; //you may want to store access_token for further use. Look at Scenario5 (Account Management).
break;
case "expires_in":
expires_in = splits[1];
break;
}
}
AppCallbacks.Instance.UnityActivate(Window.Current.CoreWindow, CoreWindowActivationState.CodeActivated);
AppCallbacks.Instance.InvokeOnAppThread(() =>
{
// back to Unity
//function to call or variable that accepts the access token
}, false);
//OutputToken(result.ResponseData.ToString());
//await GetFacebookUserNameAsync(result.ResponseData.ToString());
}
else if (result.ResponseStatus == WebAuthenticationStatus.ErrorHttp)
{
//OutputToken("HTTP Error returned by AuthenticateAsync() : " + result.ResponseErrorDetail.ToString());
AppCallbacks.Instance.InvokeOnAppThread(() =>
{
// back to Unity
//function to call indicating something went wrong
}, false);
}
else if(result.ResponseStatus == WebAuthenticationStatus.UserCancel)
{
//OutputToken("Error returned by AuthenticateAsync() : " + result.ResponseStatus.ToString());
AppCallbacks.Instance.InvokeOnAppThread(() =>
{
// back to Unity
//function to call indicating something went wrong
}, false);
}
}
#endif
/// <summary>
/// Invoked when application is launched via file
/// Read more - http://msdn.microsoft.com/library/windows/apps/br224742
/// </summary>
/// <param name="args"></param>
protected override void OnFileActivated(FileActivatedEventArgs args)
{
string appArgs = "";
Windows.ApplicationModel.Activation.SplashScreen splashScreen = null;
splashScreen = args.SplashScreen;
appArgs += "File=";
bool firstFileAdded = false;
foreach (var file in args.Files)
{
if (firstFileAdded) appArgs += ";";
appArgs += file.Path;
firstFileAdded = true;
}
InitializeUnity(appArgs, splashScreen);
}
/// <summary>
/// Invoked when the application is launched normally by the end user. Other entry points
/// will be used when the application is launched to open a specific file, to display
/// search results, and so forth.
/// </summary>
/// <param name="args">Details about the launch request and process.</param>
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
InitializeUnity(args.Arguments, args.SplashScreen);
}
private void InitializeUnity(string args, Windows.ApplicationModel.Activation.SplashScreen splashScreen)
{
#if UNITY_WP_8_1
ApplicationView.GetForCurrentView().SuppressSystemOverlays = true;
#pragma warning disable 4014
StatusBar.GetForCurrentView().HideAsync();
#pragma warning restore 4014
#endif
appCallbacks.SetAppArguments(args);
Frame rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null && !appCallbacks.IsInitialized())
{
var mainPage = new MainPage(splashScreen);
Window.Current.Content = mainPage;
Window.Current.Activate();
// Setup scripting bridge
_bridge = new WinRTBridge.WinRTBridge();
appCallbacks.SetBridge(_bridge);
#if !UNITY_WP_8_1
appCallbacks.SetKeyboardTriggerControl(mainPage);
#endif
appCallbacks.SetSwapChainPanel(mainPage.GetSwapChainPanel());
appCallbacks.SetCoreWindowEvents(Window.Current.CoreWindow);
appCallbacks.InitializeD3DXAML();
}
Window.Current.Activate();
#if UNITY_WP_8_1
SetupLocationService();
#endif
}
private void RemoveSplashScreen()
{
// This will fail if you change main window class
// Make sure to adjust accordingly if you do something like this
MainPage page = (MainPage)Window.Current.Content;
page.RemoveSplashScreen();
}
#if UNITY_WP_8_1
// This is the default setup to show location consent message box to the user
// You can customize it to your needs, but do not remove it completely if your application
// uses location services, as it is a requirement in Windows Store certification process
private async void SetupLocationService()
{
if (!appCallbacks.IsLocationCapabilitySet())
{
return;
}
const string settingName = "LocationContent";
bool userGaveConsent = false;
object consent;
var settings = Windows.Storage.ApplicationData.Current.LocalSettings;
var userWasAskedBefore = settings.Values.TryGetValue(settingName, out consent);
if (!userWasAskedBefore)
{
var messageDialog = new Windows.UI.Popups.MessageDialog("Can this application use your location?", "Location services");
var acceptCommand = new Windows.UI.Popups.UICommand("Yes");
var declineCommand = new Windows.UI.Popups.UICommand("No");
messageDialog.Commands.Add(acceptCommand);
messageDialog.Commands.Add(declineCommand);
userGaveConsent = (await messageDialog.ShowAsync()) == acceptCommand;
settings.Values.Add(settingName, userGaveConsent);
}
else
{
userGaveConsent = (bool)consent;
}
if (userGaveConsent)
{ // Must be called from UI thread
appCallbacks.SetupGeolocator();
}
}
#endif
/// <summary>
/// Invoked when Navigation to a certain page fails
/// </summary>
/// <param name="sender">The Frame which failed navigation</param>
/// <param name="e">Details about the navigation failure</param>
void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
{
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
}
/// <summary>
/// Invoked when application execution is being suspended. Application state is saved
/// without knowing whether the application will be terminated or resumed with the contents
/// of memory still intact.
/// </summary>
/// <param name="sender">The source of the suspend request.</param>
/// <param name="e">Details about the suspend request.</param>
private async void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
await SuspensionManager.SaveAsync();
deferral.Complete();
}
}
}
您还需要 ContinuationManager.cs class 和 SuspensionManager.cs class 但主要用于 WP8.1 Universal。这对于 W8.1 是不需要的,因此您应该确保您使用#defines 将它们保持在它们自己的上下文中
如果您愿意,可以直接调用 facebook 应用程序而不是调用 WebAuthenticationBroker,但我不知道所有细节。您可以在 facebook 的网站 developers.facebook.com/docs/facebook-login/login-for-windows-phone 上阅读相关内容。如果用户没有安装该方法,则不推荐使用该方法。
长话短说,调用 WebAuthenticationBroker,处理 OnActivated 事件中的延续事件以捕获通过的 WebAuthenticationBrokerContinuationEventArgs 对象并使用您认为合适的数据。如果您想在统一端调用任何代码,请务必使用以下内容。请注意,您可以直接从 App.xaml.cs:-
访问 c# 代码AppCallbacks.Instance.InvokeOnAppThread(() =>
{
// back to Unity
//your code here
}, false);
还要注意,这里主要是为了获取access token。一旦我们有了它,我们就可以直接向 facebook 进行基本的 WWW 调用并从中获取数据。数据将以 JSON 格式返回(ps 这是一种非常干净的格式!)您可以使用 .NET json 库将其序列化为 class .我使用 json2csharp.com 将任何示例输出转换为 class,我只是将其解析到 json 库中。