Example #1
0
        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();
                }
            }
        }