• 与众不同 windows phone (20) Device(设备)之位置服务(GPS 定位), FM 收音机, 麦克风, 震动器


    [索引页]
    [源码下载]


    与众不同 windows phone (20) - Device(设备)之位置服务(GPS 定位), FM 收音机, 麦克风, 震动器



    作者:webabcd


    介绍
    与众不同 windows phone 7.5 (sdk 7.1) 之设备

    • 位置服务(GPS 定位)
    • FM 收音机
    • 麦克风
    • 震动器



    示例
    1、演示如何使用位置服务(GPS 定位)
    GpsDemo.xaml

    <phone:PhoneApplicationPage 
        x:Class="Demo.Device.GpsDemo"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
        xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        FontFamily="{StaticResource PhoneFontFamilyNormal}"
        FontSize="{StaticResource PhoneFontSizeNormal}"
        Foreground="{StaticResource PhoneForegroundBrush}"
        SupportedOrientations="Portrait" Orientation="Portrait"
        mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
        shell:SystemTray.IsVisible="True">
    
        <Grid x:Name="LayoutRoot" Background="Transparent">
            <StackPanel Orientation="Vertical">
    
                <!--跳转到隐私声明页(如果使用了 GPS 则必须要有“隐私声明”,否则不会通过微软的审核)-->
                <HyperlinkButton Content="隐私声明" NavigateUri="/Device/PrivacyPolicy.xaml" FontSize="{StaticResource PhoneFontSizeNormal}" Margin="10,6" HorizontalAlignment="Left" />
    
                <TextBlock Name="lblStatus" />
                
                <Button Name="btnLow" Content="低精度定位" Click="btnLow_Click" />
                <Button Name="btnHigh" Content="高精度定位" Click="btnHigh_Click" />
                <Button Name="btnClose" Content="关闭定位" Click="btnClose_Click" />
    
                <TextBlock Name="lblMsg" />
                
            </StackPanel>
        </Grid>
    
    </phone:PhoneApplicationPage>

    GpsDemo.xaml.cs

    /*
     * 演示如何使用位置服务(GPS 定位)
     * 
     * GeoCoordinateWatcher - 用于提供地理位置数据
     *     Start() - 启动位置服务
     *     TryStart(bool suppressPermissionPrompt, TimeSpan timeout) - 尝试启动位置服务,返回值为位置服务是否启动成功
     *         suppressPermissionPrompt - 是否禁用权限提示对话框。true为禁用,false为启用
     *         timeout - 启动位置服务的超时时间
     *     Stop() - 停止位置服务
     *     
     *     DesiredAccuracy - 指定提供位置服务的精度级别(System.Device.Location.GeoPositionAccuracy 枚举)
     *         Default - 低精度定位
     *         High - 高精度定位
     *     Permission - 位置提供程序的权限,只读(System.Device.Location.GeoPositionPermission 枚举)
     *         Unknown - 权限未知
     *         Granted - 授予定位权限
     *         Denied - 拒绝定位权限
     *     Status - 位置服务的状态(System.Device.Location.GeoPositionStatus 枚举)
     *         Ready - 已经准备好相关数据
     *         Initializing - 位置提供程序初始化中
     *         NoData - 无有效数据
     *         Disabled - 位置服务不可用
     *     Position - 定位的位置数据,只读(Position.Location 是一个 System.Device.Location.GeoCoordinate 类型的对象)
     *     MovementThreshold - 自上次触发 PositionChanged 事件后,位置移动了此属性指定的距离后再次触发 PositionChanged 事件(单位:米)
     *         此属性默认值为 0,即位置的任何改变都会触发 PositionChanged 事件
     *     
     *     PositionChanged - 经纬度数据发生改变时所触发的事件(系统会根据 MovementThreshold 属性的值来决定何时触发 PositionChanged 事件,当位置服务被打开后第一次得到位置数据时也会触发此事件)
     *     StatusChanged - 位置服务的状态发生改变时所触发的事件
     * 
     * 
     * 
     * GeoCoordinate - 地理坐标
     *     Altitude - 海拔高度(单位:米)
     *     VerticalAccuracy - 海拔高度的精度(单位:米)
     *     Longitude - 经度
     *     Latitude - 纬度
     *     IsUnknown - 是否无经纬度数据。true代表无数据,false代表有数据
     *     HorizontalAccuracy - 经纬度的精度(单位:米)
     *     Course - 行进方向(单位:度,正北为 0 度)
     *     Speed - 行进速度(单位:米/秒)
     */
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;
    
    using System.Device.Location;
    using System.Threading;
    
    namespace Demo.Device
    {
        public partial class GpsDemo : PhoneApplicationPage
        {
            private GeoCoordinateWatcher _watcher;
    
            public GpsDemo()
            {
                InitializeComponent();
    
                _watcher = new GeoCoordinateWatcher();
            }
    
            private void btnLow_Click(object sender, RoutedEventArgs e)
            {
                // 开启低精度位置服务
                StartLocationService(GeoPositionAccuracy.Default);
            }
    
            private void btnHigh_Click(object sender, RoutedEventArgs e)
            {
                // 开启高精度位置服务
                StartLocationService(GeoPositionAccuracy.High);
            }
    
            private void btnClose_Click(object sender, RoutedEventArgs e)
            {
                StopLocationService();
            }
    
            private void StartLocationService(GeoPositionAccuracy accuracy)
            {
                _watcher = new GeoCoordinateWatcher(accuracy);
                // 位置每移动 20 米触发一次 PositionChanged 事件
                _watcher.MovementThreshold = 20; 
    
                _watcher.StatusChanged += new EventHandler<GeoPositionStatusChangedEventArgs>(_watcher_StatusChanged);
                _watcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(_watcher_PositionChanged);
    
                lblStatus.Text = "GPS 服务启动中...";
    
                new Thread((x) =>
                {
                    // 启动 GPS 服务,会阻塞 UI 线程,所以要在后台线程处理
                    if (!_watcher.TryStart(true, TimeSpan.FromSeconds(30)))
                    {
                        Dispatcher.BeginInvoke(delegate
                        {
                            lblStatus.Text = "GPS 服务无法启动";
                        });
                    }
                }).Start();
    
            }
    
            private void StopLocationService()
            {
                if (_watcher != null)
                    _watcher.Stop();
    
                lblStatus.Text = "GPS 服务已关闭";
            }
    
            void _watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
            {
                // 在 UI 上显示经纬度信息
                Dispatcher.BeginInvoke(delegate
                {
                    lblMsg.Text = "经度: " + e.Position.Location.Longitude.ToString("0.000");
                    lblMsg.Text += Environment.NewLine;
                    lblMsg.Text += "纬度: " + e.Position.Location.Latitude.ToString("0.000");
                });
            }
    
            void _watcher_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e)
            {
                // 在 UI 上显示 GPS 服务状态
                Dispatcher.BeginInvoke(delegate
                {
                    switch (e.Status)
                    {
                        case GeoPositionStatus.Disabled:
                            if (_watcher.Permission == GeoPositionPermission.Denied)
                                lblStatus.Text = "GPS 服务拒绝访问";
                            else
                                lblStatus.Text = "GPS 服务不可用";
                            break;
                        case GeoPositionStatus.Initializing:
                            lblStatus.Text = "GPS 服务初始化";
                            break;
                        case GeoPositionStatus.NoData:
                            lblStatus.Text = "GPS 无有效数据";
                            break;
                        case GeoPositionStatus.Ready:
                            lblStatus.Text = "GPS 接收数据中";
                            break;
                    }
                });
            }
        }
    }


    2、演示如何使用 FM 收音机
    FMRadioDemo.xaml

    <phone:PhoneApplicationPage 
        x:Class="Demo.Device.FMRadioDemo"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
        xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        FontFamily="{StaticResource PhoneFontFamilyNormal}"
        FontSize="{StaticResource PhoneFontSizeNormal}"
        Foreground="{StaticResource PhoneForegroundBrush}"
        SupportedOrientations="Portrait" Orientation="Portrait"
        mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
        shell:SystemTray.IsVisible="True">
    
        <Grid x:Name="LayoutRoot" Background="Transparent">
            <StackPanel Orientation="Vertical">
                
                <TextBlock Name="lblStatus" />
                
                <Button Name="btnStart" Content="打开收音机" Click="btnStart_Click" />
                <Button Name="btnClose" Content="关闭收音机" Click="btnClose_Click" />
    
                <TextBlock Name="lblMsg" />
    
            </StackPanel>
        </Grid>
    
    </phone:PhoneApplicationPage>

    FMRadioDemo.xaml.cs

    /*
     * 演示如何使用 FM 收音机
     * 
     * FMRadio - 用于操作 FM 收音机的类
     *     Instance - 返回 FMRadio 实例
     *     CurrentRegion - 收音机的区域信息(Microsoft.Devices.Radio.RadioRegion 枚举)
     *         UnitedStates - 美国
     *         Japan - 日本
     *         Europe - 其他地区
     *     Frequency - 指定 FM 调频的频率
     *     PowerMode - 打开或关闭收音机(Microsoft.Devices.Radio.RadioPowerMode 枚举)
     *         On - 打开收音机
     *         Off - 关闭收音机
     *     SignalStrength - 当前频率的信号强度(RSSI - Received Signal Strength Indication)
     */
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;
    
    using Microsoft.Devices.Radio;
    using System.Windows.Threading;
    using System.Threading;
    
    namespace Demo.Device
    {
        public partial class FMRadioDemo : PhoneApplicationPage
        {
            private FMRadio _radio;
            private DispatcherTimer _timer;
    
            public FMRadioDemo()
            {
                InitializeComponent();
    
                // 实例化 FMRadio,收听 90.5 频率
                _radio = FMRadio.Instance;
                _radio.CurrentRegion = RadioRegion.Europe;
                _radio.Frequency = 90.5;
    
                _timer = new DispatcherTimer();
                _timer.Interval = TimeSpan.FromMilliseconds(100);
                _timer.Tick += new EventHandler(_timer_Tick);
                _timer.Start();
    
                if (_radio.PowerMode == RadioPowerMode.On)
                    lblStatus.Text = "收音机已打开";
                else
                    lblStatus.Text = "收音机已关闭";
            }
    
            void _timer_Tick(object sender, EventArgs e)
            {
                // 实时显示当前频率及信号强度
                lblMsg.Text = "调频:" + _radio.Frequency;
                lblMsg.Text += Environment.NewLine;
                lblMsg.Text += "RSSI:" + _radio.SignalStrength.ToString("0.00");
            }
    
            // 打开收音机
            private void btnStart_Click(object sender, RoutedEventArgs e)
            {
                lblStatus.Text = "收音机打开中。。。";
    
                // 首次启动收音机可能需要多达 3 秒的时间,以后再启动收音机则会在 100 毫秒以内,所以建议在后台线程打开收音机
                new Thread((x) =>
                {
                    _radio.PowerMode = RadioPowerMode.On;
                    Dispatcher.BeginInvoke(delegate
                    {
                        lblStatus.Text = "收音机已打开";
                    });
                }).Start();
            }
    
            // 关闭收音机
            private void btnClose_Click(object sender, RoutedEventArgs e)
            {
                _radio.PowerMode = RadioPowerMode.Off;
                lblStatus.Text = "收音机已关闭";
            }
        }
    }


    3、演示如何使用麦克风
    MicrophoneDemo.xaml

    <phone:PhoneApplicationPage 
        x:Class="Demo.Device.MicrophoneDemo"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
        xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        FontFamily="{StaticResource PhoneFontFamilyNormal}"
        FontSize="{StaticResource PhoneFontSizeNormal}"
        Foreground="{StaticResource PhoneForegroundBrush}"
        SupportedOrientations="Portrait" Orientation="Portrait"
        mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
        shell:SystemTray.IsVisible="True">
    
        <Grid x:Name="LayoutRoot" Background="Transparent">
            <StackPanel Orientation="Vertical">
    
                <TextBlock Name="lblMsg" />
                
                <Button Name="btnRecord" Content="录音" Click="btnRecord_Click" />
                <Button Name="btnPlay" Content="播放" Click="btnPlay_Click" />
                <Button Name="btnStop" Content="停止" Click="btnStop_Click" />
    
            </StackPanel>
        </Grid>
    
    </phone:PhoneApplicationPage>

    MicrophoneDemo.xaml.cs

    /*
     * 演示如何使用麦克风进行录音
     * 
     * Microphone - 用于捕获麦克风音频的类
     *     Default - 返回默认的 Microphone 实例
     *     All - 返回设备的全部 Microphone 实例集合
     *     SampleRate - 获取音频的采样率
     *     State - Microphone 的状态(Microsoft.Xna.Framework.Audio.MicrophoneState 枚举)
     *         Started - 正在捕获音频
     *         Stopped - 已经停止工作
     *     BufferDuration - 麦克风捕获音频时的缓冲时长
     *     
     *     BufferReady - 当麦克风捕获的音频时长达到 BufferDuration 设置的值后所触发的事件
     *     
     *     GetData(byte[] buffer) - 将麦克风最近捕获到的音频数据写入到指定的缓冲区
     *     GetSampleSizeInBytes(TimeSpan duration) - 麦克风捕获音频,根据音频时长返回音频字节数
     *     GetSampleDuration(int sizeInBytes) - 麦克风捕获音频,根据音频字节数返回音频时长
     *     Start() - 开始捕获
     *     Stop() - 停止捕获
     */
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;
    
    using Microsoft.Xna.Framework.Audio;
    using System.IO;
    using System.Threading;
    using Microsoft.Xna.Framework;
    
    namespace Demo.Device
    {
        public partial class MicrophoneDemo : PhoneApplicationPage
        {
            // silverlight 和 xna 混合编程时,所需要用到的计时器
            private GameTimer _timer;
    
            private Microphone _microphone = Microphone.Default;
            private SoundEffectInstance _soundInstance; // 用于播放音频数据
            private byte[] _buffer; // 每一片录音数据的缓冲区
            private MemoryStream _stream = new MemoryStream(); // 整个录音数据的内存流
    
            public MicrophoneDemo()
            {
                InitializeComponent();
    
                _timer = new GameTimer();
                // 指定计时器每 1/30 秒执行一次,即帧率为 30 fps
                _timer.UpdateInterval = TimeSpan.FromTicks(333333);
                // 每次帧更新时所触发的事件
                _timer.FrameAction += FrameworkDispatcherFrameAction;
                _timer.Start();
    
                _microphone.BufferReady += new EventHandler<EventArgs>(_microphone_BufferReady);
            }
    
            private void FrameworkDispatcherFrameAction(object sender, EventArgs e)
            {
                // 当使用 silverlight 和 xna 混合编程时,每次帧更新时都需要调用 FrameworkDispatcher.Update()
                FrameworkDispatcher.Update();
            }
    
            void _microphone_BufferReady(object sender, EventArgs e)
            {
                // 当录音的缓冲被填满后,将数据写入缓冲区
                _microphone.GetData(_buffer);
                // 将缓冲区中的数据写入内存流
                _stream.Write(_buffer, 0, _buffer.Length);
            }
    
            private void btnRecord_Click(object sender, RoutedEventArgs e)
            {
                if (lblMsg.Text != "录音中")
                {
                    // 设置录音的缓冲时长为 0.5 秒
                    _microphone.BufferDuration = TimeSpan.FromMilliseconds(500);
                    // 设置录音用的缓冲区的大小
                    _buffer = new byte[_microphone.GetSampleSizeInBytes(_microphone.BufferDuration)];
                    // 初始化内存流
                    _stream.SetLength(0);
    
                    _microphone.Start();
    
                    lblMsg.Text = "录音中";
                }
            }
    
            private void btnPlay_Click(object sender, RoutedEventArgs e)
            {
                if (_stream.Length > 0)
                {
                    // 播放录音
                    Thread soundThread = new Thread(new ThreadStart(playSound));
                    soundThread.Start();
    
                    lblMsg.Text = "播放录音";
                }
            }
    
            private void btnStop_Click(object sender, RoutedEventArgs e)
            {
                if (_microphone.State == MicrophoneState.Started)
                {
                    // 停止录音
                    _microphone.Stop();
    
                    lblMsg.Text = "停止录音";
                }
                else if (_soundInstance.State == SoundState.Playing)
                {
                    // 停止播放录音
                    _soundInstance.Stop();
    
                    lblMsg.Text = "停止播放录音";
                }
            }
    
            private void playSound()
            {
                // 播放内存流中的音频
                SoundEffect sound = new SoundEffect(_stream.ToArray(), _microphone.SampleRate, AudioChannels.Mono);
                _soundInstance = sound.CreateInstance();
                _soundInstance.Play();
            }
        }
    }


    4、演示如何使用震动器
    VibrationDemo.xaml

    <phone:PhoneApplicationPage 
        x:Class="Demo.Device.VibrationDemo"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
        xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        FontFamily="{StaticResource PhoneFontFamilyNormal}"
        FontSize="{StaticResource PhoneFontSizeNormal}"
        Foreground="{StaticResource PhoneForegroundBrush}"
        SupportedOrientations="Portrait" Orientation="Portrait"
        mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
        shell:SystemTray.IsVisible="True">
    
        <Grid x:Name="LayoutRoot" Background="Transparent">
            <StackPanel Orientation="Vertical">
                
                <Button Name="btnStart" Content="开始震动" Click="btnStart_Click" />
                
                <Button Name="btnStop" Content="停止震动" Click="btnStop_Click" />
                
            </StackPanel>
        </Grid>
     
    </phone:PhoneApplicationPage>

    VibrationDemo.xaml.cs

    /*
     * 演示如何使用震动器
     * 
     * VibrateController - 用于控制震动器
     *     Default - 获取 VibrateController 实例
     *     Start(TimeSpan duration) - 指定震动时长,并使设备震动。有效时长在 0 - 5 秒之间,否则会抛出异常
     *     Stop() - 停止设备的震动
     */
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;
    
    using Microsoft.Devices;
    
    namespace Demo.Device
    {
        public partial class VibrationDemo : PhoneApplicationPage
        {
            public VibrationDemo()
            {
                InitializeComponent();
            }
    
            private void btnStart_Click(object sender, RoutedEventArgs e)
            {
                // 震动 5 秒
                VibrateController.Default.Start(TimeSpan.FromMilliseconds(5 * 1000));
            }
    
            private void btnStop_Click(object sender, RoutedEventArgs e)
            {
                // 停止震动
                VibrateController.Default.Stop();
            }
        }
    }



    OK
    [源码下载]

  • 相关阅读:
    node.js爬虫杭州房产销售及数据可视化
    webpack1.x 升级到 webpack2.x 英文文档翻译
    一机双屏和双屏通信方案总结
    Linux 利用hosts.deny 防止暴力破解ssh
    Linux 之rsyslog+LogAnalyzer 日志收集系统
    count和distinct
    排序算法 — 冒泡排序
    排序算法 — 插入排序
    排序算法 — 选择排序
    CRLF will be replaced by LF in XXX when git commit
  • 原文地址:https://www.cnblogs.com/webabcd/p/2629636.html
Copyright © 2020-2023  润新知