Windows Mobile中的WebService應用

 Web Service對於開發者來說已經不再是一個陌生概念了。Web Service允許應用程序通過Internet進行通訊和數據交換。隨着微軟.NET戰略的推行,這種可編程的、通過SOAP協議、基於XML的網絡協議已經贏得了開發者的心。

WebService對於開發者來說已經不再是一個陌生概念了。Web Service允許應用程序通過Internet進行通訊和數據交換。隨着微軟.NET戰略的推行,這種可編程的、通過SOAP協議、基於XML的網絡協議已經贏得了開發者的心。

  現在,隨着無線數據網絡的發展,移動設備如何訪問網絡資源的問題顯得格外突出。我們目前已經擁有了GPRS和CDMA的廣域數據通訊網絡,很多地方也覆蓋了WI-FI的無線數據局域網。如何讓我們的應用程序更好的利用網絡資源?

  Windows Mobile移動設備爲我們提供了.NET Compact Framework,爲我們開發移動應用程序帶來的了極大的方便。.NET Compact Framework也提供了方便的Web Service訪問方式,幫助開發者來編寫基於Web Service的移動應用程序。

  目前來看,Windows Mobile應用程序訪問Web Service的應用主要出現在兩個方面:首先是個人應用程序需要獲取公共數據服務,比如獲取天氣預報、地理信息等;其次是,基於Windows Mobile的企業級應用將核心服務發佈成Web Service形式,由移動應用程序進行調用。

  我們這次主要討論調用公衆數據服務Web Service的情況,以Google和MapPoint Web Service爲樣本,講述如何在Windows Mobile應用程序中調用搜索引擎和地圖服務。

  訪問Google Web Service

  Google是目前網絡上最流行的搜索引擎之一,關鍵字搜索完全改變了網絡信息的組織形式。Google很早就提供了公共Web Service服務,允許應用程序訪問Google提供的搜索、拼寫檢查和頁面緩存的功能。Google Web Service的每個帳號一天最多查詢一千次。

  在使用Google之前,我們必須去www.google.com/apis,申請一個Google Account。註冊成功後,會收到一個Google的關鍵字,每次調用的時候,都要提供這個關鍵字。

  在申請成功後,我們可以動手開發自己的應用程序了。我們在Visual Studio 2005 Beta 2中創建一個Device Application。然後我們要爲Google Web Service添加一個Web引用。在Project菜單中選擇Add Web Reference,在URL裏輸入 http://api.google.com/GoogleSearch.wsdl,選擇Add Reference按鈕就可以了。這樣,我們就把Google Web Service添加到我們的應用程序中來了。

  我們先來認識一下Google Web Service中的對象。這些對象設計得和Google的主頁一樣簡單。

 對象  說明
 DirectoryCategory  ODP目錄的內容和種類
 GoogleSearchResult  Goolge查詢結果
 GoogleSearchService  Google查詢服務對象
 ResultElement  查詢結果集元素

  我們下面就來用這些對象來編寫一個簡單的Google查詢的程序。我們首先要介紹一個重要的API:GoogleSearchService下的doGoogleSearch。

public GoogleSearchResult doGoogleSearch(
    string key, // Google Key
    string q, // 查詢內容
    int start, // 從第幾條結果開始返回
    int maxResults, // 最多返回多少條(最多10條)
    bool filter, // 是否自動過濾相似或來源相同的結果
    string restrict, // 限制查詢結果來自Google Web 索引的一個子集
    bool safeSearch, // 是否過濾成年人內容
    string lr, // 語言限制(”lang_zh-CN”爲中文)
    string ie, // 輸入編碼
    string oe) // 輸出編碼

  在某些情況下,我們需要設置代理服務器來訪問一些網絡資源,所以,我們要引入System.Net的命名空間,然後創建一個Web Proxy賦給GlobalProxySelection,才能保證我們調用Web Service的正常。

WebProxy proxy = new WebProxy("itgproxy",80);
proxy.BypassProxyOnLocal = true;
GlobalProxySelection.Select = proxy;

  在上面的代碼裏我們首先創建一個WebProxy,地址爲” itgproxy”,端口爲80。然後選擇本地地址不使用代理服務器,最後設置到GlobalProxySelection中。

  下面我們把完整的代碼寫出來:

try
{
    WebProxy proxy = new WebProxy("itgproxy",80);
    proxy.BypassProxyOnLocal = true;
    GlobalProxySelection.Select = proxy;

    GoogleSearchService service = new GoogleSearchService();
    GoogleSearchResult result = service.doGoogleSearch(
        key, // 查詢Key
        textBox1.Text, // 內容
        0, // 從第幾條結果開始返回
        10, // 最多返回的條數(最大10條)
        false, // 是否自動過濾相似或來源相同的結果
        "", // 限制查詢結果來自Google Web索引的一個子集
        false, // 是否過濾成年人內容
        "", //"lang_zh-CN", // 語言限制
        "", // 輸入編碼
        ""); // 輸出編碼

    for(int i = 0; i <= (result.endIndex - result.startIndex); i++)
    {
        ResultElement element = result.resultElements[i];
        listBox1.Items.Add(element.title);
        listBox1.Items.Add(element.snippet);
        listBox1.Items.Add(element.URL);
    }

    MessageBox.Show(result.estimatedTotalResultsCount.ToString());
}
catch (System.Web.Services.Protocols.SoapException ex)
{
    MessageBox.Show(ex.Message);
}

  在設置好代理服務器後,我們創建一個GoogleSearchService的對象,然後調用該對象的doGoogleSearch方法。我們將得到一個GoogleSearchResult的結果集,通過endIndex和startIndex屬性,我們可以獲得查詢結果的數量。我們從結果集對象的resultElements中獲得ResultElement對象,然後把標題、簡介和URL顯示到listBox中去。最後我們可以用結果集對象的estimatedTotalResultsCount屬性,來獲取一共找到了多少個結果。我們上邊曾經說過,每次查詢最多隻能返回10個結果,但是estimatedTotalResultsCount返回的是所有符合條件的記錄。

 

訪問MapPoint Web Service

  MapPoint是微軟提供的一個地圖信息的Web Service,提供全球各地的地理信息和商業網點信息(主要是北美和歐洲地區)。MSN Search推出的地理搜索服務也是基於MapPoint Web Service服務的。目前MapPoint還不包括中國的地理信息。

  Windows Mobile設備的存儲空間比較小,所以很難保存大量的地圖數據。但是隨着無線網絡的普及,Windows Mobile設備就可以方便地查詢保存在服務器上的地圖數據和黃頁信息。MapPoint Web Service還可以結合Windows Mobile設備上的GPS定位系統或者LBS服務,查詢附近的旅遊景點和商業場所,這對於移動應用也具有十分現實的意義。

  MapPoint是一個收費的Web Service,不過,我們可以申請一個60天的測試帳號。MSDN的訂戶還可以申請一個爲期一年的帳號,用於應用程序的開發。在申請到帳號後,我們不但可以查詢公共的地理信息,還可以上傳自己的地理信息,用於支持自定義的地理信息查詢。

  我們創建一個Windows Mobile Device Application,然後添加一個Web Reference,URL爲“http://staging.mappoint.net/standard-30/mappoint.wsdl”。

  在編寫程序之前,我們先來看一下MapPoint中需要用到的類和方法。

 類方法  說明
 FindServiceSoap  包括查詢服務(find service)的方法和屬性
 RenderServiceSoap  包括查詢結果表示服務(render service)的方法和屬性
 FindSpecification  用於指定FindServiceSoap.Find的查詢信息
 FindResults  FindServiceSoap查詢操作的單個結果
 ViewByScale  包含地圖定義地圖比例和基準點
 MapOptions  包含RenderServiceSoap.GetMap方法的地圖顯示選項
 Pushpin  包括圖釘的圖標、標籤、定位、用戶指定數字
 MapSpecification  包含地圖顯示的詳細規範
 MapImage  RenderServiceSoap.GetMap返回的地圖

  我們首先來創建MapPoint查詢過程中最重要的兩個對象:

FindServiceSoap fws = new FindServiceSoap();
RenderServiceSoap ws = new RenderServiceSoap();
fws.Credentials = new NetworkCredential(myUserName, myPassword);
ws.Credentials = new NetworkCredential(myUserName, myPassword);

  FindServiceSoap是提供地圖查詢服務的主要對象,RenderServiceSoap是表現查詢結果地圖的主要對象。在使用之前,我們要先創建一個NetworkCredential對象,將MapPoint的用戶名和密碼傳給FindServiceSoap和RenderServiceSoap的Credentials屬性。

  然後我們創建一個FindSpecification對象,指定地圖數據庫、要查詢的地點,然後將其作爲FindServiceSoap的Find方法的參數執行查詢,並返回FindResults對象中。

FindSpecification myFindSpec = new FindSpecification();
myFindSpec.DataSourceName = "MapPoint.NA";
myFindSpec.InputPlace = this.textBox1.Text;

FindResults results = fws.Find(myFindSpec);
if (0 == results.NumberFound)
{
    MessageBox.Show("你找的是什麼鬼地方?");
    return;
}

  我們選擇的地圖數據源是北美地區的數據集“MapPoint.NA”,而InputPlace是要查詢的地點,從界面上的文本框中獲得。然後調用FindSpecification的Find方法,返回FindResults對象。如果結果集對象的NumberFound屬性爲0,則說明沒找到合適的結果。

  然後我們創建一個ViewByScale對象,爲該對象的CenterPoint屬性創建LatLong對象。CenterPoint屬性的經緯度分別results.Results[0].FoundLocation.LatLong中的經緯度。然後在ViewByScale對象的MapScale屬性中設置地圖的比例尺。創建MapOptions對象,在MapOptions.Format設置地圖的寬度和長度。創建一個圖釘對象Pushpin,將圖釘對象的經緯度設置爲ViewByScale對象的經緯度。

  在創建完這些對象後,我們創建一個MapSpecification對象用於指定要顯示地圖的詳細情況。我們要指定MapSpecification對象的地圖數據集,並將前邊創建的三個對象分別賦給Options、Pushpins、Views屬性中。

MapSpecification myMapSpec = new MapSpecification();
myMapSpec.DataSourceName = "MapPoint.NA";
myMapSpec.Options = options;
myMapSpec.Pushpins = pushpins;
myMapSpec.Views = views;

  在設置完成MapSpecification對象後,我們將其作爲參數,調用RenderServiceSoap對象的GetMap方法,獲取MapImage對象。然後將MapImage對象中的數據作爲MemoryStream內存流,用於創建一個Bitmap對象,最後顯示到PictureBox中。

MapImage[] images = ws.GetMap(myMapSpec);
this.pictureBox1.Image = new System.Drawing.Bitmap(new System.IO.MemoryStream(images[0].MimeData.Bits));

  完整代碼如下:

WebProxy proxyObject = new WebProxy(proxy, 80);

// Disable proxy use when the host is local.
proxyObject.BypassProxyOnLocal = true;

// All requests this proxy information.
GlobalProxySelection.Select = proxyObject;

FindServiceSoap fws = new FindServiceSoap();
RenderServiceSoap ws = new RenderServiceSoap();
fws.Credentials = new NetworkCredential(myUserName, myPassword);
ws.Credentials = new NetworkCredential(myUserName, myPassword);

FindSpecification myFindSpec = new FindSpecification();
myFindSpec.DataSourceName = "MapPoint.NA";
myFindSpec.InputPlace = this.textBox1.Text;

FindResults results = fws.Find(myFindSpec);
if (0 == results.NumberFound)
{
    MessageBox.Show("你找的是什麼鬼地方?");
    return;
}

ViewByScale[] views = new ViewByScale[1];
views[0] = new ViewByScale();
views[0].CenterPoint = new LatLong();
views[0].CenterPoint.Latitude = results.Results[0].FoundLocation.LatLong.Latitude;
views[0].CenterPoint.Longitude = results.Results[0].FoundLocation.LatLong.Longitude;
views[0].MapScale = 150000;

MapOptions options = new MapOptions();
options.Format = new ImageFormat();
options.Format.Height = this.pictureBox1.Height;
options.Format.Width = this.pictureBox1.Width;

Pushpin[] pushpins = new Pushpin[1];
pushpins[0] = new Pushpin();
pushpins[0].IconDataSource = "MapPoint.Icons";
pushpins[0].IconName = "0";
pushpins[0].Label = results.Results[0].FoundLocation.Entity.Name;
pushpins[0].LatLong = views[0].CenterPoint;
pushpins[0].ReturnsHotArea = true;

MapSpecification myMapSpec = new MapSpecification();
myMapSpec.DataSourceName = "MapPoint.NA";
myMapSpec.Options = options;
myMapSpec.Pushpins = pushpins;
myMapSpec.Views = views;

MapImage[] images = ws.GetMap(myMapSpec);
this.pictureBox1.Image = new System.Drawing.Bitmap(new System.IO.MemoryStream(images[0].MimeData.Bits));

  我們上面演示的僅僅是最簡單的地圖查詢功能,我們還可以通過FindAddress, FindByID, FindByProperty, FindNearby 或者 FindNearRoute等方法來查詢地址、查詢附近的地點等。我們還可以通過MapPoint Web Service來實現智能路標的功能。

  寫在最後

  上面我們一起了解了如何在Windows Mobile應用程序中加入Google和MapPoint的Web Service。我們還可以通過Web Service來發送短信,獲取天氣預報。越來越多的服務提供商也開始把自己的服務發佈成Web Service,使自己的服務不但可以提供給終端用戶,還可以提供給應用程序開發者,從而擴大自己的用戶羣。

  現在Web Service和Windows Mobile應用程序都處在發展期。隨着無線網絡的成熟,加上其他的智能手機操作系統也開始支持Web Service,我們會看到越來越多應用於移動設備上的Web Service案例。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章