環境: Windows 10 IoT Core Build 14376 (10.0.14376.0), VS2015
Raspberry Pi3 有內建的 Bluetooth ,但之前使用的 IoT Core 卻還不 Support。
要用 Bluetooth 還要再外接 Bluetooth ,但 Build 14376 已支援了哦!
以下筆者建立一個 iBeacon 的 headless App 來演示一下,
下載及安裝請參考「Windows 10 IoT Core 的 remote debugging PIN」。
預設 Bluetooth 是沒有啟用的,所以要在 裝置設定=>藍牙 那裡啟用它,如下,
再來程式就可以透過 BluetoothLEAdvertisementPublisher 來模擬 iBeacon ,
1.設定 藍牙 權限,在 Package.appxmanifest 的 Capabilities 中,要勾選 Bluetooth,如下,
2.新增一個存放 beacon 資料的json檔(beaconData.json)(因為可能要部到不同的Pi上面,所以可以上傳設定檔)
{
"manufacturerId": "0215",
"uuid": "e4c8a4fc-f68b-470d-959f-29382af72ce7",
"major": "000C",
"minor": "0003",
"txPower": "c5"
}
3.設定 beaconData.json 的屬性,在檔案屬性視窗中,Build Action請用Content,如下,
4.在 StartupTask.cs 中加入啟動 iBeacon 的模擬,會先檢查 ApplicationData.Current.LocalFolder ,不存再檔案時,再檢查 Windows.ApplicationModel.Package.Current.InstalledLocation 目錄,如下,
namespace iBeacon
{
public sealed class StartupTask : IBackgroundTask
{
public async void Run(IBackgroundTaskInstance taskInstance)
{
// Create the deferral by requesting it from the task instance.
BackgroundTaskDeferral deferral = taskInstance.GetDeferral();
try
{
//先讀取 beaconData 設定的 Beacon 資訊
var beaconData = await GetBeaconData();
// 開始廣播 iBeacon 的廣告訊息
PublishiBeacon(beaconData);
}catch(Exception ex)
{
Debug.WriteLine(ex.ToString());
}
// Once the asynchronous method(s) are done, close the deferral.
// 不要 Call Complete 就不會停止
//deferral.Complete();
}
/// <summary>
/// 取得 beacon 的資訊
/// </summary>
/// <returns></returns>
private async Task<byte[]> GetBeaconData()
{
string fileContent = await ReadBeaconDataFromFile();
dynamic beacon = JsonConvert.DeserializeObject(fileContent);
StringBuilder beaconData = new StringBuilder();
beaconData.Append((string)beacon.manufacturerId);
beaconData.Append(((string)beacon.uuid).Replace("-",string.Empty));
beaconData.Append((string)beacon.major);
beaconData.Append((string)beacon.minor);
beaconData.Append((string)beacon.txPower);
string beaconDataStr = beaconData.ToString();
var result = Enumerable.Range(0, beaconDataStr.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(beaconDataStr.Substring(x, 2), 16))
.ToArray();
return result;
}
/// <summary>
/// 讀取 beaconData.json 的內容
/// </summary>
/// <returns></returns>
private async Task<string> ReadBeaconDataFromFile()
{
var fileName = @"beaconData.json";
StorageFolder folder;
StorageFile file;
try
{
//先在 LocalFolder 裡找
folder = ApplicationData.Current.LocalFolder;
file = await folder.GetFileAsync(fileName);
}
catch (Exception ex)
{
//找不到檔案,所以取預設的地方
folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
file = await folder.GetFileAsync(fileName);
Debug.WriteLine(ex.ToString());
}
var fileContent = await FileIO.ReadTextAsync(file);
return fileContent;
}
BluetoothLEAdvertisementPublisher _blePublisher;
private void PublishiBeacon(byte[] dataArray)
{
var manufactureData = new BluetoothLEManufacturerData();
//0x004C Apple, Inc.
manufactureData.CompanyId = 0x004c;
//using System.Runtime.InteropServices.WindowsRuntime;
manufactureData.Data = dataArray.AsBuffer();
_blePublisher = new BluetoothLEAdvertisementPublisher();
_blePublisher.Advertisement.ManufacturerData.Add(manufactureData);
//開始發佈
_blePublisher.Start();
}
}
}
再來就是將程式部到 RPi3 上執行, App執行起來可以用 Android 的手機來掃到模擬出來的Beacon,
而資料就是我們預設的 beaconData.json 的內容,如下,
再來我們先將App停掉,然後修改 beaconData.json 內容如下,
{
"manufacturerId": "0215",
"uuid": "e4c8a4fc-f68b-470d-959f-29382af72ce7",
"major": "000D",
"minor": "0004",
"txPower": "c5"
}
然後透過 App File Explorer 上傳到 App 的 LocalState 目錄之中,如下,
再啟動 App,再掃一次就會發現,它會使用新的 beacon 設定(Major:13, Minor:4),如下,
完整程式在 rainmakerho/iBeaconHeadless
註:目前 Build 14393 也出來了哦! 修正一些問題,所以可以直接下載 Build 14393 哦!
參考資料
Windows 10 IoT Core 的 remote debugging PIN
Windows 10 IoT Core Command Line Utils
Release Notes for Windows 10 IoT Core
Hi,
亂馬客Blog已移到了 「亂馬客 : Re:從零開始的軟體開發生活」
請大家繼續支持 ^_^