获取电池信息
本主题介绍如何获取 包含详细电池信息(例如电池的充电、容量和电池状态或电池聚合)的电池报表 ,以及处理报表中任何项的状态更改。
代码示例来自本主题末尾列出的基本电池应用。
重要的 API
获取聚合电池报告
某些设备具有多个电池,并且并非总是很明显,每个电池对设备的整体能量容量的贡献并不明显。 这是 AggregateBattery 类的传入位置。 聚合电池表示连接到设备的所有电池控制器,并提供单个整体 BatteryReport 对象。
请注意 , 电池 类实际上对应于电池控制器。 根据设备,控制器有时连接到物理电池,有时连接到设备机箱。 因此,即使不存在电池,也可以创建电池对象。 其他情况下,电池对象可能为 null。
获得聚合电池对象后,调用 GetReport 以获取相应的 BatteryReport。
private void RequestAggregateBatteryReport()
{
// Create aggregate battery object
var aggBattery = Battery.AggregateBattery;
// Get report
var report = aggBattery.GetReport();
// Update UI
AddReportUI(BatteryReportPanel, report, aggBattery.DeviceId);
}
获取单个电池报告
还可以为单个电池创建 BatteryReport 对象。 将 GetDeviceSelector 与 FindAllAsync 方法配合使用,以获取表示连接到设备的任何电池控制器的 DeviceInformation 对象的集合。 然后,使用所需 DeviceInformation 对象的 Id 属性,使用 FromIdAsync 方法创建相应的 Battery。 最后,调用 GetReport 获取单个电池报告。
此示例演示如何为连接到设备的所有电池创建电池报告。
async private void RequestIndividualBatteryReports()
{
// Find batteries
var deviceInfo = await DeviceInformation.FindAllAsync(Battery.GetDeviceSelector());
foreach(DeviceInformation device in deviceInfo)
{
try
{
// Create battery object
var battery = await Battery.FromIdAsync(device.Id);
// Get report
var report = battery.GetReport();
// Update UI
AddReportUI(BatteryReportPanel, report, battery.DeviceId);
}
catch { /* Add error handling, as applicable */ }
}
}
访问报表详细信息
BatteryReport 对象提供了大量电池信息。 有关详细信息,请参阅其属性的 API 参考:状态(BatteryStatus 枚举)、ChargeRateInMilliwatts、DesignCapacityInMilliwattHours、FullChargeCapacityInMilliwattHours 和 RemainingCapacityInMilliwattHours。 此示例显示了基本电池应用使用的一些电池报告属性,本主题稍后提供。
...
TextBlock txt3 = new TextBlock { Text = "Charge rate (mW): " + report.ChargeRateInMilliwatts.ToString() };
TextBlock txt4 = new TextBlock { Text = "Design energy capacity (mWh): " + report.DesignCapacityInMilliwattHours.ToString() };
TextBlock txt5 = new TextBlock { Text = "Fully-charged energy capacity (mWh): " + report.FullChargeCapacityInMilliwattHours.ToString() };
TextBlock txt6 = new TextBlock { Text = "Remaining energy capacity (mWh): " + report.RemainingCapacityInMilliwattHours.ToString() };
...
...
请求报告更新
当电池电量、容量或状态发生更改时,Battery 对象将触发 ReportUpdated 事件。 对于状态更改和所有其他更改,通常会立即发生这种情况。 此示例演示如何注册电池报告更新。
...
Battery.AggregateBattery.ReportUpdated += AggregateBattery_ReportUpdated;
...
处理报表更新
发生电池更新时,ReportUpdated 事件会将相应的 Battery 对象传递给事件处理程序方法。 但是,不会从 UI 线程调用此事件处理程序。 需要使用 Dispatcher 对象来调用任何 UI 更改,如以下示例所示。
async private void AggregateBattery_ReportUpdated(Battery sender, object args)
{
if (reportRequested)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
// Clear UI
BatteryReportPanel.Children.Clear();
if (AggregateButton.IsChecked == true)
{
// Request aggregate battery report
RequestAggregateBatteryReport();
}
else
{
// Request individual battery report
RequestIndividualBatteryReports();
}
});
}
}
示例:基本电池应用
通过在 Microsoft Visual Studio 中生成以下基本电池应用来测试这些 API。 在 Visual Studio 起始页中,单击“新建项目”,然后在 Visual C# > Windows > 通用模板下,使用空白应用模板创建新应用。
接下来,打开 MainPage.xaml 文件,并将以下 XML 复制到此文件中(替换其原始内容)。
注意
如果你的应用未命名 App1,则需要将以下代码片段中的类名的第一部分替换为应用的命名空间。 例如,如果创建了名为 BasicBatteryApp 的项目,请替换为x:Class="App1.MainPage"
x:Class="BasicBatteryApp.MainPage"
和xmlns:local="using:App1"
替换为 xmlns:local="using:BasicBatteryApp"
。
<Page
x:Class="App1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" >
<StackPanel VerticalAlignment="Center" Margin="15,30,0,0" >
<RadioButton x:Name="AggregateButton" Content="Aggregate results" GroupName="Type" IsChecked="True" />
<RadioButton x:Name="IndividualButton" Content="Individual results" GroupName="Type" IsChecked="False" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<Button x:Name="GetBatteryReportButton"
Content="Get battery report"
Margin="15,15,0,0"
Click="GetBatteryReport"/>
</StackPanel>
<StackPanel x:Name="BatteryReportPanel" Margin="15,15,0,0"/>
</StackPanel>
</Page>
接下来,打开项目的 MainPage.xaml.cs 文件,并将现有代码替换为以下内容。
注意
如果应用未命名 为 App1,则需要使用你提供项目的名称重命名以下示例中的命名空间。 例如,如果创建了名为 BasicBatteryApp 的项目,则将命名空间 App1
替换为命名空间 BasicBatteryApp
。
using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.Devices.Enumeration;
using Windows.Devices.Power;
using Windows.UI.Core;
namespace App1
{
public sealed partial class MainPage : Page
{
bool reportRequested = false;
public MainPage()
{
this.InitializeComponent();
Battery.AggregateBattery.ReportUpdated += AggregateBattery_ReportUpdated;
}
private void GetBatteryReport(object sender, RoutedEventArgs e)
{
// Clear UI
BatteryReportPanel.Children.Clear();
if (AggregateButton.IsChecked == true)
{
// Request aggregate battery report
RequestAggregateBatteryReport();
}
else
{
// Request individual battery report
RequestIndividualBatteryReports();
}
// Note request
reportRequested = true;
}
private void RequestAggregateBatteryReport()
{
// Create aggregate battery object
var aggBattery = Battery.AggregateBattery;
// Get report
var report = aggBattery.GetReport();
// Update UI
AddReportUI(BatteryReportPanel, report, aggBattery.DeviceId);
}
async private void RequestIndividualBatteryReports()
{
// Find batteries
var deviceInfo = await DeviceInformation.FindAllAsync(Battery.GetDeviceSelector());
foreach(DeviceInformation device in deviceInfo)
{
try
{
// Create battery object
var battery = await Battery.FromIdAsync(device.Id);
// Get report
var report = battery.GetReport();
// Update UI
AddReportUI(BatteryReportPanel, report, battery.DeviceId);
}
catch { /* Add error handling, as applicable */ }
}
}
private void AddReportUI(StackPanel sp, BatteryReport report, string DeviceID)
{
// Create battery report UI
TextBlock txt1 = new TextBlock { Text = "Device ID: " + DeviceID };
txt1.FontSize = 15;
txt1.Margin = new Thickness(0, 15, 0, 0);
txt1.TextWrapping = TextWrapping.WrapWholeWords;
TextBlock txt2 = new TextBlock { Text = "Battery status: " + report.Status.ToString() };
txt2.FontStyle = Windows.UI.Text.FontStyle.Italic;
txt2.Margin = new Thickness(0, 0, 0, 15);
TextBlock txt3 = new TextBlock { Text = "Charge rate (mW): " + report.ChargeRateInMilliwatts.ToString() };
TextBlock txt4 = new TextBlock { Text = "Design energy capacity (mWh): " + report.DesignCapacityInMilliwattHours.ToString() };
TextBlock txt5 = new TextBlock { Text = "Fully-charged energy capacity (mWh): " + report.FullChargeCapacityInMilliwattHours.ToString() };
TextBlock txt6 = new TextBlock { Text = "Remaining energy capacity (mWh): " + report.RemainingCapacityInMilliwattHours.ToString() };
// Create energy capacity progress bar & labels
TextBlock pbLabel = new TextBlock { Text = "Percent remaining energy capacity" };
pbLabel.Margin = new Thickness(0,10, 0, 5);
pbLabel.FontFamily = new FontFamily("Segoe UI");
pbLabel.FontSize = 11;
ProgressBar pb = new ProgressBar();
pb.Margin = new Thickness(0, 5, 0, 0);
pb.Width = 200;
pb.Height = 10;
pb.IsIndeterminate = false;
pb.HorizontalAlignment = HorizontalAlignment.Left;
TextBlock pbPercent = new TextBlock();
pbPercent.Margin = new Thickness(0, 5, 0, 10);
pbPercent.FontFamily = new FontFamily("Segoe UI");
pbLabel.FontSize = 11;
// Disable progress bar if values are null
if ((report.FullChargeCapacityInMilliwattHours == null)||
(report.RemainingCapacityInMilliwattHours == null))
{
pb.IsEnabled = false;
pbPercent.Text = "N/A";
}
else
{
pb.IsEnabled = true;
pb.Maximum = Convert.ToDouble(report.FullChargeCapacityInMilliwattHours);
pb.Value = Convert.ToDouble(report.RemainingCapacityInMilliwattHours);
pbPercent.Text = ((pb.Value / pb.Maximum) * 100).ToString("F2") + "%";
}
// Add controls to stackpanel
sp.Children.Add(txt1);
sp.Children.Add(txt2);
sp.Children.Add(txt3);
sp.Children.Add(txt4);
sp.Children.Add(txt5);
sp.Children.Add(txt6);
sp.Children.Add(pbLabel);
sp.Children.Add(pb);
sp.Children.Add(pbPercent);
}
async private void AggregateBattery_ReportUpdated(Battery sender, object args)
{
if (reportRequested)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
// Clear UI
BatteryReportPanel.Children.Clear();
if (AggregateButton.IsChecked == true)
{
// Request aggregate battery report
RequestAggregateBatteryReport();
}
else
{
// Request individual battery report
RequestIndividualBatteryReports();
}
});
}
}
}
}
提示
若要从 BatteryReport 对象接收数值,请在本地计算机或外部设备上调试应用。 在设备模拟器上进行调试时,BatteryReport 对象将 null 返回到容量和速率属性。