酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

Windowsストアアプリでインターネット接続されているかどうかを確認する

以前、Twitterで嘆いていたような気もするのですが、Windows Live SDKはインターネット接続されていない状態でSkyDriveのディレクトリを取得しにいったりしようとすると、度々ハンドルできない例外を吐いてアプリをクラッシュさせます。

x86とARM環境下でも挙動が異なる時があって、(きちんとした記録を残していないのですが)インターネットに接続されていない環境下で、Live SDKを使ってログイン処理を実行するとハンドルできない例外でが発生してしまいアプリがクラッシュしていました。

そこで僕はLive SDKに処理を渡す前にインターネット接続されているかどうかの検証をおこなうようにしました。

ネットワークに接続されているか調べる

GetIsNetworkAvailableメソッドを使用して、ネットワーク接続が使用できるかどうかを調べることができます。

// using System.Net.NetworkInformation;

if (NetworkInterface.GetIsNetworkAvailable()) {
    // ネットワークに繋がっている場合の処理
} else {
    // ネットワークに繋がっていない場合の処理
}

しかし、上記のコードのようにSystem.Net名前空間のNetworkInterfaceクラスのGetIsNetworkAvailableメソッドだけではインターネット接続できているかどうかの検証をおこなうことはできませんでした。

デバイスが有効なネットワークに接続されていないにも関わらず、使用可能であるとしてGetIsNetworkAvailableメソッドがtrueで返ってくることがあるので注意してください。

インターネットへ接続されているかどうかを調べる

最終的にはWindows.Networking.Connectivity名前空間のNetworkInterfaceクラスのGetInternetConnectionProfileメソッドを使って、現在パソコン(タブレット)で使われているネットワーク接続プロファイルを取得しました。

そのネットワーク接続プロファイルがどのリソース(LANなのかWANなのかなど)を利用することがでるのか情報を取得するために、GetInternetConnectionProfileメソッドを使って接続レベルを取得します。

接続レベルには複数あります。意味はそれぞれの通りです。

意味
NetworkConnectivityLevel.InternetAccess ローカルおよびインターネット接続
NetworkConnectivityLevel.LocalAccess ローカル接続
NetworkConnectivityLevel.ConstrainedInternetAccess 制限されたインターネット接続
NetworkConnectivityLevel.None なし

制限されたインターネット接続はどのようなケースかというと、カフェや新幹線などで提供しているその無料インターネットサービスのサービスのポータルサイトには接続できるけれど、それ以外のサイトは閲覧できないという状態です。

この接続レベルによってインターネット接続されているか確認してみましょう。下記のように実装することが可能です。

// using Windows.Networking.Connectivity;
var profile = NetworkInformation.GetInternetConnectionProfile();
if (profile != null)
{
    var connectivityLevel = profile.GetNetworkConnectivityLevel();
    if (connectivityLevel != NetworkConnectivityLevel.InternetAccess)
    {
        // インターネット接続できへん
    }
}

接続されているネットワークタイプを調べる

インターネットに接続されているのかどうかを取得できることは分かりました。

安定したネットワーク接続を求めるのであれば、接続されているのがUSBケーブルや無線LANなど何を介してインターネットに接続されているのかをネットワークタイプを調べることができます。

// using System.Net.NetworkInformation;

    var nt = NetworkInterface.NetworkInterfaceType;
    switch (nt) {
        case NetworkInterfaceType.Ethernet:
            // IEEE規格802.3で定義された
            // イーサネット接続を使用している状態
            break;
        case NetworkInterfaceType.Fddi:
            // 光ファイバー回線を使用した
            // FDDI接続を使用している状態
            break;
        case NetworkInterfaceType.TokenRing:
            // IEEE規格802.5で定義された
            // トークンリング接続を使用している状態
            break;
        case NetworkInterfaceType.Unknown:
            // インターフェイスの種類がわからない状態
            break;
    }

上記に挙げているものが全てではありません。

詳細については、こちらのNetworkInterfaceType Enumerationをご覧ください。

お願いします。

関連記事

WindowsランタイムAPI(Windows Runtime API, WinRT API)を使ってアプリ開発する際に逆引きとしてお使いください。