2012-02-21 224 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