取得電池資訊

本主題描述如何取得包含詳細電池資訊 (例如電池或電池組的電量、容量和狀態) 的電池報告,並處理報告中任何項目的狀態變更。

(BatteryReport)

程式碼範例來自本主題結尾所列的基本電池應用程式。

重要 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 物件。 搭配 FindAllAsync 方法使用 GetDeviceSelector 來取得 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 參考:Status (BatteryStatus) 列舉、ChargeRateInMilliwattsDesignCapacityInMilliwattHoursFullChargeCapacityInMilliwattHoursRemainingCapacityInMilliwattHours。 本範例顯示本主題稍後提供的基本電池應用程式所使用的部分電池報表屬性。

...
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="BasicBatteryApp.MainPage" 取代為 x:Class="App1.MainPage" 為,xmlns:local="using:BasicBatteryApp" 取代為 xmlns:local="using:App1"

<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 的專案,則會將命名空間取代為命名空間App1BasicBatteryApp

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 傳回至容量和速率屬性。