代码改变世界

Windows Phone7监测网络接口及状态变化

2012-04-27 14:14  王祖康  阅读(1537)  评论(4编辑  收藏  举报

当我们的手机进入到已知(PS:这个wlan网络必须是已经成功连接的)的wlan网络覆盖范围时,手机可以利用这个高速的wlan网络,那么我们第三方应用程序就有机会利用这个高带宽的网络接口进行通讯。

程序中可以通过NetworkAvailabilityChanged 事件监听网络可用性的更改。

下面通过Demo演示如何注册此事件。

  1. 创建应用程序界面。

<Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!--TitlePanel contains the name of the application and page title-->
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock x:Name="ApplicationTitle" Text="网络更改监测" Style="{StaticResource PhoneTextNormalStyle}"/>
        </StackPanel>

        <!--ContentPanel - place additional content here-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <TextBlock Grid.Row="0" Text="可用网络接口" FontSize="{StaticResource PhoneFontSizeLarge}"/>
            <ListBox Grid.Row="1" x:Name="lbNetworkInterfaces" ItemsSource="{Binding}" Background="LightGray" >
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding}" Margin="5,5,0,5" Foreground="Black"/>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
            <TextBlock Grid.Row="2" Text="事件" FontSize="{StaticResource PhoneFontSizeLarge}"/>
            <ScrollViewer Grid.Row="3" Background="LightGray" BorderThickness="1">
                <ListBox x:Name="lbNetworkChanges" ItemsSource="{Binding}">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding}" Foreground="Black" 
                                    FontSize="{StaticResource PhoneFontSizeNormal}" TextWrapping="Wrap" Margin="5,10,0,10"  />
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </ScrollViewer>
            <TextBlock Grid.Row="4" Text="网络状态" FontSize="{StaticResource PhoneFontSizeLarge}"/>
            <Grid Grid.Row="5" Background="LightGray" >
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <TextBlock Grid.Row="0" Grid.Column="0" Text="IsNetworkAvailable" Foreground="Black" Margin="5,5,0,5" />
                <TextBlock Grid.Row="0" Grid.Column="1" x:Name="tbIsNetworkAvailable" HorizontalAlignment="Center" Foreground="Black" />

                <TextBlock Grid.Row="1" Grid.Column="0" Text="IsWiFiEnabled" Foreground="Black" Margin="5,5,0,5" />
                <TextBlock Grid.Row="1" Grid.Column="1" x:Name="tbIsWiFiEnabled" HorizontalAlignment="Center" Foreground="Black"/>

                <TextBlock Grid.Row="2" Grid.Column="0" Text="IsCellularDataEnabled" Foreground="Black" Margin="5,5,0,5" />
                <TextBlock Grid.Row="2" Grid.Column="1" x:Name="tbIsCellularDataEnabled" HorizontalAlignment="Center" Foreground="Black"/>
            </Grid>
            <Button Grid.Row="6" x:Name="btnChangeNetworkSettings" Content="更改网络设置" Click="btnChangeNetworkSettings_Click"/>
        </Grid>
    </Grid>

运行界面如下:

页面顶端,显示出所有可用的网络接口。

页面中间,显示关于应用程序接收的任何NetworkAvailabilityChanged 事件的信息。

页面底部,显示手机网络功能的整体状态。

页面底端,显示一个按钮,通过该按钮可以手动更改网络设置,并触发NetworkAvailabilityChanged 事件。

2.注册网络可用性更改

打开MainPage.cs文件

2.1  添加命名空间

using System.Collections.ObjectModel;
using Microsoft.Phone.Net.NetworkInformation;
using Microsoft.Phone.Tasks;

2.2  声明一下变量

// 程序运行时,所有监测到变化集合。
        public ObservableCollection<string> Changes { get; set; }

        // 当前可用网络接口集合
        public ObservableCollection<string> NetworkInterfaces { get; set; }

2.3  将以下代码替换MainPage.cs的构造函数

// 构造函数
        public MainPage()
        {
            InitializeComponent();

            //初始化Changes集合
            Changes = new ObservableCollection<string>();

            //ListBox绑定Changes集合
            lbNetworkChanges.DataContext = Changes;

            NetworkInterfaces = new ObservableCollection<string>();
            lbNetworkInterfaces.DataContext = NetworkInterfaces;

            //注册NetworkAvailabilityChanged事件
            DeviceNetworkInformation.NetworkAvailabilityChanged += new EventHandler<NetworkNotificationEventArgs>(ChangeDetected);

            UpdateNetworkInterfaces();
            UpdateNetworkStatus();
        }

UpdateNetworkInterfaces()方法进行初始化UI的网络接口区域。

UpdateNetworkStatus()方法进程初始化UI的网络状态区域。

通过以上代码,就已经注册了网络可用性的更改。

3.处理网络可用性更改

上一步,我们已经注册了NetworkAvailabilityChanged事件,下面需要实现相应的回调函数。代码如下:

//在回调函数中,进行检查变化。 
        //在demo中,创建了一个string类型的简单信息,并且添加到UI中。 
        //在实际应用中,可以利用网络变化,调整项目中的联网方式。 
        void ChangeDetected(object sender, NetworkNotificationEventArgs e)
        {
            string change = string.Empty;
            switch (e.NotificationType)
            {
                case NetworkNotificationType.InterfaceConnected:
                    change = "连接到 ";
                    break;
                case NetworkNotificationType.InterfaceDisconnected:
                    change = "脱离 ";
                    break;
                case NetworkNotificationType.CharacteristicUpdate:
                    change = "网络变化 ";
                    break;
                default:
                    change = "未知变化 ";
                    break;
            }

            string changeInformation = String.Format(" {0} {1} {2} ({3})",
                        DateTime.Now.ToString(), change, e.NetworkInterface.InterfaceName,
                        e.NetworkInterface.InterfaceType.ToString());

            //更新UI.
            Dispatcher.BeginInvoke(() =>
            {
                Changes.Add(changeInformation);
                UpdateNetworkStatus();
                UpdateNetworkInterfaces();

            });

        }

其中NetworkNotificationEventArgs参数包含所有与通知的变更相关的信息。我们会生成一个信息字符串,字符串中包括何时进行更改,更改的接口名称,接口的类型,然后将信息字符串添加到Changes列表中。我们将UI交互包装在BeginInvoke中,来确保它们在UI线程上执行。

下面实现UpdateNetworkStatus()和UpdateNetworkInterfaces()两个方法。

private void UpdateNetworkInterfaces()
        {

            NetworkInterfaces.Clear();
            NetworkInterfaceList networkInterfaceList = new NetworkInterfaceList();
            foreach (NetworkInterfaceInfo networkInterfaceInfo in networkInterfaceList)
            {
                NetworkInterfaces.Add(networkInterfaceInfo.InterfaceName);
            }
        }

        private void UpdateNetworkStatus()
        {
            tbIsCellularDataEnabled.Text = (DeviceNetworkInformation.IsCellularDataEnabled) ? "" : "";
            tbIsNetworkAvailable.Text = (DeviceNetworkInformation.IsNetworkAvailable) ? "" : "";
            tbIsWiFiEnabled.Text = (DeviceNetworkInformation.IsWiFiEnabled) ? "" : "";
        }

UpdateNetworkInterfaces 方法会实例化NetworkInterfaceList对象。

UpdateNetworkStatus 方法使用DeviceNetworkInformation对象上的静态属性更新UI的网络状态区域。

4.手动更改网络连接

// 为了测试,提供了通过启动ConnectionSettingsTask来更改网络连接设置的方法。
        // 由于模拟器的限制,我们并不能获取到所有NetworkAvailabilityChanged事件。
        // 不过你可以通过真机,进行连接和取消连接wifi网络,进行测试。
        private void btnChangeNetworkSettings_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("此操作将改变网络设置。设置成功后,你可以通过Back键,返回查看NetworkAvailabilityChanged事件。");

            //使用ConnectionSettingsTask启用连接设置
            ConnectionSettingsTask connectionSettings = new ConnectionSettingsTask();

            //将连接设置更改为飞行模式
            connectionSettings.ConnectionSettingsType = ConnectionSettingsType.AirplaneMode;
            connectionSettings.Show();

            // 注意: 一旦我们改变了设置,可以使用物理Back键,进行观察NetworkAvailabilityChanged事件。
        }

此方法会启动飞行模式的ConnectionSettingsTask。我们可以通过设置飞行模式的打开或关闭。通过更改飞行模式的设置,返回到应用程序中,可以观察到因更改飞行模式引起的网络可用性更改。

5.应用程序运行结果

点击更改网络设置按钮。

我们除了测试飞行模式外,也可以通过修改代码来启动手机网络或WLAN的ConnectionSettingsTask。

总结:如果我们的程序中,需要通过网络进行数据操作,可以在程序中进行检测是否有网络可用,同时可以建议用户进行设置相应的网络连接设置,进行获取程序中数据等网络连接操作。

注意:虽然手机可以检查到一定数量的WLAN网络,但是这些网络曾经并未进行成功连接过,那么在第三方程序是无法获取到这些网络的。

具体详细介绍请参考MSDN中如何检测 Windows Phone 的网络更改一文。