2

我在 2008-2009 年为Windows mobile 6.1创建了一个GPS 程序,可以在后台实时跟踪位置。多年来,它在这些设备上运行良好。出于某种原因,相同的代码从未在Windows Mobile 6.5上完美运行。

经过数小时的操作(主要是在没有人使用设备的情况下),我从函数“WaitForMultipleObjects”收到“超时”(代码 258):

this.GPSEvent_WaitValue = WaitForMultipleObjects(2, this.GPSEvent_Handles, 0, 45000);

同样,这可以工作几个小时,突然之间,如果没有:更新: - 重新启动设备(GoogleMap 确认没有 GPS 设备存在!)就不可能获得另一个位置 !

它与 Windows Mobile 进入睡眠状态和减慢我的线程有关。

这是核心代码(改编自 Microsoft SDK 示例):

/// <summary>
/// When "WindowsMobile" wake up the program to check for a new position
/// </summary>
private void OnNextGPSEvent_Callback()
{
  int SecondsToNextWakeUp = ETL.Mobile.Device.ScheduledCallback.MINIMUM_SECONDTONEXTWAKEUP;

  switch (this.SleepingState)
  {
    case SleepingStateType.SleepingForNextPosition:
      // Get position
      this.GPSEvent_WaitValue = (WaitForEventThreadResultType)WaitForMultipleObjects(2, this.GPSEvent_Handles, 0, 45000);

      switch (this.GPSEvent_WaitValue)
      {
        case WaitForEventThreadResultType.Event_LocationChanged:
          // Got a new position
          this.FireLocationChanged(this.GetCurrentPosition());

          // Manage device shutdown (save battery)
          if (this.PositionFrequency > MIN_SECONDS_FREQUENCY_FORDEVICE_SHUTDOWN)
          {
            // Close device
            this.CloseDevice();
            SecondsToNextWakeUp = (this.PositionFrequency - GPSDEVICE_LOAD_SECONDS_LOAD_TIME);
            this.SleepingState = SleepingStateType.SleepingBeforeDeviceWakeUp;
          }
          else
          {
            // Default Wait Time
            this.SleepingState = SleepingStateType.SleepingForNextPosition;
          }

          break;

        case WaitForEventThreadResultType.Event_StateChanged:
          break;

        case WaitForEventThreadResultType.Timeout:
        case WaitForEventThreadResultType.Failed:
        case WaitForEventThreadResultType.Stop:
          // >>>>>>>>>>>>>> This is where the error happens <<<<<<<<<<<<<<<<<<<<<<<<<<<
          // >>>>>>>>>>>>>> This is where the error happens <<<<<<<<<<<<<<<<<<<<<<<<<<<
          // >>>>>>>>>>>>>> This is where the error happens <<<<<<<<<<<<<<<<<<<<<<<<<<<

          // Too many errors
          this.ConsecutiveErrorReadingDevice++;
          if (this.ConsecutiveErrorReadingDevice > MAX_ERRORREADINGDEVICE)
          {
            this.CloseDevice();

            SecondsToNextWakeUp = (this.PositionFrequency - GPSDEVICE_LOAD_SECONDS_LOAD_TIME);
            this.SleepingState = SleepingStateType.SleepingBeforeDeviceWakeUp;
          }
          else
          {
            // Default Wait Time
            this.SleepingState = SleepingStateType.SleepingForNextPosition;
          }

          break;
      }
      #endregion
      break;

    case SleepingStateType.SleepingBeforeDeviceWakeUp:
      this.OpenDevice();

      SecondsToNextWakeUp = GPSDEVICE_LOAD_SECONDS_LOAD_TIME;
      this.SleepingState = SleepingStateType.SleepingForNextPosition;
      break;
  }

  if (this.IsListeningGPSEvent)
  {
    // Ajustement du prochain rappel
    this.NextGPSEvent_Callback.SecondToNextWakeUp = SecondsToNextWakeUp;
    this.NextGPSEvent_Callback.RequestWakeUpCallback();
  }
}
/// <summary>
///Create Thread
/// </summary>
private void StartListeningThreadForGPSEvent()
{
  // We only want to create the thread if we don't have one created already and we have opened the gps device
  if (this._GPSEventThread == null)
  {
    // Create and start thread to listen for GPS events
    this._GPSEventThread = new System.Threading.Thread(new System.Threading.ThreadStart(this.ListeningThreadForGPSEvent));
    this._GPSEventThread.Start();
  }
}
private void ListeningThreadForGPSEvent()
{
  this.GPSEvent_WaitValue = WaitForEventThreadResultType.Stop;
  this.IsListeningGPSEvent = true;

  // Allocate handles worth of memory to pass to WaitForMultipleObjects
  this.GPSEvent_Handles = Helpers.LocalAlloc(12);
  Marshal.WriteInt32(this.GPSEvent_Handles, 0, this._StopHandle.ToInt32());
  Marshal.WriteInt32(this.GPSEvent_Handles, 4, this._NewLocationHandle.ToInt32());
  Marshal.WriteInt32(this.GPSEvent_Handles, 8, this._GPSDeviceStateChanged.ToInt32());

  this.Start_NextGPSEvent_Timer(this.PositionFrequency);
  this.SleepingState = SleepingStateType.SleepingBeforeDeviceWakeUp;
  this.OnNextGPSEvent_Callback();
}
4

1 回答 1

0

Windows Mobile 5/6 SDK 中包含的 C# GPS 示例是否有同样的问题?如果是这样,那么这可能是驱动程序问题,您需要与硬件制造商或 OEM 联系。

您可以通过轮询 GPS 驱动程序而不是依赖中间驱动程序接口的位置更改回调来缓解此问题。

没有重置 GPS 硬件的标准方法。GPS 在有程序使用时“开启”,而在没有程序使用时“关闭”(或处于非常低功耗模式)。如果您的 GPS 在 WWAN 芯片上,您可以通过关闭和打开 WWAN 调制解调器来重置它。或者,一些 GPS 芯片接受 ASCII 或二进制串行命令来重置 GPS 本身,但这些是特定于芯片组的。您需要与您的 GPS 芯片组制造商核实这些代码。

您的 GPSID 重置代码(我假设来自此处)与强制所有 GPSID 客户端断开连接使 GPS 处于低功耗状态相同,但实际上可能不会重置硬件。

于 2012-04-22T15:06:34.897 回答