public GeoLocationProvider(GeoLocationAccuracy desiredAccuracy) { m_desiredAccuracy = desiredAccuracy; m_provider = new GeoLocationProviderInternal(desiredAccuracy); if (SynchronizationContext.Current == null) { // // Create a SynchronizationContext if there isn't one on calling thread // m_synchronizationContext = new SynchronizationContext(); } else { m_synchronizationContext = SynchronizationContext.Current; } m_provider.StatusChanged += new EventHandler <GeoLocationStatusChangedEventArgs>(OnInternalStatusChanged); }
// <summary> // Creates an instance of GeoLocationProviderInternal with the specified desired accuracy // </summary> public GeoLocationProviderInternal(GeoLocationAccuracy desiredAccuracy) { // // Create the native location object on a worker thread, so that it exists // in a multithreaded apartment. // m_eventCreateDone = new ManualResetEvent(false); ThreadPool.QueueUserWorkItem(new WaitCallback(this.CreateHandler), desiredAccuracy); #if _DEBUG m_eventCreateDone.WaitOne(5000); #else m_eventCreateDone.WaitOne(500); #endif Utility.Trace("GeoLocationProviderInternal.ctor: " + "desiredAccuracy: " + desiredAccuracy.ToString() + " m_latLongRegistered: " + m_latLongRegistered.ToString() + " m_civicAddrRegistered: " + m_civicAddrRegistered.ToString() + " m_latLongStatus: " + m_latLongStatus.ToString() + " m_curStatus: " + m_curStatus.ToString()); }
/// <summary> /// Thread pool callback used to ensure location COM API is instantiated from /// multi-thread apartment, and register for location events. /// </summary> /// <param name="state"></param> private void CreateHandler(object state) { lock (this.InternalSyncObject) { try { m_location = new COMLocation(); } catch (COMException) { Utility.Trace("Failed to CoCreate ILocation COM object."); } if (null != m_location) { Utility.Trace("Done creating ILocation COM object"); // // Mapping to platform accuracy // GeoLocationAccuracy desiredAccuracy = (GeoLocationAccuracy)state; DesiredAccuracy accuracy = (desiredAccuracy == GeoLocationAccuracy.Low) ? DesiredAccuracy.DefaultAccuracy : DesiredAccuracy.HighAccuracy; Guid reportKey = LocationReportKey.LatLongReport; m_location.SetDesiredAccuracy(ref reportKey, accuracy); // // Always listen for latlong reports // if (m_location.RegisterForReport(this, ref reportKey, 0) == 0) { m_latLongRegistered = true; } // // Check the latlong status. If latlong reports are not supported, then register // for civic address reports. // m_location.GetReportStatus(ref reportKey, ref m_latLongStatus); if (ReportStatus.NotSupported == m_latLongStatus) { reportKey = LocationReportKey.CivicAddressReport; if (m_location.RegisterForReport(this, ref reportKey, 0) == 0) { m_civicAddrRegistered = true; m_location.GetReportStatus(ref reportKey, ref m_civicAddrStatus); } } // // set the current status to the available report type status // ReportStatus status = (ReportStatus.NotSupported != m_latLongStatus) ? m_latLongStatus : m_civicAddrStatus; m_curStatus = m_geoStatusMap[(int)status]; } Utility.DebugAssert(m_eventCreateDone != null, "m_eventCreateDone is null"); ManualResetEvent eventDone = m_eventCreateDone; if (eventDone != null) { eventDone.Set(); } } }