Skip to content

Commit c5e1e14

Browse files
authored
feat(BluetoothDevice): add GetCurrentTime method (#4501)
* doc: 更新示例 * feat: 增加 BluetoothDeviceInfo 类 * doc: 更新示例 * feat: 增加蓝牙服务扩展方法 * feat: 增加 SoftwareRevision 参数 * feat: 增加 GetAllServices 扩展方法 * doc: 更新示例 * chore: 增加命名空间配置 * test: 增加测试代码 * feat: 增加 CurrentTime 解析方法 * feat: 增加 GetCurrentTime 方法 * doc: 更新示例 * feat: 支持时区 * doc: 更新注释 * doc: 更新示例 * test: 增加单元测试 * test: 增加单元测试 * doc: 更新示例 * test: 更新单元测试
1 parent 3f3f8b9 commit c5e1e14

File tree

15 files changed

+763
-5
lines changed

15 files changed

+763
-5
lines changed

.editorconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public
217217
[*.cs]
218218
# Add file header
219219
file_header_template = Licensed to the .NET Foundation under one or more agreements.\nThe .NET Foundation licenses this file to you under the Apache 2.0 License\nSee the LICENSE file in the project root for more information.\nMaintainer: Argo Zhang([email protected]) Website: https://www.blazor.zone
220-
csharp_style_namespace_declarations = block_scoped:silent
220+
csharp_style_namespace_declarations = file_scoped:silent
221221
csharp_style_expression_bodied_local_functions = false:silent
222222
csharp_using_directive_placement = outside_namespace:silent
223223
csharp_prefer_simple_using_statement = true:suggestion

src/BootstrapBlazor.Server/Components/Samples/Bluetooth.razor

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ private IBluetoothService? BluetoothService { get; set; }</Pre>
2121
<DemoBlock Title="@Localizer["BaseUsageTitle"]"
2222
Introduction="@Localizer["BaseUsageIntro"]"
2323
Name="Normal">
24+
<section ignore>
25+
@Localizer["UsageDesc"]
26+
</section>
2427
<div class="row form-inline g-3">
2528
<div class="col-12">
2629
<Button Text="@Localizer["BluetoothRequestText"]" Icon="fa-brands fa-bluetooth" OnClick="RequestDevice"></Button>
@@ -36,6 +39,25 @@ private IBluetoothService? BluetoothService { get; set; }</Pre>
3639
<label class="d-flex align-items-center"><progress value="@_batteryValue" max="100" class="ms-3"></progress><span class="ms-3">@_batteryValueString</span></label>
3740
</div>
3841
</div>
42+
<div class="col-12">
43+
<div class="d-flex align-items-center">
44+
<Button Text="@Localizer["BluetoothGetCurrentTimeText"]" Icon="fa-solid fa-clock" IsDisabled="@(_blueDevice is not { Connected: true })" OnClick="GetTimeValue"></Button>
45+
<label class="ms-3">@_currentTimeValueString</label>
46+
</div>
47+
</div>
48+
<div class="col-12">
49+
<div class="d-flex align-items-center">
50+
<Button Text="@Localizer["BluetoothDeviceInfoText"]" Icon="fa-solid fa-microchip" IsDisabled="@(_blueDevice is not { Connected: true })" OnClick="GetDeviceInfoValue"></Button>
51+
</div>
52+
</div>
53+
<div class="col-12">
54+
<div>
55+
@foreach (var info in _deviceInfoList)
56+
{
57+
<div>@info</div>
58+
}
59+
</div>
60+
</div>
3961
</div>
4062
</DemoBlock>
4163

src/BootstrapBlazor.Server/Components/Samples/Bluetooth.razor.cs

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,20 @@ public partial class Bluetooth
2424

2525
private string? _batteryValueString = null;
2626

27+
private string? _currentTimeValueString = null;
28+
2729
private async Task RequestDevice()
2830
{
29-
_blueDevice = await BluetoothService.RequestDevice();
31+
_blueDevice = await BluetoothService.RequestDevice(new BluetoothRequestOptions()
32+
{
33+
Filters = [
34+
new BluetoothFilter()
35+
{
36+
NamePrefix = "Argo"
37+
}
38+
],
39+
OptionalServices = ["device_information"]
40+
});
3041
if (BluetoothService.IsSupport == false)
3142
{
3243
await ToastService.Error(Localizer["NotSupportBluetoothTitle"], Localizer["NotSupportBluetoothContent"]);
@@ -60,6 +71,11 @@ private async Task Disconnect()
6071
{
6172
await ToastService.Error("Disconnect", _blueDevice.ErrorMessage);
6273
}
74+
else
75+
{
76+
_batteryValue = null;
77+
_batteryValueString = null;
78+
}
6379
}
6480
}
6581

@@ -81,4 +97,36 @@ private async Task GetBatteryValue()
8197
_batteryValueString = $"{_batteryValue} %";
8298
}
8399
}
100+
101+
private async Task GetTimeValue()
102+
{
103+
_currentTimeValueString = null;
104+
105+
if(_blueDevice != null)
106+
{
107+
var val = await _blueDevice.GetCurrentTime();
108+
if (val.HasValue && !string.IsNullOrEmpty(_blueDevice.ErrorMessage))
109+
{
110+
await ToastService.Error("Current Time", _blueDevice.ErrorMessage);
111+
return;
112+
}
113+
_currentTimeValueString = val.ToString();
114+
}
115+
}
116+
117+
private readonly List<string> _deviceInfoList = [];
118+
119+
private async Task GetDeviceInfoValue()
120+
{
121+
_deviceInfoList.Clear();
122+
if (_blueDevice != null)
123+
{
124+
var info = await _blueDevice.GetDeviceInfo();
125+
_deviceInfoList.Add($"Manufacturer Name: {info?.ManufacturerName}");
126+
_deviceInfoList.Add($"Module Number: {info?.ModelNumber}");
127+
_deviceInfoList.Add($"Firmware Revision: {info?.FirmwareRevision}");
128+
_deviceInfoList.Add($"Hardware Revision: {info?.HardwareRevision}");
129+
_deviceInfoList.Add($"Software Revision: {info?.SoftwareRevision}");
130+
}
131+
}
84132
}

src/BootstrapBlazor.Server/Locales/en-US.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5901,7 +5901,10 @@
59015901
"BluetoothGetBatteryText": "Battery",
59025902
"BluetoothGetHeartRateText": "HeartRate",
59035903
"BaseUsageTitle": "Basic usage",
5904-
"BaseUsageIntro": "Request communication with Bluetooth devices through the <code>IBluetoothService</code> service"
5904+
"BaseUsageIntro": "Request communication with Bluetooth devices through the <code>IBluetoothService</code> service",
5905+
"BluetoothGetCurrentTimeText": "Time",
5906+
"BluetoothDeviceInfoText": "Device Info",
5907+
"UsageDesc": "Click the Scan button and select the phone to test in the pop-up window"
59055908
},
59065909
"BootstrapBlazor.Server.Components.Samples.FileIcons": {
59075910
"Title": "File Icon",

src/BootstrapBlazor.Server/Locales/zh-CN.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5901,7 +5901,10 @@
59015901
"BluetoothGetBatteryText": "读取电量",
59025902
"BluetoothGetHeartRateText": "读取心率",
59035903
"BaseUsageTitle": "基础用法",
5904-
"BaseUsageIntro": "通过 <code>IBluetoothService</code> 服务,请求与蓝牙设备通讯"
5904+
"BaseUsageIntro": "通过 <code>IBluetoothService</code> 服务,请求与蓝牙设备通讯",
5905+
"BluetoothGetCurrentTimeText": "读取时间",
5906+
"BluetoothDeviceInfoText": "读取硬件信息",
5907+
"UsageDesc": "点击扫描按钮,在弹窗中选中手机进行测试"
59055908
},
59065909
"BootstrapBlazor.Server.Components.Samples.FileIcons": {
59075910
"Title": "File Icon 文件图标",
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the Apache 2.0 License
3+
// See the LICENSE file in the project root for more information.
4+
// Maintainer: Argo Zhang([email protected]) Website: https://www.blazor.zone
5+
6+
using System.Reflection;
7+
using System.Text.Json.Serialization;
8+
9+
namespace BootstrapBlazor.Components;
10+
11+
/// <summary>
12+
/// Bluetooth 扩展方法
13+
/// </summary>
14+
public static class BluetoothExtensions
15+
{
16+
/// <summary>
17+
/// 获得指定蓝牙服务字符串集合
18+
/// </summary>
19+
/// <param name="services"></param>
20+
/// <returns></returns>
21+
public static List<string> GetServicesList(this IEnumerable<BluetoothServices> services) => services.Select(i =>
22+
{
23+
var v = i.ToString();
24+
var attributes = typeof(BluetoothServices).GetField(v)!.GetCustomAttribute<JsonPropertyNameAttribute>(false)!;
25+
return attributes.Name;
26+
}).ToList();
27+
}

src/BootstrapBlazor/Services/Bluetooth/BluetoothDevice.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
// See the LICENSE file in the project root for more information.
44
// Maintainer: Argo Zhang([email protected]) Website: https://www.blazor.zone
55

6+
using System.Globalization;
7+
68
namespace BootstrapBlazor.Components;
79

810
/// <summary>
@@ -97,6 +99,41 @@ public async Task<bool> Disconnect(CancellationToken token = default)
9799
return ret;
98100
}
99101

102+
/// <summary>
103+
/// <inheritdoc />
104+
/// </summary>
105+
/// <param name="token"></param>
106+
/// <returns></returns>
107+
public async Task<BluetoothDeviceInfo?> GetDeviceInfo(CancellationToken token = default)
108+
{
109+
BluetoothDeviceInfo? ret = null;
110+
if (Connected)
111+
{
112+
ErrorMessage = null;
113+
ret = await _module.InvokeAsync<BluetoothDeviceInfo?>("getDeviceInfo", token, _clientId, _interop, nameof(OnError));
114+
}
115+
return ret;
116+
}
117+
118+
/// <summary>
119+
/// <inheritdoc />
120+
/// </summary>
121+
/// <param name="token"></param>
122+
/// <returns></returns>
123+
public async Task<DateTimeOffset?> GetCurrentTime(CancellationToken token = default)
124+
{
125+
DateTimeOffset? ret = null;
126+
if (Connected)
127+
{
128+
ErrorMessage = null;
129+
var timeString = await _module.InvokeAsync<string?>("getCurrentTime", token, _clientId, _interop, nameof(OnError));
130+
if (DateTimeOffset.TryParseExact(timeString, "yyyy-MM-ddTHH:mm:sszzz", DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None, out var d))
131+
{
132+
ret = d;
133+
}
134+
}
135+
return ret;
136+
}
100137
/// <summary>
101138
/// JavaScript 报错回调方法
102139
/// </summary>
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// Copyright (c) Argo Zhang ([email protected]). All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
// Website: https://www.blazor.zone or https://argozhang.github.io/
4+
5+
namespace BootstrapBlazor.Components;
6+
7+
/// <summary>
8+
/// 蓝牙设备信息
9+
/// </summary>
10+
public class BluetoothDeviceInfo
11+
{
12+
/// <summary>
13+
/// 获得/设置 ManufacturerName
14+
/// </summary>
15+
public string? ManufacturerName { get; set; }
16+
17+
/// <summary>
18+
/// 获得/设置 ModelNumber
19+
/// </summary>
20+
public string? ModelNumber { get; set; }
21+
22+
/// <summary>
23+
/// 获得/设置 HardwareRevision
24+
/// </summary>
25+
public string? HardwareRevision { get; set; }
26+
27+
/// <summary>
28+
/// 获得/设置 FirmwareRevision
29+
/// </summary>
30+
public string? FirmwareRevision { get; set; }
31+
32+
/// <summary>
33+
/// 获得/设置 SoftwareRevision
34+
/// </summary>
35+
public string? SoftwareRevision { get; set; }
36+
37+
/// <summary>
38+
/// 获得/设置 SystemId
39+
/// </summary>
40+
public SystemId? SystemId { get; set; }
41+
42+
/// <summary>
43+
/// 获得/设置 IEEERegulatoryCertificationDataList
44+
/// </summary>
45+
public string? IEEERegulatoryCertificationDataList { get; set; }
46+
47+
/// <summary>
48+
/// 获得/设置 PnPID
49+
/// </summary>
50+
public PnPID? PnPID { get; set; }
51+
}
52+
53+
/// <summary>
54+
/// SystemId 类
55+
/// </summary>
56+
public class SystemId
57+
{
58+
/// <summary>
59+
/// 获得/设置 ManufacturerIdentifier
60+
/// </summary>
61+
public string? ManufacturerIdentifier { get; set; }
62+
63+
/// <summary>
64+
/// 获得/设置 OrganizationallyUniqueIdentifier
65+
/// </summary>
66+
public string? OrganizationallyUniqueIdentifier { get; set; }
67+
}
68+
69+
/// <summary>
70+
/// PnPID 类
71+
/// </summary>
72+
public class PnPID
73+
{
74+
/// <summary>
75+
/// 获得/设置 VendorIdSource
76+
/// </summary>
77+
public string? VendorIdSource { get; set; }
78+
79+
/// <summary>
80+
/// 获得/设置 ProductId
81+
/// </summary>
82+
public string? ProductId { get; set; }
83+
84+
/// <summary>
85+
/// 获得/设置 ProductVersion
86+
/// </summary>
87+
public string? ProductVersion { get; set; }
88+
}

src/BootstrapBlazor/Services/Bluetooth/BluetoothRequestOptions.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// See the LICENSE file in the project root for more information.
44
// Maintainer: Argo Zhang([email protected]) Website: https://www.blazor.zone
55

6+
using System.Reflection;
67
using System.Text.Json.Serialization;
78

89
namespace BootstrapBlazor.Components;
@@ -39,6 +40,18 @@ public class BluetoothRequestOptions
3940
/// <summary>
4041
/// A boolean value indicating that the requesting script can accept all Bluetooth devices. The default is false.
4142
/// </summary>
43+
/// <remarks>This option is appropriate when devices have not advertised enough information for filtering to be useful. When acceptAllDevices is set to true you should omit all filters and exclusionFilters, and you must set optionalServices to be able to use the returned device.</remarks>
4244
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
4345
public bool AcceptAllDevices { get; set; }
46+
47+
/// <summary>
48+
/// 获得所有蓝牙服务
49+
/// </summary>
50+
/// <returns></returns>
51+
public static List<string> GetAllServices() => Enum.GetNames(typeof(BluetoothServices)).Select(i =>
52+
{
53+
var v = i.ToString();
54+
var attributes = typeof(BluetoothServices).GetField(v)!.GetCustomAttribute<JsonPropertyNameAttribute>(false)!;
55+
return attributes.Name;
56+
}).ToList();
4457
}

0 commit comments

Comments
 (0)