今天给大家介绍下 windows phone 8 的近场通信技术,常用近场通信技术有几种 NFC、蓝牙(Bluetooth)、Wifi 以上三种都是在WP8的API中所支持的,NFC我个人感觉是一个可以让人耳目一新的功能。而且NFC设备目前被很多手机厂商应用,目前NFC技术在手机上应用主要有以下五类。
可能有人会问到关于NFC的安全问题,以及传输速度问题,这里我也给大家列出NFC的特性来帮助大家了解NFC。
如何在我们的应用中使用NFC呢?下来我逐一给大家介绍。
首先 还是设置我们的 WMAppManifest.xml 文件标记我们应用需要是有近场通信技术
这里我还选择了NetWoking 是因为后面我还会使用 Bluetooth 和 TCP/IP (Wi-Fi)连接。
建立NFC的连接我们要用到 Windows.Networking.Proximity.ProximityDevice 我们可以使用 Windows.Networking.Proximity.ProximityDevice.GetDefault(); 来判断手机硬件是否支持NFC。
private void InitializeProximityDevice() { if (mProximityDevice == null) { mProximityDevice = Windows.Networking.Proximity.ProximityDevice.GetDefault(); } if (mProximityDevice != null) { mProximityDevice.DeviceArrived += ProximityDeviceArrived; mProximityDevice.DeviceDeparted += ProximityDeviceDeparted; AddToSysMsgList(MSG_NFC_EXISTS); } else { AddToSysMsgList(MSG_NFC_NOT_EXISTS); } }
上面的代码还看到了连个事件 DeviceArrived 和 DeviceDeparted 分别用于判断一个NFC设备进入和离开我们设备的感应区域。
下面我列举一个发送消息的code
ProximityDevice device = ProximityDevice.GetDefault(); // Make sure NFC is supported if (device!= null) { long Id = device.PublishMessage("Windows.SampleMessageType", "Hello World!"); Debug.WriteLine("Published Message. ID is {0}", Id); // Store the unique message Id so that it // can be used to stop publishing this message }
注册接收消息的code
Windows.Networking.Proximity.ProximityDevice proximityDevice; private void InitializeProximityDevice() { proximityDevice = Windows.Networking.Proximity.ProximityDevice.GetDefault(); if (proximityDevice != null) { proximityDevice.DeviceArrived += ProximityDeviceArrived; proximityDevice.DeviceDeparted += ProximityDeviceDeparted; WriteMessageText("Proximity device initialized.\n"); } else { WriteMessageText("Failed to initialized proximity device.\n"); } } private void ProximityDeviceArrived(Windows.Networking.Proximity.ProximityDevice device) { WriteMessageText("Proximate device arrived. id = " + device.DeviceId + "\n"); } private void ProximityDeviceDeparted(Windows.Networking.Proximity.ProximityDevice device) { WriteMessageText("Proximate device departed. id = " + device.DeviceId + "\n"); } // Write a message to MessageBlock on the UI thread. private Windows.UI.Core.CoreDispatcher messageDispatcher = Window.Current.CoreWindow.Dispatcher; async private void WriteMessageText(string message, bool overwrite = false) { await messageDispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { if (overwrite) MessageBlock.Text = message; else MessageBlock.Text += message; }); }
这里WP8除了支持信息的传输还支持更多的文件类型
Windows.Networking.Proximity.ProximityDevice proximityDevice; private void PublishLaunchApp() { proximityDevice = Windows.Networking.Proximity.ProximityDevice.GetDefault(); if (proximityDevice != null) { // The format of the app launch string is: "<args>\tWindows\t<AppName>". // The string is tab or null delimited. // The <args> string can be an empty string (""). string launchArgs = "user=default"; // The format of the AppName is: PackageFamilyName!PRAID. string praid = "MyAppId"; // The Application Id value from your package.appxmanifest. string appName = Windows.ApplicationModel.Package.Current.Id.FamilyName + "!" + praid; string launchAppMessage = launchArgs + "\tWindows\t" + appName; var dataWriter = new Windows.Storage.Streams.DataWriter(); dataWriter.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf16LE; dataWriter.WriteString(launchAppMessage); var launchAppPubId = proximityDevice.PublishBinaryMessage( "LaunchApp:WriteTag", dataWriter.DetachBuffer()); } }
详细请参考 如果你使用Nokia的NDEF 请参考
其中包含了 配对请求,Tag信息的写入,以及设备间交互。
其中交互功能可以使用连接deeplink的形式打开应用传入参数或者打开应用或者应用商店。参考我之前的帖子:windows phone 8 中的应用间通信
由于NFC技术仅限近距离通信,如果传输大文件或者长时间连接的一种场景,bluetooth和wifi无疑是更好的一种连接方式,下面我给大家继续介绍下windows phone 8 的蓝牙传输。
临近感应和 NFC 使您能够通过点击或将两个设备放在几毫米的距离内来连接它们。该方案适用于 Windows Phone 8 和 Windows 8 设备。点击成功时,您会获得一个套接字,通过它即可与另一个设备通信。在 Windows Phone 8 上,在 TCP/IP (Wi-Fi) 连接或蓝牙连接时建立该套接字。临近感应 API 根据PeerFinder.AllowBluetooth 和 PeerFinder.AllowInfrastructure 的属性值(默认为 true)确定建立何种连接。当希望进行连接的设备已启用蓝牙时,可获得最一致的用户体验(就能够随处点击和连接而言)。如果两个设备处于相同的基础结构网络(相同的网络或路由器、无 IP 冲突、无防火墙、设备之间可执行 ping 操作),则有可能建立 Wi-Fi 连接。因此,建议应用在进行点击尝试之前通知用户,以确保两个设备都已启用蓝牙。
以上这段话摘自MSDN 可能看上去说的比较蹩脚,简单来说在连建立连接的时候呢如果两台设备在同一个局域网中并且没有网络限制的情况下,连接会优先选择TCP/IP (Wi-Fi) 其次会进行蓝牙连接。
等待查找(连接)的代码
ProximityDevice device = ProximityDevice.GetDefault(); // Make sure NFC is supported if (device!= null) { PeerFinder.TriggeredConnectionStateChanged += OnTriggeredConnectionStateChanged; // Start finding peer apps, while making this app discoverable by peers PeerFinder.Start(); }
连接状态处理
StreamSocket _streamSocket; void OnTriggeredConnectionStateChanged(object sender, TriggeredConnectionStateChangedEventArgs args) { switch (args.State) { case TriggeredConnectState.Listening: // Connecting as host break; case TriggeredConnectState.PeerFound: // Proximity gesture is complete and user can pull their devices away. Remaining work is to // establish the connection using a different transport, like TCP/IP or Bluetooth break; case TriggeredConnectState.Connecting: // Connecting as a client break; case TriggeredConnectState.Completed: // Connection completed, retrieve the socket over which to communicate _streamSocket = args.Socket; break; case TriggeredConnectState.Canceled: break; case TriggeredConnectState.Failed: // Connection was unsuccessful break; } }
蓝牙主动连接设备/应用
TO APP
async void AppToApp() { // PeerFinder.Start() is used to advertise our presence so that peers can find us. // It must always be called before FindAllPeersAsync. PeerFinder.Start(); var peers = await PeerFinder.FindAllPeersAsync(); if (peers.Count == 0) { Debug.WriteLine("Peer not found."); } else { // Select a peer. In this example, let's just pick the first peer. PeerInformation selectedPeer = peers[0]; // Attempt a connection var streamSocket = await PeerFinder.ConnectAsync(selectedPeer); DoSomethingUseful(streamSocket); } }
To device
// Note: You can only browse and connect to paired devices! private async void AppToDevice() { // Configure PeerFinder to search for all paired devices. PeerFinder.AlternateIdentities["Bluetooth:Paired"] = ""; var pairedDevices = await PeerFinder.FindAllPeersAsync(); if (pairedDevices.Count == 0) { Debug.WriteLine("No paired devices were found."); } else { // Select a paired device. In this example, just pick the first one. PeerInformation selectedDevice = pairedDevices[0]; // Attempt a connection StreamSocket socket = new StreamSocket(); // Make sure ID_CAP_NETWORKING is enabled in your WMAppManifest.xml, or the next // line will throw an Access Denied exception. await socket.ConnectAsync(selectedDevice.HostName, selectedDevice.ServiceName); DoSomethingUseful(socket); } }
监听连接请求
// Page Constructor public MainPage() { InitializeComponent(); Loaded += MainPage_Loaded; } void MainPage_Loaded(object sender, RoutedEventArgs e) { PeerFinder.ConnectionRequested += PeerFinder_ConnectionRequested; } void PeerFinder_ConnectionRequested(object sender, ConnectionRequestedEventArgs args) { if (ShouldConnect()) { // Go ahead and connect ConnectToPeer(args.PeerInformation); } } async void ConnectToPeer(PeerInformation peer) { StreamSocket socket = await PeerFinder.ConnectAsync(peer); DoSomethingUseful(socket); } private bool ShouldConnect() { // Determine whether to accept this connection request and return return true; }
检查设备的蓝牙是否处于打开状态
private async void FindPaired() { // Search for all paired devices PeerFinder.AlternateIdentities["Bluetooth:Paired"] = ""; try { var peers = await PeerFinder.FindAllPeersAsync(); // Handle the result of the FindAllPeersAsync call } catch (Exception ex) { if ((uint)ex.HResult == 0x8007048F) { MessageBox.Show("Bluetooth is turned off"); } } }
这里看到连接后得到的都是一个StreamSocket 对象所以后面的工作就是将你的数据Stream在传输就好了,我就不做过多篇幅介绍Stream的使用了。
此文是 升级到WP8必需知道的13个特性 系列的一个更新 希望这个系列可以给 Windows Phone 8开发者带来一些开发上的便利。
同时欢迎大家在这里和我沟通交流或者在新浪微博上 @王博_Nick