アプリライフサイクル API を使用した電源管理

Windows app SDK のアプリライフサイクル api は、Microsoft の Windows で一連の電源管理 api を提供します。 System. Power名前空間。 これらの Api は、アプリがデバイスの電源状態にどのように影響するかを可視化し、アプリがリソースの使用状況に関するインテリジェントな決定を行うことができるようにします。 たとえば、アプリは、この API を使用して、デバイスがバッテリ電源で実行されている間に、リソースを大量に消費するバックグラウンドタスクを延期する場合があります。

電源管理 Api では、既存の Powersettingregisternotification 関数と同様のコールバックベースのモデルを使用します。 コールバックモデルを使用すると、バックグラウンドアプリ、ヘッドレスアプリなど、すべてのアプリに対して API のリーチが拡張されます。

前提条件

Windows app SDK でアプリライフサイクル API を使用するには、次のようにします。

  1. Windows App SDK の最新リリースをダウンロードしてインストールします。 詳細については、開発者ツールのインストールに関する記事をご覧ください。
  2. 手順に従って、Windows App SDK を使用した新しいプロジェクトを作成するか、既存のプロジェクトで Windows App SDK を使用します。

イベントのサブスクライブと応答

次の例は、 Powermanager イベントをサブスクライブして応答する方法を示しています。 このコードは、起動時に BatteryStatusChanged イベントをサブスクライブします。 その後、アプリは、現在の電源レベルを確認し、リソースの使用状況を適切に調整することで、変更に応答します。 たとえば、バッテリが省電力状態で退院た場合、アプリは重要ではないバックグラウンド作業を遅らせる可能性があります。

Note

アプリは、いつでもこれらのイベントの登録と登録解除を行うことができますが、ほとんどのアプリでは、アプリの実行が継続されている限り、のコールバックを設定する必要があり WinMain ます。

BOOL bWorkInProgress;
winrt::event_token batteryToken;
winrt::event_token powerToken;
winrt::event_token powerSourceToken;
winrt::event_token chargeToken;
winrt::event_token dischargeToken;

void RegisterPowerManagerCallbacks()
{
    batteryToken = PowerManager::BatteryStatusChanged([&](
        const auto&, winrt::Windows::Foundation::IInspectable obj) { OnBatteryStatusChanged(); });
    powerToken = PowerManager::PowerSupplyStatusChanged([&](
        const auto&, winrt::Windows::Foundation::IInspectable obj) { OnPowerSupplyStatusChanged(); });
    powerSourceToken = PowerManager::PowerSourceKindChanged([&](
        const auto&, winrt::Windows::Foundation::IInspectable obj) { OnPowerSourceKindChanged(); });
    chargeToken = PowerManager::RemainingChargePercentChanged([&](
        const auto&, winrt::Windows::Foundation::IInspectable obj) { OnRemainingChargePercentChanged(); });
    dischargeToken = PowerManager::RemainingDischargeTimeChanged([&](
        const auto&, winrt::Windows::Foundation::IInspectable obj) { OnRemainingDischargeTimeChanged(); });

    if (batteryToken && powerToken && powerSourceToken && chargeToken && dischargeToken)
    {
        OutputMessage(L"Successfully registered for state notifications");
    }
    else
    {
        OutputMessage(L"Failed to register for state notifications");
    }
}

void OnBatteryStatusChanged()
{
    const size_t statusSize = 16;
    WCHAR szStatus[statusSize];
    wmemset(&(szStatus[0]), 0, statusSize);

    BatteryStatus batteryStatus = PowerManager::BatteryStatus();
    int remainingCharge = PowerManager::RemainingChargePercent();
    switch (batteryStatus)
    {
    case BatteryStatus::Charging:
        wcscpy_s(szStatus, L"Charging");
        break;
    case BatteryStatus::Discharging:
        wcscpy_s(szStatus, L"Discharging");
        break;
    case BatteryStatus::Idle:
        wcscpy_s(szStatus, L"Idle");
        break;
    case BatteryStatus::NotPresent:
        wcscpy_s(szStatus, L"NotPresent");
        break;
    }

    OutputFormattedMessage(
        L"Battery status changed: %s, %d%% remaining", 
        szStatus, remainingCharge);
    DetermineWorkloads();
}

void OnPowerSupplyStatusChanged()
{
//...etc
}

複数のステータス値に基づいてアプリケーションロジックを構成する

Powermanager イベントは比較的低レベルです。場合によっては、1つのイベントハンドラーが呼び出されると、アプリが動作方法を決定するのに十分な情報が得られないことがあります。 この例では、デバイスが電源に接続されていないときに、 PowerSupplyStatusChanged イベントを呼び出すことができます。 その場合、アプリは、続行する方法を決定する前に、現在のバッテリの状態を確認する必要があります。

void DetermineWorkloads()
{
    BatteryStatus batteryStatus = PowerManager::BatteryStatus();
    int remainingCharge = PowerManager::RemainingChargePercent();
    PowerSupplyStatus powerStatus = PowerManager::PowerSupplyStatus();
    PowerSourceKind powerSource = PowerManager::PowerSourceKind();

    if ((powerSource == PowerSourceKind::DC 
        && batteryStatus == BatteryStatus::Discharging 
        && remainingCharge < 25)
        || (powerSource == PowerSourceKind::AC
        && powerStatus == PowerSupplyStatus::Inadequate))
    {
        // The device is not in a good battery/power state, 
        // so we should pause any non-critical work.
        PauseNonCriticalWork();
    }
    else if ((batteryStatus != BatteryStatus::Discharging && remainingCharge > 75)
        && powerStatus != PowerSupplyStatus::Inadequate)
    {
        // The device is in good battery/power state,
        // so let's kick of some high-power work.
        StartPowerIntensiveWork();
    }
}

画面の状態を確認する

Powermanagerクラスは、アプリの電力使用状況に関連するその他のデバイスの状態に関する情報を提供します。 たとえば、アプリは、デバイスのディスプレイがオフになっているときにグラフィックス処理を無効にすることができます。

void OnDisplayStatusChanged()
{
    const size_t statusSize = 16;
    WCHAR szStatus[statusSize];
    wmemset(&(szStatus[0]), 0, statusSize);

    DisplayStatus displayStatus = PowerManager::DisplayStatus();
    switch (displayStatus)
    {
    case DisplayStatus::Dimmed:
        wcscpy_s(szStatus, L"Dimmed");
        break;
    case DisplayStatus::Off:
        wcscpy_s(szStatus, L"Off");
        break;
    case DisplayStatus::On:
        wcscpy_s(szStatus, L"On");
        break;
    }

    OutputFormattedMessage(
        L"Display status changed: %s", szStatus);
    if (displayStatus == DisplayStatus::Off)
    {
        // The screen is off, let's stop rendering foreground graphics,
        // and instead kick off some background work now.
        StopUpdatingGraphics();
        StartDoingBackgroundWork();
    }
}

イベントのサブスクリプションを解除する

アプリは、ライフサイクル中に通知の登録と登録解除を行うことができます。 アプリがライフサイクル全体で電源状態の通知を受信する必要がない場合は、言語の優先イベント登録管理システムを使用します。

void UnregisterPowerManagerCallbacks()
{
    OutputMessage(L"Unregistering state notifications");
    PowerManager::BatteryStatusChanged(batteryToken);
    PowerManager::PowerSupplyStatusChanged(powerToken);
    PowerManager::PowerSourceKindChanged(powerSourceToken);
    PowerManager::RemainingChargePercentChanged(chargeToken);
    PowerManager::RemainingDischargeTimeChanged(dischargeToken);
}