gps 获取方法

 public delegate void LocationChangedEventHandler(object sender, LocationChangedEventArgs args);
    public delegate void DeviceStateChangedEventHandler(object sender, DeviceStateChangedEventArgs args);

    /// <summary>
    /// Summary description for GPS.
    /// </summary>
    public class Gps
    {
        // handle to the gps device
        IntPtr gpsHandle = IntPtr.Zero;

        // handle to the native event that is signalled when the GPS
        // devices gets a new location
        IntPtr newLocationHandle = IntPtr.Zero;

        // handle to the native event that is signalled when the GPS
        // device state changes
        IntPtr deviceStateChangedHandle = IntPtr.Zero;

        // handle to the native event that we use to stop our event
        // thread
        IntPtr stopHandle = IntPtr.Zero;

        // holds our event thread instance
        System.Threading.Thread gpsEventThread = null;


        event LocationChangedEventHandler locationChanged;

        /// <summary>
        /// Event that is raised when the GPS locaction data changes
        /// </summary>
        public event LocationChangedEventHandler LocationChanged
        {
            add
            {
                locationChanged += value;

                // create our event thread only if the user decides to listen
                CreateGpsEventThread();
            }
            remove
            {
                locationChanged -= value;
            }
        }


        event DeviceStateChangedEventHandler deviceStateChanged;

        /// <summary>
        /// Event that is raised when the GPS device state changes
        /// </summary>
        public event DeviceStateChangedEventHandler DeviceStateChanged
        {
            add
            {
                deviceStateChanged += value;

                // create our event thread only if the user decides to listen
                CreateGpsEventThread();
            }
            remove
            {
                deviceStateChanged -= value;
            }
        }

        /// <summary>
        /// True: The GPS device has been opened. False: It has not been opened
        /// </summary>
        public bool Opened
        {
            get { return gpsHandle != IntPtr.Zero; }
        }

        public Gps()
        {
        }

        ~Gps()
        {
            // make sure that the GPS was closed.
            Close();
        }

        /// <summary>
        /// Opens the GPS device and prepares to receive data from it.
        /// </summary>
        public void Open()
        {
            if (!Opened)
            {
                // create handles for GPS events
                newLocationHandle = CreateEvent(IntPtr.Zero, 0, 0, null);
                deviceStateChangedHandle = CreateEvent(IntPtr.Zero, 0, 0, null);
                stopHandle = CreateEvent(IntPtr.Zero, 0, 0, null);

                gpsHandle = GPSOpenDevice(newLocationHandle, deviceStateChangedHandle, null, 0);

                // if events were hooked up before the device was opened, we'll need
                // to create the gps event thread.
                if (locationChanged != null || deviceStateChanged != null)
                {
                    CreateGpsEventThread();
                }
            }
        }

        /// <summary>
        /// Closes the gps device.
        /// </summary>
        public void Close()
        {
            if (gpsHandle != IntPtr.Zero)
            {
                GPSCloseDevice(gpsHandle);
                gpsHandle = IntPtr.Zero;
            }

            // Set our native stop event so we can exit our event thread.
            if (stopHandle != IntPtr.Zero)
            {
                EventModify(stopHandle, eventSet);
            }

            // block until our event thread is finished before
            // we close our native event handles
            lock (this)
            {
                if (newLocationHandle != IntPtr.Zero)
                {
                    CloseHandle(newLocationHandle);
                    newLocationHandle = IntPtr.Zero;
                }

                if (deviceStateChangedHandle != IntPtr.Zero)
                {
                    CloseHandle(deviceStateChangedHandle);
                    deviceStateChangedHandle = IntPtr.Zero;
                }

                if (stopHandle != IntPtr.Zero)
                {
                    CloseHandle(stopHandle);
                    stopHandle = IntPtr.Zero;
                }
            }
        }

        /// <summary>
        /// Get the position reported by the GPS receiver
        /// </summary>
        /// <returns>GpsPosition class with all the position details</returns>
        public GpsPosition GetPosition()
        {
            return GetPosition(TimeSpan.Zero);
        }


        /// <summary>
        /// Get the position reported by the GPS receiver that is no older than
        /// the maxAge passed in
        /// </summary>
        /// <param name="maxAge">Max age of the gps position data that you want back.
        /// If there is no data within the required age, null is returned. 
        /// if maxAge == TimeSpan.Zero, then the age of the data is ignored</param>
        /// <returns>GpsPosition class with all the position details</returns>
        public GpsPosition GetPosition(TimeSpan maxAge)
        {
            GpsPosition gpsPosition = null;
            if (Opened)
            {
                // allocate the necessary memory on the native side.  We have a class (GpsPosition) that
                // has the same memory layout as its native counterpart
                IntPtr ptr = Utils.LocalAlloc(Marshal.SizeOf(typeof(GpsPosition)));

                // fill in the required fields
                gpsPosition = new GpsPosition();
                gpsPosition.dwVersion = 1;
                gpsPosition.dwSize = Marshal.SizeOf(typeof(GpsPosition));

                // Marshal our data to the native pointer we allocated.
                Marshal.StructureToPtr(gpsPosition, ptr, false);

                // call native method passing in our native buffer
                int result = GPSGetPosition(gpsHandle, ptr, 500000, 0);
                if (result == 0)
                {
                    // native call succeeded, marshal native data to our managed data
                    gpsPosition = (GpsPosition)Marshal.PtrToStructure(ptr, typeof(GpsPosition));

                    if (maxAge != TimeSpan.Zero)
                    {
                        // check to see if the data is recent enough.
                        if (!gpsPosition.TimeValid || DateTime.Now - maxAge > gpsPosition.Time)
                        {
                            gpsPosition = null;
                        }
                    }
                }

                // free our native memory
                Utils.LocalFree(ptr);
            }

            return gpsPosition;           
        }

        /// <summary>
        /// Queries the device state.
        /// </summary>
        /// <returns>Device state information</returns>
        public GpsDeviceState GetDeviceState()
        {
            GpsDeviceState device = null;

            // allocate a buffer on the native side.  Since the
            IntPtr pGpsDevice = Utils.LocalAlloc(GpsDeviceState.GpsDeviceStructureSize);
           
            // GPS_DEVICE structure has arrays of characters, it's easier to just
            // write directly into memory rather than create a managed structure with
            // the same layout.
            Marshal.WriteInt32(pGpsDevice, 1); // write out GPS version of 1
            Marshal.WriteInt32(pGpsDevice, 4, GpsDeviceState.GpsDeviceStructureSize); // write out dwSize of structure

            int result = GPSGetDeviceState(pGpsDevice);

            if (result == 0)
            {
                // instantiate the GpsDeviceState class passing in the native pointer
                device = new GpsDeviceState(pGpsDevice);
            }

            // free our native memory
            Utils.LocalFree(pGpsDevice);

            return device;
        }

        /// <summary>
        /// Creates our event thread that will receive native events
        /// </summary>
        private void CreateGpsEventThread()
        {
            // we only want to create the thread if we don't have one created already
            // and we have opened the gps device
            if (gpsEventThread == null && gpsHandle != IntPtr.Zero)
            {
                // Create and start thread to listen for GPS events
                gpsEventThread = new System.Threading.Thread(new System.Threading.ThreadStart(WaitForGpsEvents));
                gpsEventThread.Start();
            }
        }

        /// <summary>
        /// Method used to listen for native events from the GPS.
        /// </summary>
        private void WaitForGpsEvents()
        {
            lock (this)
            {
                bool listening = true;
                // allocate 3 handles worth of memory to pass to WaitForMultipleObjects
                IntPtr handles = Utils.LocalAlloc(12);

                // write the three handles we are listening for.
                Marshal.WriteInt32(handles, 0, stopHandle.ToInt32());
                Marshal.WriteInt32(handles, 4, deviceStateChangedHandle.ToInt32());
                Marshal.WriteInt32(handles, 8, newLocationHandle.ToInt32());

                while (listening)
                {
                    int obj = WaitForMultipleObjects(3, handles, 0, -1);
                    if (obj != waitFailed)
                    {
                        switch (obj)
                        {
                            case 0:
                                // we've been signalled to stop
                                listening = false;
                                break;
                            case 1:
                                // device state has changed
                                if (deviceStateChanged != null)
                                {
                                    deviceStateChanged(this, new DeviceStateChangedEventArgs(GetDeviceState()));
                                }
                                break;
                            case 2:
                                // location has changed
                                if (locationChanged != null)
                                {
                                    locationChanged(this, new LocationChangedEventArgs(GetPosition()));
                                }
                                break;
                        }
                    }
                }

                // free the memory we allocated for the native handles
                Utils.LocalFree(handles);

                // clear our gpsEventThread so that we can recreate this thread again
                // if the events are hooked up again.
                gpsEventThread = null;
            }
        }

        #region PInvokes to gpsapi.dll
        [DllImport("gpsapi.dll")]
        static extern IntPtr GPSOpenDevice(IntPtr hNewLocationData, IntPtr hDeviceStateChange, string szDeviceName, int dwFlags);

        [DllImport("gpsapi.dll")]
        static extern int  GPSCloseDevice(IntPtr hGPSDevice);

        [DllImport("gpsapi.dll")]
        static extern int  GPSGetPosition(IntPtr hGPSDevice, IntPtr pGPSPosition, int dwMaximumAge, int dwFlags);

        [DllImport("gpsapi.dll")]
        static extern int  GPSGetDeviceState(IntPtr pGPSDevice);
        #endregion

        #region PInvokes to coredll.dll
        [DllImport("coredll.dll")]
        static extern IntPtr CreateEvent(IntPtr lpEventAttributes, int bManualReset, int bInitialState, StringBuilder lpName);

        [DllImport("coredll.dll")]
        static extern int CloseHandle(IntPtr hObject);

        const int waitFailed = -1;
        [DllImport("coredll.dll")]
        static extern int WaitForMultipleObjects(int nCount, IntPtr lpHandles, int fWaitAll, int dwMilliseconds);

        const int eventSet = 3;

       //www.window2018.com//

        [DllImport("coredll.dll")]
        static extern int EventModify(IntPtr hHandle, int dwFunc);
       
#endregion

 

转载于:https://www.cnblogs.com/window2018/archive/2010/04/14/1712123.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值