2012-02-21 269 views
1

我希望在模拟器中运行Windows Phone 7.1时能够模拟指南针传感器。WP7使用模拟器模拟Microsoft.Devices.Sensors.Compass

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

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

更新

我看着创造我自己的包装类运行调试版本,不支持其它指南针时,可以模拟指南针。

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

+0

相关:http://stackoverflow.com/questions/7629453/wp7-convert-accelometer-and-compass-data-to-mock-motion-api – 2012-02-21 02:18:17

回答

2

你已经注意到我有类似的问题。当我嘲笑指南针传感器时,我也遇到了困难,因为您无法从现有类继承并编写自己的逻辑。因此,我编写了自己的指南针界面,这是我的应用程序使用的唯一指南针功能。然后有两个实现,WP7指南针功能和我的模拟指南针的一个包装。

我可以告诉你一些代码,但不是在周末之前,因为我不在我的发明机器atm。

编辑:

你已经得到它但谁有同样的问题其他人我要添加代码。正如我已经说过的,我编写了一个接口和两个实现,一个用于电话和一个模拟实现。

指南针接口

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 

} 
+1

这就是结论,我也来,以及,谢谢。我创建了自己的接口来处理代码。在调试模式下运行时指针不受支持我已经返回了我的模拟指南针类的实例。否则,我提供一个连接到真正指南针的实例。 – 2012-02-23 08:26:26

+0

我为其他可能有同样问题的人添加了我的代码。 – MatthiasG 2012-02-24 19:09:28