次の方法で共有


Coding4Fun: 持ち運ぶ - 第 1 部

持ち運ぶ - 第 1 部

Arian Kulp

April 14, 2006
日本語版最終更新日 2006 年 6 月 14 日

今回は、.NET Framework のモビリティについてお話しする 2 部構成のコラムの第 1 部です。モビリティとは何でしょう、難しい質問ですね。モビリティの意味は、人によって受け取り方が異なります。しかし、どのような受け取り方をしても、モバイル対応の環境でさまざまな変化に対応できることが、モビリティの重要な点です。たとえば、ラップトップを起動する場合、システムがバッテリで実行されるか AC 電源で実行されるかを考慮する必要があります。バッテリで実行されるならば、充電量が問題です。AC 電源で実行される場合でも、バッテリの充電が完了しているか、まだ充電中かを考慮する必要があります。また、ネットワークについても考慮する必要があります。ラップトップを持ち運びするときは、ネットワークに接続されたり、切断されたり、接続状態が変化します。つまり、ネットワークと電源の状態を把握することが、モビリティの 2 つの重要な側面になります。そこで、コラムを 2 部に分け、今回は電源の認識に重点を置き、次回はネットワークに関する考慮事項について説明します。

アプリケーションにモビリティのサポートを追加することで、利用できる範囲のリソースを使った操作が容易になります。ネットワークの速度がわかれば、それに応じてデータのスループットを調整できます。ネットワークに接続できないことがわかれば、接続を試みること自体を回避できます。その結果、ユーザーに表示されるエラーが少なくなります。バッテリ電源を使用して操作する場合、電源の状態を把握しておけば、バッテリ電源のレベルが低下したときでも、充電残量を効率的に使用できます。

この記事で紹介するアプリケーションは、C# と Visual Basic の両方を用意しています。コードへのリンクはページ上部にあります。このサンプル コードを出発点として独自のプロジェクトを作成するか、または学習の参考資料として使用してください。サンプル プログラム ファイル内では実際のコメント行は英語で書かれていますが、この記事内では説明目的で日本語で書かれています。このコラムでは、Microsoft Visual Basic Express Edition または Microsoft Visual C# Express Edition のコピーが必要です。https://www.microsoft.com/japan/msdn/vstudio/express/ から、これらのコピーのいずれか (および他の Visual Studio Express Edition) をダウンロードできます。このアプリケーションでは、ラップトップ コンピュータや Tablet PC で実行するときに最も重要な機能に注目していますが、デスクトップ コンピュータでも問題なく実行できます (バッテリが存在しないことが報告されるだけです)。

電源を操作する

電源に関する情報を扱う場合、.NET Framework 2.0 までは P/Invoke 機能を使用してネイティブ Win32 ライブラリを呼び出す必要がありました。コピーして貼り付けることができる適切なコードを所持している場合 (またはアンマネージ コードの呼び出しが苦にならない場合)、このような呼び出しを行うことに問題ありませんでしたが、決して正しいとは言えませんでした。マネージ オブジェクトを使用してすべてのコードを記述すれば、コードの記述と管理が容易になります。

.NET Framework 1.1 では、イベントを使用して複数の電源状態から 1 つの状態を判断できました。SystemEvents.PowerModeChanged イベントは、次の 3 つのモードのいずれかを示します。

  • Resume: システムが再開中です。

  • StatusChange: AC 電源とバッテリの間、または他の状態に変化中です。

  • Suspend: システムが中断中です。

私見ですが、StatusChange モードは奇妙なモードに思えます。MSDN には、「これは、バッテリ電力の低下、バッテリの充電中、AC 電源からバッテリへの移行など、システムの電源状態が変化したことを示しています」と記載されています。つまり、このモードは単独ではほとんど役に立ちません。電源の切り替え (または他の状態への変化) を認識しても、詳しい情報を読み取ることができなければ、あまり意味はありません。ここでアンマネージ コードを使用します。この時点で強制的に Win32 の GetSystemPowerStatus 関数を呼び出して、システム電源の情報を含む構造体を操作します。しかし、あまりスマートではありません。

.NET Framework 2.0 では、SystemInformation クラスに、PowerStatus プロパティが追加されました。このプロパティは、上記の構造体と同じ情報を含む、同じ型のオブジェクトを返します。多くの場合、実際には同じアンマネージ呼び出しが行われますが、このプロパティにより、kernel32.dll をインポートする必要がなくなり、.NET のスキルを活用できます。余談ですが、SystemInformation クラスは、モニタ、解像度、キーボードやマウスの設定、コンピュータ名などを判断するうえで役立つ情報の宝庫です。

バッテリ情報は、次のように簡単に取得できます。

  
    Dim ps As PowerStatus = SystemInformation.PowerStatus
' バッテリの現在充電量が 1 ~ 0 で表されます
Console.WriteLine("Level: {0}:",  (ps.BatteryLifePercent * 100) & "%")

PowerStatus オブジェクトは任意の時点に取得でき、常に最新の状態です。変化が生じたかどうかを判断するには、次のように SystemEvents.PowerModeChanged イベントをサブスクライブするだけです。

  
    AddHandler SystemEvents.PowerModeChanged, AddressOf PowerModeHandler 

このイベントが発生したときは、電源に関連するイベントかどうかを確認し、そのイベントの Mode プロパティが StatusChange であれば、PowerStatus の情報を読み取ります。これが今回のアプリケーションで採用している方法です。次のスクリーン ショットは、AC 電源を使用し、インターネット接続を行うアプリケーションを示しています。

図 1. AC 電源での実行

今回は [Network] 領域を無視し、[Battery Info] 領域に注目しましょう。表示されている 5 つのフィールドは、すべて PowerStatus オブジェクトのプロパティです。BatteryChargeStatus プロパティの値は次のいずれかになります。

  • Charging

  • Critical

  • High

  • Low

  • NoSystemBattery

  • Unknown

ご想像のとおり、NoSystemBattery 値はシステムにバッテリが存在しない場合に設定されます。これを使えば、電源の機能をアプリケーションに実装でき、デスクトップ コンピュータでもラップトップ コンピュータでも正常に機能します。PowerLineStatus を使用して、システムがバッテリ電源と AC 電源のどちらを利用しているかを示します。このプロパティは次のいずれかの値になります。

  • Online (AC)

  • Offline (Battery)

  • Unknown (Hmm...)

BatteryFullLifetime プロパティと BatteryLifeRemaining プロパティはそれぞれ、バッテリの全体寿命と現時点の残寿命を表す秒数を返します。結果は、特定のバッテリやシステムによって異なる場合があります。ご覧のとおり、筆者のシステムではバッテリの BatteryFullLifetime が報告されません。このことは、0 という値で示されます。アプリケーションで表示する場合、TimeSpan オブジェクトを作成して次のような形式に変換します。

  
    ' 現在の充電量に基づくバッテリ寿命の長さ
Dim ts As New TimeSpan(0, 0, ps.BatteryLifeRemaining)
If ps.BatteryLifeRemaining > 0 Then
    BatteryLifeRemainingTextBox.Text = ts.ToString()
Else
    BatteryLifeRemainingTextBox.Text = "Unknown"
End If

最後に、BatteryLifePercent プロパティは、0 (バッテリがまったく充電されていない状態) ~ 1 (完全に充電された状態) の数値を返します。表示する数値を求めるには、単純に 100 を乗算します。少なくとも筆者のシステムでは、100% が報告されることはほとんどないことがわかりました。ただし、これらのプロパティの情報は、通常、システムの [パワー マネージメントのプロパティ] コントロール パネル アプレットと一貫性があります。

図 2. バッテリでの実行

電源を判断するメソッドを完成するには、PowerStatus のプロパティを問い合わせて、受け取ったデータの書式を変換するだけです。このメソッドは、PowerModeChanged イベントに基づかなくても、いつでも呼び出すことができます。今回のアプリケーションでは、このメソッドがアプリケーションの初期化中に (フォームのコンストラクタで) 1 回呼び出され、その後イベントが発生するたびに呼び出されます。

  
    Private Sub UpdatePowerInfo()
  Dim ps As PowerStatus = SystemInformation.PowerStatus
  ' 充電中、放電中、充電完了など
  BatteryChargeStatusTextBox.Text = ps.BatteryChargeStatus.ToString()
  ' バッテリの現在充電量が 1 ~ 0 で表されます
  BatteryLifePercentTextBox.Text = (ps.BatteryLifePercent * 100) & "%"
  PowerLineStatusTextBox.Text = ps.PowerLineStatus.ToString()
  ' 現在の充電量に基づくバッテリ寿命の長さ
  Dim ts As New TimeSpan(0, 0, ps.BatteryLifeRemaining)
  If ps.BatteryLifeRemaining > 0 Then
    BatteryLifeRemainingTextBox.Text = ts.ToString()
  Else
    BatteryLifeRemainingTextBox.Text = "Unknown"
  End If
  ' 完全に充電された場合のバッテリ寿命 (秒)
  ts = New TimeSpan(0, 0, ps.BatteryFullLifetime)
  If ps.BatteryFullLifetime > 0 Then
    BatteryFullLifetimeTextBox.Text = ts.ToString()
  Else
    BatteryFullLifetimeTextBox.Text = "Unknown"
  End If
  ' PowerLineStatus は Online (AC)、Offline (Battery)、または Unknown
  PowerModeToolStripStatusLabel.Text = _
    IIf(ps.PowerLineStatus = PowerLineStatus.Online, "AC", "Battery")
End Sub

今後のステップ

このメソッドをアプリケーションと統合することは簡単です。このままでも十分ですが、ステータス バーに上記の情報が報告されると、アプリケーションはより洗練されて完全なものに見えるようになります。バッテリのレベルまたは AC 電源やバッテリの状態に基づいてユーザーが対応を変更できるような設定を追加することもできます。たとえば、バッテリの消耗を少なくするために、ゲームの詳細レベルを自動的に下げたり、動的なスクリーンセーバーの複雑さを自動的に緩和したりできます。

PowerModeChanged イベントの Resume モードと Suspend モードについては少し触れましたが、実際には説明しませんでした。これらのモードは、システムが中断される前に保存されていないデータをディスクに保存したり、ファイル転送を中断または再開したりするために使用します。

まとめ

電源状態の認識機能を追加することは複雑な課題のように思えるかもしれませんが、.NET 2.0 の新しいサポートによって容易になりました。あらゆるアプリケーションでこうした機能を利用できます。利用できるシステム情報を使用することで、他の方法を利用する場合よりもさらに優れたアプリケーションになります。

ページ上部からサンプル コードをダウンロードし、https://www.microsoft.com/japan/msdn/vstudio/express/ から Visual Basic Express または Visual C# Express のコピーをダウンロードして、以前よりも優れたコードを記述してください。電源状態の認識機能を追加することで、アプリケーションをどこにでも持ち運ぶことができます。

Arian Kulp は中西部在住のフリーのソフトウェア開発者です。彼は小学校 5 年生のとき以来、次々に異なるプラットフォームでコーディングを行ってきました。最近では .NET Framework に熱中しています。彼の Web サイトは、http://www.ariankulp.com/default.aspx (英語) からご覧になれます。

top of page Top of Page