加入RUN!PC粉絲團
最近新增的精選文章
 
最多人點閱的精選文章
 
 
精選文章 - 開發技術
分享到Plurk
分享到FaceBook
 
Windows Phone 7開發專欄(六)
文‧圖/董大偉 2011/7/26 下午 05:49:48

對於微軟的行動裝置市場現況來說,過去這幾年實在不能說是很樂觀,在iPhone出現之後,市場開始一面倒的傾斜,而微軟依舊沒有太大的動作,緊接著Android的問世,微軟才慢慢發現時間顯然早已不站在微軟這一邊,隨著時間的流逝,微軟早就錯過了制敵先機。
等到Windows Phone 7的出現,則理所當然的被大家認為這是微軟不成功便成仁的最後一擊。慶幸的是,在北美和歐洲上市的狀況還算交得了差,截至目前為止,不論在應用程式的品質和數量上,微軟都表現得還算不錯。(當然,由於Marketplace尚未在台灣和中國大陸地區開放,因此在這兩個地方的銷量依舊偏低,台灣部分預計2011年第四季將會全面開放)
微軟知道Apple在iPhone成功的關鍵是手機上的App,因此對App的開發人員頗多著力,從過去半年微軟所推出的活動可以窺見一二,連Marketplace尚未開放的台灣市場,微軟也釋出百萬重金來鼓勵WP7的App開發廠商。也因此,WP7作業系統的持續更新,不只是必要恐怕更是Windows Phone能否繼續成長的關鍵。而開發人員也磨刀霍霍,畢竟Mango這個版本的更新對於亞太開發人員來說更有著重大的意義。
由於Mango作業系統聲稱開始支援亞太地區語言,這是手機能否跨出歐美語系市場的重要步驟(在這次我們下載的SDK當中已經可以看到),同時Marketplace也開始針對台灣與幾個重要的亞洲市場開放,搭配更全面的API,對於在台灣和中國的App開發人員來說,不啻為一個大顯身手的好機會。
同時,從去年第三季上市以來,已經不少媒體與知名人士(諸如Dell, Motorola, IDC…etc)對WP7保持非常肯定與支持的態度,這也為WP7後續看好的市場,再注入一劑強心針。
因此,從Mango為起點,微軟面對手機市場的反攻正要開始。
有哪些新功能?這次針對開發人員釋出的Mango 7.1 SDK,已經可以窺見到不少的新功能,從模擬器開始,就有一系列的增強。首先,台灣開發人員相當在意的中文輸入,當然已經出現在7.1版的模擬器當中:


你會發現不僅可以輸入中文,也支援聯想字詞的功能,不僅如此,據說正式版本的Mango甚至可能會支援包含手寫在內的多種中文輸入方式,這也算是對台灣開發人員的力挺有了個負責任的交代。
除了模擬器開始支援中文之外,你也會發現模擬器同時也支援了GPS定位模擬:


這對於開發人員來說真是提供了莫大的便利性,先前版本的開發工具,由於缺少了這個功能,倘若要開發與GPS定位有關的應用,一律都得用實機測試,而加上了GPS模擬器,真的方便太多了。我們還可以在模擬器上預先錄製好幾個地點(如上圖右),然後開始撥放,模擬器手機上的程式開始運行時,GPS感應器就會每隔幾秒依序偵測到模擬器預先錄製的位置,這讓我們測試時非常方便。
不僅如此,針對手機上的方向感知器(accelerometer),模擬器也提供了支援,你會發現,只要我們用滑鼠拖曳下圖右方的accelerometer模擬器,手機模擬器中的程式可以立即偵測到X,Y,Z三軸傾斜度的改變:


Mango SDK在模擬器上的增強,一舉解決了開發人員臨時沒有實機在手則無法測試的窘境,也大大的提升了開發人員的便利性,這對開發人員的利多,恐怕也是微軟為了爭取更多開發人員投入所埋下的誘因。
在sensor相關的機制部分,除了上面介紹的accelerometer和GPS,其實在這個版本的Mango當中,也加上了羅盤(compass)和陀螺儀(gyroscope),這本來就是WP7手機支援的標準配備,但由於先前沒有API提供,因此一般的開發人員無緣享用,從Mango開始,各位Developer諸公們可以更盡興地發揮您的創意了。
多工與背景作業
這次Mango不可不提的,則是多工與背景作業機制,打從WP7上市以來,多工就是被使用者要求的重點功能之一,這次微軟也從善如流地照做了,也因此,目前我們可以在模擬器上按下F1來啟動多工切換功能(正式的手機上則是透過長按返回[Back]鈕來進入多工切換模式),而對於開發人員來說,多工模式並不和過去我們在7.0撰寫程式的Tombstoned模式相衝突,只是多了一個Dormant狀態,應用程式在記憶體充足的狀況下,可在使用者切換到(或啟動)另一個App時,將先前的App切入Dormant狀態,在這個狀態下的App, 可以透過task-switching多工切換模式(也就是長按返回[Back]鈕),來進行切換,由於在Dormant這個狀態下,程式並未從記憶體中被移除,因此當切換回來時,應用程式不需要從Tombstoned模式重新被載入記憶體中,這讓切換速度得以更快速,也達成了多應用程式切換的效果(開發人員也不需要額外撰寫其他特殊的程式碼)。
如果開發人員需要判斷應用程式是否是由Dormant狀態返回,可在App.xaml.cs當中這樣判斷:
------------BOX------------
private void Application_Activated(object sender, ActivatedEventArgs e)
{
//是否由Dormant狀態返回
if (e.IsApplicationInstancePreserved) {
//是
}
else {
//否
}
}
--------End----------
除了多應用程式切換之外,Mango還提供了其他許多常用的背景作業功能,我們稱之為Scheduled Actions:


從上圖您可以看到,Scheduled Actions共分為二大類(共四種),其功能分別是:


Alarm與Reminder比較簡單,可以透過底下的程式碼直接使用,例如:
------------BOX------------
Alarm alarm = new Alarm("alarm名稱");
alarm.Content = "時間有限,講快點...,講快點...";
alarm.BeginTime = DateTime.Now.AddSeconds(10);
alarm.ExpirationTime = DateTime.Now.AddHours(1);
alarm.RecurrenceType = RecurrenceInterval.None;
alarm.Sound = new Uri(@“/Sound/要播放的音樂.mp3", UriKind.Relative);

//Register the reminder with the system.
ScheduledActionService.Add(alarm);
--------End----------
呈現出的效果如下,時間一到就會撥放你指定的音樂,並出現系統提示訊息:


而Reminder和Alarm只有一點不同,就是Reminder無法撥放音樂,但可以連結到特定的頁面:
------------BOX------------
Reminder reminder = new Reminder(“Reminder名稱");
reminder.Title = "標題文字(Reminder1)";
reminder.Content = "提示內容...";
reminder.BeginTime = DateTime.Now.AddSeconds(10);
reminder.ExpirationTime = DateTime.Now.AddHours(1);
reminder.RecurrenceType = RecurrenceInterval.None;
reminder.NavigationUri = new Uri("/LinkPage.xaml?abc=123", UriKind.Relative);
// Register the reminder with the system.
ScheduledActionService.Add(reminder);
--------End----------
所有的Scheduled Actions都有一個一致的特性,就是即便您的應用程式沒有在前景執行,這些Actions依舊會在指定的時間被觸發,這讓開發人員開始有機會可以設計出鬧鈴或行事曆等功能,而這在先前版本的WP7當中則是沒有的。

除了Reminder和Alarm之外,還有兩個更低階的功能,我們稱為Scheduled Tasks,具體的實作分別是PeriodicTask與ResourceIntensiveTask。

在前面的表格中我們有說明,PeriodicTask是定時會被執行的背景作業,約莫每30分鐘會被執行一次,但一次不得超過15秒,PeriodicTask比較適合輕量級的背景工作,諸如紀錄用戶的GPS座標位置,少量的資訊傳遞,遠端伺服器狀態的檢查…等。而ResourceIntensiveTask則是在手機閒置且資源相當充分的狀況下才會被執行的背景工作(執行前提是…手機有插電、有Wifi或連線上網、電量充足、螢幕已鎖定、沒在講電話…),每次執行的工作可多達10分鐘,很適合進行資料同步作業或批次的資料上傳(或下載)工作。

要建立這樣的背景作業稍微複雜一些,開發人員必須在WP7方案中,額外加入一個SchedulerAgent專案:


並且在主程式當中,透過Add Reference加入此專案,接著透過底下的程式碼將SchedulerAgent排入排程(以PeriodicAgent為例,程式碼如下):
------------BOX------------
private void StartPeriodicAgent()
{
PeriodicTask periodicTask = new PeriodicTask("工作名稱");
periodicTask.Description = "說明文字";
if (ScheduledActionService.Find(periodicTask.Name) != null)
{
StopPeriodicAgent(); //如果有同名工作則停止
}
ScheduledActionService.Add(periodicTask);
}
--------End----------
別忘記,還要在SchedulerAgent的TaskScheduler.cs當中,實作OnInvoke方法,開發人員可以從OnInvoke方法所帶入的task參數得知該task被啟動時的性質與狀態:
------------BOX------------
protected override void OnInvoke(ScheduledTask task)
{
if (task is PeriodicTask)
{
//要進行的工作
}
else
{
//要進行的工作
}
NotifyComplete();
}
--------End----------
如此一來,OnInvoke當中所撰寫的程式碼就會在背景定時被執行。
Background Audio與Background Transfer
另一個跟背景作業有關且相當好用的新功能,則是Background Audio機制,它可以讓我們的應用程式在背景撥放音樂,簡單的說,就是設計背景音樂撥放器的機制。
使用的方法和先前介紹的Scheduled Tasks很像,需要在你的WP7專案中額外加入一個AudioPlaybackAgent:


並且實作AudioPlayer.cs當中的OnUserAction, OnPlayStateChanged…等方法。
接著在主程式當中,透過Add Reference來引用這個專案,如此一來即可透過BackgroundAudioPlayer.Instance這個靜態類別來操控音樂的撥放,例如:
------------BOX------------
BackgroundAudioPlayer.Instance.Play() //撥放
BackgroundAudioPlayer.Instance.SkipPrevious(); //上一首
BackgroundAudioPlayer.Instance.SkipNext(); //下一首
--------End----------
也可以藉由Hook PlayStateChanged事件來取得撥放狀態的變化:
------------BOX------------
BackgroundAudioPlayer.Instance.PlayStateChanged += new EventHandler(Instance_PlayStateChanged);

void Instance_PlayStateChanged(object sender, EventArgs e)
{
if (BackgroundAudioPlayer.Instance.PlayerState == PlayState.Playing)
{
textBlock1.Text = "Title:" + BackgroundAudioPlayer.Instance.Track.Title;
textBlock1.Text += "\nAlbum:" + BackgroundAudioPlayer.Instance.Track.Album;
textBlock1.Text += "\nArtist:" + BackgroundAudioPlayer.Instance.Track.Artist;
image1.Source = new System.Windows.Media.Imaging.BitmapImage(BackgroundAudioPlayer.Instance.Track.AlbumArt);
}
else
{ textBlock1.Text = ""; }
}
--------End----------
如此這般,我們就可以輕鬆地建立出一個音樂點唱機了:


除了Background Audio之外,另一個常用的背景作業則是Background Transfer,它可以讓我們在背景透過HTTP Protocol進行Web通訊(Get/Post),用來上傳或下載較大檔案(或其他數據資料),即使你的App在背景狀態也可以運行,而程式碼的撰寫也相當簡單,只需要指定來源與目的位置即可:
------------BOX------------
btr = new BackgroundTransferRequest(
sourceUri, destinationUri);
btr.TransferStatusChanged += BtsStatusChanged;
btr.TransferProgressChanged += BtsProgressChanged;
BackgroundTransferService.Add(btr);
--------End----------
從上述的這些功能介紹中您不難發現,微軟釋出的API都盡可能的大幅簡化開發人員的負擔,讓開發人員得以用最少的程式碼來完成常用的工作。
太多的功能增強與擴充
這次Mango SDK的釋出,相當程度的展現出了微軟的決心,並且也為Silverlight/WP7開發人員下了一顆定心丸,從前面介紹的一些新功能看來,Mango這次已經大幅的提升了作業系統的功能,新的API也讓開發人員在自己所開發的App中得以完成更多的應用,在兼顧安全性與效能的狀態下,讓無限的想像成為可能,
當然,我們在這一篇當中,無法完整的介紹Mango所有的功能,諸如開發人員非常關注的自訂動態磚(Tile),Push Notification的增強、與Bing Map的整合、Local Database, User data access…種種更多的新功能,只好在下一期為繼續為各位讀者介紹了。