微軟手機的 GPS 程式設計

作品

書籍

課程

程式集

小說集

論文集

散文集

影片集

編輯雜誌

程式人

電子書

JavaScript

計算語言學

微積分

Blender 動畫

C# 語言

系統程式

高等 C 語言

Java

Android

Verilog

Wikidot

R 統計軟體

機率統計

計算機數學

組合語言

人工智慧

開放原始碼

網路資源運用

計算機結構

相關訊息

常用工具

友站連結

在家教育

RSS

最新修改

網頁列表

簡體版

English

專案程式下載:MsGpsSample.zip

說明

要撰寫微軟手機的衛星定位程式,最簡單的方式是參考其 Code Samples for Windows Mobile 範例程式集,這個範例程式集包含了許多有用的 Windows Mobile 6 的範例程式,像是相機、電話、藍芽、簡訊、Direct3D 繪圖、Direct Show 多媒體等範例程式,是學習 Windows Mobile 手機程式設計者的重要資源。

在這個範例程式集當中,包含了一個由 C# 撰寫的衛星 GPS 接收器範例 GPS Application,其中主要包含兩個部分,一個是 Microsoft . WindowsMobile . Samples . Location 這個 GPS 函式庫,該函式庫是將系統的 GPS 功能,透過 System . Runtime . InteropServices 封裝後,提供給 C# 使用,另一個則是 GpsSample 的範例程式,該程式會顯示接收到的 GPS 座標於螢幕上。

想要撰寫微軟手機的衛星定位的應用程式者,只要看懂 GpsSample 的寫法,即可撰寫出很好的衛星程式,不需要詳細理解 Microsoft . WindowsMobile . Samples . Location 函式庫的內容。GpsSample 的主要程式 GpsTest.Form1 ,其程式重點摘要如下。

        private EventHandler updateDataHandler;
        GpsDeviceState device = null;
        GpsPosition position = null;

        Gps gps = new Gps();

        private void Form1_Load(object sender, System.EventArgs e)  {
            updateDataHandler = new EventHandler(UpdateData);
            ...
            gps.DeviceStateChanged += new DeviceStateChangedEventHandler(gps_DeviceStateChanged);
            gps.LocationChanged += new LocationChangedEventHandler(gps_LocationChanged);
        }

        protected void gps_LocationChanged(object sender, LocationChangedEventArgs args)   {
            position = args.Position;

            // call the UpdateData method via the updateDataHandler so that we update the UI on the UI thread
            Invoke(updateDataHandler);
        }

        void gps_DeviceStateChanged(object sender, DeviceStateChangedEventArgs args)  {
            device = args.DeviceState;

            // call the UpdateData method via the updateDataHandler so that we update the UI on the UI thread
            Invoke(updateDataHandler);
        }

        void UpdateData(object sender, System.EventArgs args)  {
            if (gps.Opened) {
                ...
                顯示  device.ServiceSate , device.DeviceState
                顯示  position.Latitude, position.LatitudeInDegreesMinutesSeconds
                顯示  position.Longitude, position.LongitudeInDegreesMinutesSeconds
                顯示  position.Longitude, position.LongitudeInDegreesMinutesSeconds
                if (position.SatellitesInSolutionValid&&position.SatellitesInViewValid&&position.SatelliteCountValid)  {
                  顯示 position.GetSatellitesInSolution().Length
                         position.GetSatellitesInView().Length
                         position.SatelliteCount
                         position.Time.ToString()
           }
        }

        private void Form1_Closed(object sender, System.EventArgs e)  {
            if (gps.Opened) gps.Close();
        }

在上述程式中,請務必用 Invoke 的方式取得衛星訊息,否則會導致系統當機,這是因為 Windows Mobile 的視窗本身無法完整的支援多執行緒功能,因此需要利用 Invoke 函數能讓視窗程式能正確被 GPS 回呼函數所呼叫。

以下是 GpsSample 的完整程式,有興趣者可詳細閱讀之。

using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Data;
using Microsoft.WindowsMobile.Samples.Location;

namespace GpsTest
{
    /// <summary>
    /// Summary description for Form1.
    /// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.MenuItem exitMenuItem;
        private System.Windows.Forms.MainMenu mainMenu1;
        private System.Windows.Forms.Label status;
        private MenuItem menuItem2;
        private MenuItem startGpsMenuItem;
        private MenuItem stopGpsMenuItem;

        private EventHandler updateDataHandler;
        GpsDeviceState device = null;
        GpsPosition position = null;

        Gps gps = new Gps();

        public Form1()
        {
            //
            // Required for Windows Form Designer support
            //
            InitializeComponent();

            //
            // TODO: Add any constructor code after InitializeComponent call
            //
        }
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose( bool disposing )
        {
            base.Dispose( disposing );
        }
        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.mainMenu1 = new System.Windows.Forms.MainMenu();
            this.exitMenuItem = new System.Windows.Forms.MenuItem();
            this.menuItem2 = new System.Windows.Forms.MenuItem();
            this.startGpsMenuItem = new System.Windows.Forms.MenuItem();
            this.stopGpsMenuItem = new System.Windows.Forms.MenuItem();
            this.status = new System.Windows.Forms.Label();
            // 
            // mainMenu1
            // 
            this.mainMenu1.MenuItems.Add(this.exitMenuItem);
            this.mainMenu1.MenuItems.Add(this.menuItem2);
            // 
            // exitMenuItem
            // 
            this.exitMenuItem.Text = "Exit";
            this.exitMenuItem.Click += new System.EventHandler(this.exitMenuItem_Click);
            // 
            // menuItem2
            // 
            this.menuItem2.MenuItems.Add(this.startGpsMenuItem);
            this.menuItem2.MenuItems.Add(this.stopGpsMenuItem);
            this.menuItem2.Text = "GPS";
            // 
            // startGpsMenuItem
            // 
            this.startGpsMenuItem.Text = "Start GPS";
            this.startGpsMenuItem.Click += new System.EventHandler(this.startGpsMenuItem_Click);
            // 
            // stopGpsMenuItem
            // 
            this.stopGpsMenuItem.Enabled = false;
            this.stopGpsMenuItem.Text = "Stop GPS";
            this.stopGpsMenuItem.Click += new System.EventHandler(this.stopGpsMenuItem_Click);
            // 
            // status
            // 
            this.status.Location = new System.Drawing.Point(0, 0);
            this.status.Size = new System.Drawing.Size(237, 173);
            this.status.Text = "label1";
            // 
            // Form1
            // 
            this.ClientSize = new System.Drawing.Size(240, 268);
            this.Controls.Add(this.status);
            this.Menu = this.mainMenu1;
            this.Text = "Form1";
            this.Load += new System.EventHandler(this.Form1_Load);
            this.Closed += new System.EventHandler(this.Form1_Closed);

        }
        #endregion

        /// <summary>
        /// The main entry point for the application.
        /// </summary>

        static void Main() 
        {
            Application.Run(new Form1());
        }

        private void exitMenuItem_Click(object sender, EventArgs e)
        {
            if (gps.Opened)
            {
                gps.Close();
            }

            Close();
        }

        private void Form1_Load(object sender, System.EventArgs e)
        {
            updateDataHandler = new EventHandler(UpdateData);

            status.Text = "";

            status.Width = Screen.PrimaryScreen.WorkingArea.Width;
            status.Height = Screen.PrimaryScreen.WorkingArea.Height;

            gps.DeviceStateChanged += new DeviceStateChangedEventHandler(gps_DeviceStateChanged);
            gps.LocationChanged += new LocationChangedEventHandler(gps_LocationChanged);
        }

        protected void gps_LocationChanged(object sender, LocationChangedEventArgs args)
        {
            position = args.Position;

            // call the UpdateData method via the updateDataHandler so that we
            // update the UI on the UI thread
            Invoke(updateDataHandler);

        }

        void gps_DeviceStateChanged(object sender, DeviceStateChangedEventArgs args)
        {
            device = args.DeviceState;

            // call the UpdateData method via the updateDataHandler so that we
            // update the UI on the UI thread
            Invoke(updateDataHandler);
        }

        void UpdateData(object sender, System.EventArgs args)
        {
            if (gps.Opened)
            {
                string str = "";
                if (device != null)
                {
                    str = device.FriendlyName + " " + device.ServiceState + ", " + device.DeviceState + "\n";
                }

                if (position != null)
                {

                    if (position.LatitudeValid)
                    {
                        str += "Latitude (DD):\n   " + position.Latitude + "\n";
                        str += "Latitude (D,M,S):\n   " + position.LatitudeInDegreesMinutesSeconds + "\n";
                    }

                    if (position.LongitudeValid)
                    {
                        str += "Longitude (DD):\n   " + position.Longitude + "\n";
                        str += "Longitude (D,M,S):\n   " + position.LongitudeInDegreesMinutesSeconds + "\n";
                    }

                    if (position.SatellitesInSolutionValid &&
                        position.SatellitesInViewValid &&
                        position.SatelliteCountValid)
                    {
                        str += "Satellite Count:\n   " + position.GetSatellitesInSolution().Length + "/" +
                            position.GetSatellitesInView().Length + " (" +
                            position.SatelliteCount + ")\n";
                    }

                    if (position.TimeValid)
                    {
                        str += "Time:\n   " + position.Time.ToString() + "\n";
                    }
                }

                status.Text = str;

            }
        }

        private void Form1_Closed(object sender, System.EventArgs e)
        {
            if (gps.Opened)
            {
                gps.Close();
            }
        }

        private void stopGpsMenuItem_Click(object sender, EventArgs e)
        {
            if (gps.Opened)
            {
                gps.Close();
            }

            startGpsMenuItem.Enabled = true;
            stopGpsMenuItem.Enabled = false;
        }

        private void startGpsMenuItem_Click(object sender, EventArgs e)
        {
            if (!gps.Opened)
            {
                gps.Open();
            }

            startGpsMenuItem.Enabled = false;
            stopGpsMenuItem.Enabled = true;
        }
    }
}

結語

微軟手機雖然支援 GPS 功能,但卻沒有將 GPS 功能封裝入 .NET Compact Framework 當中,因此必須使用 C# 撰寫系統呼叫的方式執行,這畢竟是一大缺點,希望微軟能有所改進,否則市場當然會被 Android 與 iPhone 不斷侵吞, Windows Mobile 手機的佔有率也正在不斷下降當中。

Facebook

gps
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License