バッテリー情報の取得Get battery information

** 重要な API **** Important APIs **

Windows.Devices.Power 名前空間で、API を使って詳細なバッテリー情報を取得する方法について説明します。Learn how to get detailed battery information using APIs in the Windows.Devices.Power namespace. バッテリー レポート (BatteryReport) は、バッテリーの充電量、容量、状態や、バッテリーの集計を示します。A battery report (BatteryReport) describes the charge, capacity, and status of a battery or aggregate of batteries. このトピックでは、アプリでバッテリー レポートを取得したり、変更に関する通知を受け取ったりする方法を紹介します。This topic demonstrates how your app can get battery reports and be notified of changes. コード例は基本的なバッテリー アプリからの抜粋で、このトピックの末尾の一覧で確認できます。Code examples are from the basic battery app that's listed at the end of this topic.

バッテリー集計レポートの取得Get aggregate battery report

一部のデバイスにはバッテリーが複数あり、各バッテリーがデバイスの消費エネルギー全体にどのように関与しているのか明確でない場合があります。Some devices have more than one battery and it's not always obvious how each battery contributes to the overall energy capacity of the device. AggregateBattery クラスはまさにそのような用途に使います。This is where the AggregateBattery class comes in. バッテリー集計レポートはデバイスに接続されたすべてのバッテリー コントローラーを表し、1 つの全体的な BatteryReport オブジェクトを提供できます。The aggregate battery represents all battery controllers connected to the device and can provide a single overall BatteryReport object.

  A バッテリクラスは、実際には、バッテリのコント ローラーに対応します。Note  A Battery class actually corresponds to a battery controller. デバイスに応じて、コントローラーは物理的なバッテリーに接続されることもあれば、デバイス エンクロージャに接続されることもあります。Depending on the device, sometimes the controller is attached to the physical battery and sometimes it's attached to the device enclosure. そのため、バッテリーがなくても、バッテリ オブジェクトを作ることができます。Thus, it's possible to create a battery object even when no batteries are present. また、バッテリ オブジェクトは null にすることもできます。Other times, the battery object may be null.

集計バッテリー オブジェクトを指定したら、GetReport を呼び出して、対応する BatteryReport を取得します。Once you have an aggregate battery object, call GetReport to get the corresponding 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);
}

個々のバッテリー レポートを取得するGet individual battery reports

個々のバッテリーに対する BatteryReport オブジェクトを作ることもできます。You can also create a BatteryReport object for individual batteries. GetDeviceSelectorFindAllAsync メソッドと共に使って、デバイスに接続されているバッテリー コントローラーがあるかどうかを表す DeviceInformation オブジェクトのコレクションを取得します。Use GetDeviceSelector with the FindAllAsync method to obtain a collection of DeviceInformation objects that represent any battery controllers that are connected to the device. 次に、必要な DeviceInformation オブジェクトの Id プロパティを使って、FromIdAsync メソッドを使い、対応する Battery を作ります。Then, using the Id property of the desired DeviceInformation object, create a corresponding Battery with the FromIdAsync method. 最後に、GetReport を呼び出して、各バッテリー レポートを取得します。Finally, call GetReport to get the individual battery report.

次の例は、デバイスに接続されているすべてのバッテリーのバッテリー レポートを作る方法を示しています。This example shows how to create a battery report for all batteries connected to the device.

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 */ }
    }
}

レポートの詳細にアクセスするAccess report details

BatteryReport オブジェクトは、多くのバッテリー情報を提供します。The BatteryReport object provides a lot of battery information. 詳細については、そのプロパティの API リファレンスを参照してください。ステータス(、 BatteryStatus 列挙型)、 ChargeRateInMilliwatts DesignCapacityInMilliwattHours FullChargeCapacityInMilliwattHours、および RemainingCapacityInMilliwattHoursします。For more info, see the API reference for its properties: Status (a BatteryStatus enumeration), ChargeRateInMilliwatts, DesignCapacityInMilliwattHours, FullChargeCapacityInMilliwattHours, and RemainingCapacityInMilliwattHours. 次の例は、基本的なバッテリー アプリで使用される一部のバッテリー レポート プロパティを示しています。このプロパティについては、このトピックで後ほど説明します。This example shows some of the battery report properties used by the basic battery app, that's provided later in this topic.

...
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() };
...
...

レポートの更新を要求するRequest report updates

Battery オブジェクトは、バッテリーの充電量、容量、状態が変わると ReportUpdated イベントをトリガーします。The Battery object triggers the ReportUpdated event when charge, capacity, or status of the battery changes. 通常、これは、ステータスの変更についてはすぐに、その他のすべての変更については定期的に発生します。This typically happens immediately for status changes and periodically for all other changes. 次の例は、バッテリー レポートの更新に登録する方法を示しています。This example shows how to register for battery report updates.

...
Battery.AggregateBattery.ReportUpdated += AggregateBattery_ReportUpdated;
...

レポートの更新を処理するHandle report updates

バッテリーの更新が発生すると、ReportUpdated イベントは対応する Battery オブジェクトをイベント ハンドラー メソッドに渡します。When a battery update occurs, the ReportUpdated event passes the corresponding Battery object to the event handler method. ただし、このイベント ハンドラーは、UI スレッドから呼び出されません。However, this event handler is not called from the UI thread. 次の例で示すように、Dispatcher オブジェクトを使って任意の UI の変更を呼び出す必要があります。You'll need to use the Dispatcher object to invoke any UI changes, as shown in this example.

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();
            }
        });
    }
}

例: 基本的なバッテリー アプリExample: basic battery app

Microsoft Visual Studio で次の基本的なバッテリー アプリをビルドすることによって、これらの API をテストします。Test out these APIs by building the following basic battery app in Microsoft Visual Studio. Visual Studio のスタート ページで [新しいプロジェクト] をクリックし、 [Visual C#] > [Windows] > [ユニバーサル] テンプレートで [空のアプリケーション] テンプレートを使って新しいアプリを作ります。From the Visual Studio start page, click New Project, and then under the Visual C# > Windows > Universal templates, create a new app using the Blank App template.

次に、MainPage.xaml ファイルを開き、次の XML をこのファイルにコピーします (元の内容を置き換えます)。Next, open the file MainPage.xaml and copy the following XML into this file (replacing its original contents).

<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>

自分のアプリの名前が App1 ではない場合、元のスニペットのクラス名の最初の部分を、自分のアプリの名前空間に置き換える必要があります。If your app isn't named App1, you'll need to replace the first part of the class name in the previous snippet with the namespace of your app. たとえば、作成したプロジェクトの名前が BasicBatteryApp だとすると、x:Class="App1.MainPage"x:Class="BasicBatteryApp.MainPage" に置き換えます。For example, if you created a project named BasicBatteryApp, you'd replace x:Class="App1.MainPage" with x:Class="BasicBatteryApp.MainPage". また、xmlns:local="using:App1"xmlns:local="using:BasicBatteryApp" に置き換える必要があります。You should also replace xmlns:local="using:App1" with xmlns:local="using:BasicBatteryApp".

次に、プロジェクトの MainPage.xaml.cs ファイルを開き、記載されているコードを次のコードで置き換えます。Next, open your project's MainPage.xaml.cs file and replace the existing code with the following.

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();
                    }
                });
            }
        }
    }
}

自分のアプリの名前が App1 ではない場合、元のサンプルの名前空間の名前を、自分のプロジェクトに指定した名前に変更する必要があります。If your app isn't named App1, you'll need to rename the namespace in the previous example with the name you gave your project. たとえば、作成したプロジェクトの名前が BasicBatteryApp だとすると、App1 名前空間を BasicBatteryApp 名前空間に置き換えます。For example, if you created a project named BasicBatteryApp, you'd replace namespace App1 with namespace BasicBatteryApp.

最後に、この基本的なバッテリー アプリを実行します: [デバッグ] メニューで [デバッグの開始] をクリックしてソリューションをテストします。Finally, to run this basic battery app: on the Debug menu, click Start Debugging to test the solution.

ヒント:   の数値の値を受信する、 BatteryReport オブジェクトでのアプリのデバッグ、ローカル マシンまたは外部デバイス(Windows Phone) など。Tip  To receive numeric values from the BatteryReport object, debug your app on the Local Machine or an external Device (such as a Windows Phone). デバイス エミュレーターでデバッグした場合、BatteryReport オブジェクトは容量や消費率のプロパティに null を返します。When debugging on a device emulator, the BatteryReport object returns null to the capacity and rate properties.