2

2008 年から 2009 年にかけて、 Windows モバイル 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 に答える