【问题标题】:WP7 Mock Microsoft.Devices.Sensors.Compass when using the emulatorWP7 Mock Microsoft.Devices.Sensors.Compass 使用模拟器时
【发布时间】:2012-02-25 03:15:43
【问题描述】:

我希望能够在模拟器中运行 Windows Phone 7.1 时模拟指南针传感器。

在这个阶段,我并不特别关心指南针返回什么数据。只是我在使用模拟器测试有问题的代码时可以运行一些东西。

我知道我可以部署到我的未锁定开发手机来测试指南针功能,但我发现通过 Zune 软件的连接经常断开。

更新

我已经研究过创建自己的包装类,该类可以在运行调试构建时模拟指南针,并且不支持指南针。

Microsoft.Devices.Sensors.CompassReading struct 让我有点难过。因为它是一个只能在内部设置属性的结构,所以我不能从它继承来提供我自己的值。我看了using reflection to brute force some values inSilverlight doesn't appear to allow it

【问题讨论】:

标签: windows-phone-7 windows-phone-7.1


【解决方案1】:

正如您已经注意到的那样,我遇到了类似的问题。当我嘲笑罗盘传感器时,我也遇到了困难,因为你不能从现有的类继承并编写自己的逻辑。因此,我编写了自己的指南针接口,这是我的应用程序使用的唯一指南针功能。然后有两种实现,一种是 WP7 指南针功能的包装器,另一种是我的模拟指南针。

我可以给你看一些代码,但不能在周末之前,因为我不在我的开发机器上。

编辑:

您已经知道了,但是对于遇到相同问题的其他人,我将添加我的代码。正如我已经说过的,我编写了一个接口和两个实现,一个用于电话和一个模拟实现。

指南针界面

public interface ICompass
{
    #region Methods

    void Start();

    void Stop();

    #endregion

    #region Properties

    CompassData CurrentValue { get; }

    bool IsDataValid { get; }

    TimeSpan TimeBetweenUpdates { get; set; }

    #endregion

    #region Events

    event EventHandler<CalibrationEventArgs> Calibrate;

    event EventHandler<CompassDataChangedEventArgs> CurrentValueChanged;

    #endregion
}

使用的数据类和事件参数

public class CompassData
{
    public CompassData(double headingAccurancy, double magneticHeading, Vector3 magnetometerReading, DateTimeOffset timestamp, double trueHeading)
    {
        HeadingAccuracy = headingAccurancy;
        MagneticHeading = magneticHeading;
        MagnetometerReading = magnetometerReading;
        Timestamp = timestamp;
        TrueHeading = trueHeading;
    }

    public CompassData(CompassReading compassReading)
    {
        HeadingAccuracy = compassReading.HeadingAccuracy;
        MagneticHeading = compassReading.MagneticHeading;
        MagnetometerReading = compassReading.MagnetometerReading;
        Timestamp = compassReading.Timestamp;
        TrueHeading = compassReading.TrueHeading;
    }

    #region Properties

    public double HeadingAccuracy { get; private set; }

    public double MagneticHeading { get; private set; }

    public Vector3 MagnetometerReading { get; private set; }

    public DateTimeOffset Timestamp { get; private set; }

    public double TrueHeading { get; private set; }

    #endregion
}

public class CompassDataChangedEventArgs : EventArgs
{
    public CompassDataChangedEventArgs(CompassData compassData)
    {
        CompassData = compassData;
    }

    public CompassData CompassData { get; private set; }
}

WP7 实施

public class DeviceCompass : ICompass
{
    private Compass _compass;

    #region Implementation of ICompass

    public void Start()
    {
        if(_compass == null)
        {
            _compass = new Compass {TimeBetweenUpdates = TimeBetweenUpdates};
            // get TimeBetweenUpdates because the device could have change it to another value
            TimeBetweenUpdates = _compass.TimeBetweenUpdates;
            // attach to events
            _compass.CurrentValueChanged += CompassCurrentValueChanged;
            _compass.Calibrate += CompassCalibrate;
        }
        _compass.Start();
    }

    public void Stop()
    {
        if(_compass != null)
        {
            _compass.Stop();
        }
    }

    public CompassData CurrentValue
    {
        get { return _compass != null ? new CompassData(_compass.CurrentValue) : default(CompassData); }
    }

    public bool IsDataValid
    {
        get { return _compass != null ? _compass.IsDataValid : false; }
    }

    public TimeSpan TimeBetweenUpdates { get; set; }

    public event EventHandler<CalibrationEventArgs> Calibrate;
    public event EventHandler<CompassDataChangedEventArgs> CurrentValueChanged;

    #endregion

    #region Private methods

    private void CompassCalibrate(object sender, CalibrationEventArgs e)
    {
        EventHandler<CalibrationEventArgs> calibrate = Calibrate;
        if (calibrate != null)
        {
            calibrate(sender, e);
        }
    }

    private void CompassCurrentValueChanged(object sender, SensorReadingEventArgs<CompassReading> e)
    {
        EventHandler<CompassDataChangedEventArgs> currentValueChanged = CurrentValueChanged;
        if (currentValueChanged != null)
        {
            currentValueChanged(sender, new CompassDataChangedEventArgs(new CompassData(e.SensorReading)));
        }
    }

    #endregion
}

模拟实现

public class MockCompass : ICompass
{
    private readonly Timer _timer;
    private CompassData _currentValue;
    private bool _isDataValid;
    private TimeSpan _timeBetweenUpdates;
    private bool _isStarted;
    private readonly Random _random;

    public MockCompass()
    {
        _random = new Random();
        _timer = new Timer(TimerEllapsed, null, Timeout.Infinite, Timeout.Infinite);
        _timeBetweenUpdates = new TimeSpan();
        _currentValue = new CompassData(0, 0, new Vector3(), new DateTimeOffset(), 0);
    }

    #region Implementation of ICompass

    public void Start()
    {
        _timer.Change(0, (int)TimeBetweenUpdates.TotalMilliseconds);
        _isStarted = true;
    }

    public void Stop()
    {
        _isStarted = false;
        _timer.Change(Timeout.Infinite, Timeout.Infinite);
        _isDataValid = false;
    }

    public CompassData CurrentValue
    {
        get { return _currentValue; }
    }

    public bool IsDataValid
    {
        get { return _isDataValid; }
    }

    public TimeSpan TimeBetweenUpdates
    {
        get { return _timeBetweenUpdates; }
        set
        {
            _timeBetweenUpdates = value;
            if (_isStarted)
            {
                _timer.Change(0, (int) TimeBetweenUpdates.TotalMilliseconds);
            }
        }
    }

    public event EventHandler<CalibrationEventArgs> Calibrate;
    public event EventHandler<CompassDataChangedEventArgs> CurrentValueChanged;

    #endregion

    #region Private methods

    private void TimerEllapsed(object state)
    {
        _currentValue = new CompassData(_random.NextDouble()*5,
                                        (_currentValue.MagneticHeading + 0.1)%360,
                                        _currentValue.MagnetometerReading,
                                        new DateTimeOffset(DateTime.UtcNow),
                                        (_currentValue.TrueHeading + 0.1)%360);
        _isDataValid = true;
        EventHandler<CompassDataChangedEventArgs> currentValueChanged = CurrentValueChanged;
        if(currentValueChanged != null)
        {
            currentValueChanged(this, new CompassDataChangedEventArgs(_currentValue));
        }
    }

    #endregion

}

【讨论】:

  • 这也是我得出的结论,谢谢。我已经创建了自己的接口来使用代码。当在调试模式下运行时不支持指南针,我返回了我的 Mock Compass 类的实例。否则我提供一个连接到真实指南针的实例。
  • 我为可能有同样问题的其他人添加了我的代码。
猜你喜欢
  • 2011-07-14
  • 2011-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-05
  • 1970-01-01
  • 1970-01-01
  • 2011-12-17
相关资源
最近更新 更多