共用方式為


本文章是由機器翻譯。

Windows Phone 7

Windows Phone 與雲 — 簡介

Ramon Arjona

我正在學慣用西班牙語進行閱讀和寫作。由於我居住的位置有先天條件,我可以嘗試閱讀許多公共場所出現的雙語標記來練習西班牙語。問題是,有些時候我會被某個特定詞語困住,弄不清楚意思,或者完全無法理解整句話。而且,也很難保證在沒有相應的英語翻譯可供參考的情況下,我是否理解了所閱讀的內容。我可以隨身攜帶西班牙語-英語詞典,但是翻遍詞典也只是模棱兩可。

因為我的手機似乎總不離手,所以我實際上希望輕鬆地使用手機來説明進行翻譯。用手機訪問 Bing,然後使用基於雲的 Microsoft Translator,這樣做會有所説明,但要進入翻譯螢幕需要大量的按鍵操作。如果有某種方式可以方便地在手機上使用翻譯功能,那就萬事大吉啦。現在,隨著 Windows Phone 7 的橫空出世,您再也不必為此發愁了。

本文對開發 Windows Phone 應用程式進行了介紹,並演示了如何將此類應用程式與雲中的 Web 服務綁定。您應該對 C# 和 Visual Studio 有一定的瞭解,如果您或多或少有一些使用可擴展應用程式標記語言 (XAML) 開發應用程式的經驗(但並不作要求),將非常有説明。我使用的是 Windows Phone 工具的社區技術預覽 (CTP) 四月升級版。在您閱讀本文時,內容可能已經發生了更改,因此,請訪問 developer.windowsphone.com,閱讀最新的文檔並下載最新的工具。

首先要做的是:獲取一個應用程式 ID

如果您要與 Translator 或任何 Bing Web 服務進行交互,第一步就是獲取一個應用程式 ID。應用程式 ID 由服務 API 用來驗證來自已註冊 Bing 應用程式開發人員的請求。

請訪問 bing.com/developers/createapp.aspx,接著使用您的 Windows Live ID 登錄。然後填寫表單,該表單會要求您提供應用程式的名稱和說明,以及諸如您的公司名稱和電子郵寄地址之類的詳細資訊。當這些 API 發生了更改(例如推出新版本或者舊版本離線)時,就會使用您的電子郵寄地址來通知您。尤其對於 Translator API,在撰寫本文檔時已說明,舊版本將在新版本發佈後持續服務 90 天。

接下來,請閱讀使用條款,選中核取方塊以表示您接受這些條款,然後按一下“接受”按鈕。隨即會進入一個頁面,您新創建的應用程式 ID 就顯示在該頁面中。您可以隨時返回此頁面進行查看,但我通常在首次創建應用程式 ID 時,會將它複製並粘貼到應用程式的原始檔案中。

對於您打算在應用程式中使用的任何 Web 服務,請務必閱讀該服務的使用條款。請靜下心來仔細閱讀,而不要一掃而過,尤其是當您打算通過 Marketplace 向使用者分發您的應用程式時更是如此。對於您的客戶,您有責任瞭解由提供您的應用程式所使用服務的合作夥伴設定的服務水準目標和其他條件。因此,無論您的應用程式是否使用了 Microsoft 或任何其他方提供的服務,都應確保您閱讀並瞭解該服務的使用條款。

既然您已經有了應用程式 ID,我們就可以開始開發手機翻譯應用程式了。

定義方案

在開始創建我的第一個應用程式之前,我瞭解了一下市場上一些成功的移動應用程式。我對一些用於 Windows 電話以及其他智慧手機的應用程式進行了了解,想嘗試搞清楚一款真正成功的移動應用程式的成功秘訣。我閱讀了許多產品評論,採訪過許多使用者,也打擾過許多朋友,讓他們把自己的手機交給我體驗。

做完所有這些調查之後,我得到的結論是:一款成功的移動應用程式的關鍵在於簡便性。每種流行的應用程式都實現了一種或兩種主要的使用者方案,並且都實現得非常完善。例如,我發現了一整類應用程式,它們的唯一用途就是產生各種粗俗的噪音。實際上,它們本來的功能就是在手機上重現呵斥聲或腸胃脹氣聲。使用者似乎對這些很感興趣,至少足以讓他們付費在自己的手機上載入這些應用程式。

類似地,還有一些應用程式,它們可以類比投擲骰子的遊戲,推薦享用晚餐的餐館,甚至可以為推薦的晚餐計算小費。所有這些應用程式都有一種核心的使用者方案,並以一種簡便、直觀的方法來執行該方案。這種方法並非任何特定品牌的智慧手機所專有。developer.windowsphone.com/windows-phone-7 上發佈的《Windows Phone UI 設計和交互指南》已經要求我們堅持打造優美、直觀使用者體驗的設計理念。

因此,當我開始開發自己的翻譯應用程式時,重點是要關注我真正希望該應用程式實現的功能,而不是其他方面。為此,我首先需要對自己希望實現的功能有清晰的認識。腦海中有了此認識之後,我就可以抵制誘惑,不會去添加炫酷新功能。這樣的新功能雖然有趣,但對主要使用者方案毫無用處。我決定了,我的應用程式要實現的應該是英語和西班牙語之間的互譯功能。這款應用程式必須可以輕鬆地切換翻譯模式(從西班牙語到英語或英語到西班牙語),而且只處理單個單詞或簡單的句子。另外,由於我只關注西班牙語和英語,因此我的應用程式將忽略其他語言。

構建應用程式

要開始構建翻譯應用程式,請打開 Visual Studio Express 2010 for Windows Phone。依次選擇“New project...”(新建專案...)、“Windows Phone Application”(Windows Phone 應用程式)。此操作會打開預設的 Windows Phone 專案,並顯示一個由以下兩部分組成的螢幕:標題和內容。這兩部分用 XAML Grid 物件來表示,我們可以利用該物件定義一系列的行和列,然後在其中放置諸如按鈕和 TextBlock 之類的子 UI 元素(請參見圖 1)。

圖 1 預設 Windows Phone 專案(包含“顯示視圖”和“代碼視圖”)

首先,在設計器中選中應用程式名稱和頁面標題,對這些 UI 元素進行編輯。此操作會在設計器的代碼視圖視窗中突出顯示相關的 XAML,向您展示需要編輯的元素。接下來,打開工具箱,然後向頁面上較低的網格(稱為 ContentGrid)拖放一些 UI 元素。選擇一個 TextBox(用於輸入要翻譯的單詞),然後選擇一個 TextBlock(用於呈現翻譯的內容)。最後,添加兩個按鈕(請參見圖 2)。

圖 2 添加 TextBox、TextBlock 和 Button UI 元素

一個按鈕用於執行翻譯功能,另一個按鈕用於從西班牙語到英語或相反方向切換翻譯方向。

XAMLthe Modern UI

Windows Phone 7 使用者體驗的核心是名為“Metro”的設計系統代碼,而根據 Metro 系統實現 UI 的核心就是 XAML。如果您之前使用過 Silverlight 或 Windows Presentation Foundation (WPF),則您很可能熟悉 XAML。如果您沒有用過,則本部分將進行簡要介紹。

XAML 是一種以聲明形式構造 UI 的方法,可以使您將應用程式的邏輯與外觀嚴格分離。例如,您會注意到應用程式主頁面的代碼包含在 Mainpage.xaml.cs 中,而應用程式的基本佈局的代碼則包含在 Mainpage.xaml 中。與傳統的 Windows Forms 開發不同,這裡的應用程式碼與應用程式的 UI 佈局不存在任何混合。應用程式中的每個 UI 元素都建模為 XAML 檔中的 XML 元素。

這樣做的好處在於,它可以在一位設計人員處理應用程式的邏輯時,允許另一位設計人員獨立地處理應用程式的外觀。例如,既然我們已經勾勒出翻譯應用程式的基本 UI,就可以將 XAML 交由 UI 專家來處理,而我們則可以繼續處理代碼。UI 設計人員不需要知道我的應用程式實現的任何內容,我也不需要知道他選擇的調色板的任何情況。

當然,我也沒有 UI 設計人員的任何預算,但我有 MSPaint,它足以演示更新我的應用程式配套的圖形資源有多麼容易。

給 Translator 打造一個全新的圖示

按兩下創建專案時自動添加到專案的預設 ApplicationIcon.png。此操作可打開我的圖像編輯軟體,即我的開發電腦上的 MSPaint。將令人乏味的齒輪狀圖示替換為大寫字母 T。然後清除黑色背景,將背景填充為純粉紅色。大家可能會不喜歡我的圖形設計,但我喜歡(請參見圖 3)。

圖 3 使用 MSPaint 創建的新專案圖示

為了查看更改情況,按一下啟動按鈕,將應用程式部署到 Windows Phone 7 模擬器中。如果您使用過以前版本的 Windows Phone 模擬器,則會立即感受到開發人員體驗有了大幅提升。使用 Windows Phone 6.5 模擬器可能會非常麻煩,涉及到啟動以及向模擬器附加偵錯工具的許多手動配置步驟。在 Windows Phone 7 開發環境中,只需按一下綠色的啟動按鈕即可實現所有操作。我對模擬器載入和顯示應用程式主 UI(請參見圖 4)的速度十分滿意。

圖 4 Windows Phone 7 模擬器顯示的應用程式

為了查看應用程式圖示,我從主 UI 中退出,然後導航至模擬器的主螢幕。即可看到 Translator 圖形,顯示效果還不錯(請參見圖 5)。

圖 5 在模擬器中查看新應用程式圖示

應用程式清單

應用程式圖示是在名為 WMAppManifest.xml 的檔中定義的,該檔位於專案的 Properties 資料夾中。要重命名應用程式的圖示,請更改專案中 ApplicationIcon.png 的名稱,然後確保在 IconPath 元素中反映該更改:

<IconPath IsRelative="true"
   IsResource="false">myicon.png
   </IconPath>

如果應用程式無法找到自己的圖示,則在運行時會分配預設圖示,預設圖示看起來就像一塊黑色背景上有一個白色圓圈。

該檔的另一個需要檢查的元素是 Capabilities 元素,該元素包含您的應用程式希望使用的特定功能。最好只請求您的應用程式真正需要的功能。如果您通讀該檔,您會看到該檔中包含大量不大可能在我們的翻譯應用程式中使用的功能。

例如,ID_CAP_GAMERSERVICES 表示應用程式需要與 XBox 遊戲 API 進行交互,ID_CAP_LOCATION 功能表示應用程式需要利用設備的定位功能,ID_CAP_PUSH_NOTIFICATION 表示應用程式需要與 Windows Phone 7 的推送通知功能進行交互。所有這些功能都很棒,但我們的應用程式並不需要,因此可以去掉這些功能。實際上,我們可能只需要 ID_CAP_NETWORKING 功能,該功能表示應用程式需要使用網路來發送和接收資料。

Microsoft Translator API

Microsoft Translator 提供了三種 API。SOAP API 可以為使用者提供強類型化和易用性。AJAX API 主要供希望在其 UI 中嵌入翻譯功能的網頁開發人員使用。當 SOAP 和 AJAX API 都不適用時,HTTP API 非常有用。

我們將選擇 SOAP 介面,因為該介面最容易實現我們的目的。轉到“解決方案資源管理器”,然後按右鍵“引用”。然後選擇“添加服務引用”,輸入 Translator API 的 SOAP 介面的端點:http://api.microsofttranslator.com/V2/Soap.svc。在命名空間文字方塊中,將該服務端點命名為 TranslatorService,然後按一下“確定”(請參見圖 6)。

圖 6 添加 SOAP 服務引用

Visual Studio 將為您代勞其餘的工作,生成 SOAP 介面用戶端代碼。

現在向您的應用程式添加一些代碼。在應用程式的 MainPage 類聲明中,將應用程式 ID 和引用添加到 TranslatorService 用戶端:

string appID = <<your appID>>;
  TranslationService.LanguageServiceClient client = 
    new TranslationService.LanguageServiceClient();

IntelliSense 顯示翻譯服務有許多有趣的方法可用。 首先要注意的是,所有這些方法都是非同步的。 這一點很有用,因為我們在等待網路操作完成的過程中,沒有任何充分的理由去阻止用戶端應用程式。 這意味著,我們需要為我們執行的每個特定操作註冊一個委託。 在本例中,我們只對 LanguageServiceClient 提供的 TranslateAsync 方法和 TranslateAsyncComplete 事件感興趣, 但其他方法一定也很有趣。 讓我們來瞭解一下這些方法,看看它們是否適合我們的使用者方案。

其中比較突出的兩個方法是 GetLanguagesForTranslateAsync 和 GetLanguageNamesAsync。 第一個方法可以提供 Translator 服務支援的語言代碼清單。 通過調用此方法,您可以看到西班牙語的語言代碼為“es”。對於給定的一組語言代碼,GetLanguageNamesAsync 方法可以返回一個按照給定區域設置當地語系化過的語言名稱清單。 例如,如果您將“es”作為區域設置和語言代碼傳遞到此方法,則將返回字串“Español”。如果我們要實現多語種翻譯功能,則這兩種方法將非常有用。

另一個有趣的方法的名稱為 SpeakAsync。 該方法可以接受一個字串和一個區域設置,然後返回指向一個 WAV 檔(單詞的地道發音)的 URL。 這項功能酷極了。 例如,我可以鍵入一個字串,獲得其翻譯,然後將該字串傳遞給 SpeakAsync 方法獲取一個 WAV 檔,接著可以利用此檔用西班牙語與他人進行交流。 或者,當我不確定某個特定詞語的發音時,我可以使用 SpeakAsync 方法來聽一下該詞語的地道發音。

這些功能超酷,因此實在忍不住要將它們放到應用程式中。 但是,現在我們得挺住,需要將全部精力投入到實現我們最初制定的使用者方案當中。 如果腦海中有這種清晰的認識,就能夠更輕鬆地抵擋“再多添加一項功能”的誘惑。我確信在將來的某個時候,我肯定會使用 Translator API 中提供的這些功能,但不是現在。

綁定代碼來製作我們的翻譯應用程式非常容易。 首先,我們要為 TranslateCompleted 註冊委託:

client.TranslateCompleted += new
  EventHandler<TranslationService.TranslateCompletedEventArgs>
  
(client_TranslateCompleted);

然後,我們要實現 TranslateCompleted 事件處理常式,該處理常式可以將 TextBlock 的文本設置為翻譯後的文本:

void client_TranslateCompleted(object sender,
   TranslationService.TranslateCompletedEventArgs e)
 {
   TranslatedTextBlock.Text = e.Result;
 }
We wire up the button to submit the text we’ve entered for translation:
 private void TranslateButton_Click(object sender, 
   RoutedEventArgs e)
 {
   client.TranslateAsync(appID, TranslateTextBox.Text, fromLanguage,
     toLanguage);             
 }

接著,我們要為第二個按鈕添加一些簡單的代碼,使它可以在兩種翻譯模式(“西班牙語到英語”或“英語到西班牙語”)之間進行切換。此按鈕可以管理一個全域狀態變數,並且更改翻譯按鈕的文本來指示該狀態。

最後,我們將該應用程式部署到模擬器中進行測試。現在,我們只需幾行代碼和大約一小時的開發時間,就獲得了一個功能完整的翻譯應用程式。

擴展翻譯應用程式

儘管這款簡單的翻譯應用程式已經很不錯了,但我們還可以通過擴展我們的使用者方案進行進一步完善。如果我們能夠按照符合 Metro 設計規範的方式向我們的應用程式中綁定 Translator API 提供的更多語言,那就太棒了。如果能夠清除控制翻譯方向的按鈕,用一種更簡便、直觀的方式來控制翻譯方向,那就更完美了。無論我們怎麼做,都必須為使用手指與設備進行交互的使用者提供友好、快捷、簡便的使用者體驗。

那麼,我們該怎麼做呢?我們使用預設的清單專案構建一個應用程式。啟動一個新專案,然後選擇“Windows Phone List Application”(Windows Phone 清單應用程式)。此操作將進入預設螢幕,其中的 ContentGrid 會顯示一個 ListBox 控制項。該 ListBox 將用六種語言(即我們要將文本翻譯成的目的語言)替換虛擬文本(請參見圖 7)。

圖 7 預設 Windows Phone 清單應用程式

我們要對 MainViewModelSampleData.xaml 檔進行編輯,該檔包含在專案的 SampleData 資料夾中。您會看到一些類似如下代碼的 XML:

<local:ItemViewModel LineOne="design one" LineTwo="Maecenas praesent accumsan bibendum" LineThree="Maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos interdum lobortis nascetur"/>

您可以通過編輯該 XML,來更改 ListBox 的設計時視圖,使之包含我們要處理的所有語言:西班牙語、德語、英語、葡萄牙語、義大利語和法語。請注意,在您保存此檔之後,設計時視圖就會反映您所做的更改。這是因為 ListBox 控制項與 MainViewModelSampleData.xaml 中定義的 Items 元素是資料綁定的。這一點由 ListBox 控制項的 ItemsSource 屬性控制。

您還可以在運行時更新 ListBox 的內容。如果您仔細查看 Visual Studio 生成的檔,您會發現一個使用預留位置資料填充的可觀察集合 <ItemViewCollection>,這些資料與 MainViewModelSampleData.xaml 檔中包含的資料類似。例如,如果我希望根據 GetLanguageNamesAsync 方法返回的語言在 UI 中動態地生成語言清單,就需要編輯 MainViewModel.cs 檔來填充 Items 集合。現在我更願意指定一個靜態語言清單,只對 ItemViewModel 物件集合直接進行編輯。現在,當我們運行該清單應用程式時,應該會看到一個有點類似圖 8 的 UI。

圖 8 清單應用程式 UI

當使用者觸碰其中一個按鈕之後,就會進入一個詳細資訊頁面,該頁面實際上與我們的 SimpleTranslator 的 UI 是一樣的。該頁面包含以下控制項:一個用於輸入要翻譯的文字的 TextBox,一個用於顯示翻譯後的文本的 TextBlock,以及一個用於提交翻譯命令的按鈕。不過,我們不用添加另一個按鈕來管理翻譯的方向,我們將依靠 Translator API 來實現這一功能。我們的 SimpleTranslator 應用程式的雙向翻譯功能在這種多語言方案中是沒有意義的,而添加額外的 UI 層又會使應用程式運行遲緩而不流暢。值得慶倖的是,Translator API 提供了一種可以自動檢測傳入的語言的方法。

我們先添加一些代碼來調用翻譯用戶端的 DetectAsync 方法,傳入我們要翻譯的文本,然後再從 DetectAsyncComplete 事件處理常式調用 TranslateAsync。現在該事件處理常式將如下所示:

void client_DetectCompleted(object sender, 
  TranslationService.DetectCompletedEventArgs e)
{
  string languageCode = e.Result;
  client.TranslateAsync(appID, TranslateTextBox.Text, fromLanguage, tolanguage);
}

我們可以從使用者選擇的按鈕知曉我們要翻譯成的目的語言。我們可以從 Translator API 自動檢測的結果知曉我們要翻譯的來源語言。我們用了不到一小時的編碼時間,就創建了一款簡易多語種翻譯應用程式,使用者只需按兩下(不計算鍵入操作)就可獲得翻譯。

簡便性

簡便性是 Windows Phone 7 開發的核心。一款應用程式應專注于實現一種使用者方案,而且要實現得很完善。利用 Windows Phone 7 SDK CTP 自帶的工具可以輕而易舉地交付操作簡便、功能強大的應用程式。同時我們已經看到,與雲交互非常容易,開發人員只需投入少量時間,即可將 Microsoft Translator Web 服務綁定到 Windows Phone 應用程式中。借助一些熟悉的工具(如 Visual Studio)和明確的規範(如 Metro),Windows Phone 可以和雲一起共同為開發人員和使用者開闢一片充滿新機遇的廣闊天地。

Ramon Arjona 是 Microsoft Windows 團隊的一名高級測試主管。

衷心感謝以下技術專家參與本文的審閱:VikramDendiSandor Maurice