課程內容
Ø Radio Turner
Ø The NetworkInterface.InterfaceType Property
Local FM Radio應用程式提供了一種特定的介面來操作手機內建的FM收音機。與“Music + Videos hub”中手機內建的收音機不同,該應用程式允許使用者直接輸入想要收聽的電台頻率。而且,應用程式還顯示當前的接收訊號強度,這也是對我們所處的無線環境的一個驗證。該應用程式的目的是展示手機中使用簡單有效收音機操作介面,即Microsoft.Devices.Radio命名空間中的FMRadio類。雖然它提供的功能非常有限,但是也具備了一些優點。比如,它能夠與“Music + Video hub”中的記錄和播放清單自動整合。
該應用程式需要擷取手機中的媒體庫(即具備ID_CAP_MEDIALIB能力)。如果沒有這個能力的話,雖然應用程式仍舊可以顯示收音機的一些基本資料,但是在啟動收音機時,程式會拋出一個名為“RadioDisabledException”的異常。
The User Interface
正如我們從應用程式的所看到的那樣,該應用程式的使用者介面就是“Tip Calculator”與“Alarm Clock”的混合。
圖32.1 應用程式首頁面
注意:
➔ 除了double-zero按鈕被power按鈕所替代以外,頁面資源集合中的button和相關的canvas樣式與第10章“Tip Calculator”應用程式中使用的極其相似。
➔ 顯示頻率用的自訂七段數位管字型在FrequencyDisplay這個使用者控制項中實現。它幾乎與第20章“Alarm Clock”中的TimeDisplay使用者控制項一致,但還是要稍微簡單一些。本章不涉及這方面的內容介紹,但是我們可以查看工程原始碼。
The Code-Behind
➔ 這裡使用的大多數代碼與第10章“Tip Calculator”有很多相似之處。除了與FMRadio類互動以及處理power按鈕的代碼不同之外,它們之間最大的差異就是:顯示頻率值的時候,只保留了一位小數;而“Tip Calculator”中使用了兩位小數。
➔我們可以通過靜態FMRadio.Instance屬性,得到一個FMRadio類的執行個體。該執行個體包含了三個可讀寫的屬性,用來控制手機中的收音機操作:
* Frequency,表示當前播放電台頻率的double類型值。
* PowerMode,只能是On或者是Off。
* CurrentRegion,可以是美國,日本,或者是歐洲。後者的含義就是“除了美國和日本之外的所有地區”。
FMRadio還包含一個唯讀、類型為double的SignalStrength屬性,它用來指示接收訊號強度(RSSI)。該屬性值的範圍還沒有規定,但從我測試的結果來看,它是一個0到1之間的值,其中0表示無訊號,1表示最強訊號。
在手機通過Zune與PC機相連時,為什麼收音機不工作?
案頭端啟動並執行Zune軟體會鎖定媒體庫,這就使得需要ID_CAP_MEDIALIB能力的程式無法正常工作(同樣,在手機與Zune串連時,我們無法使用Marketplace這個應用程式)。如果我們需要測試具備這種功能的程式,我們可以使用“Windows Phone Connect Tool”這個工具,它包含在“Windows Phone Developer Tools”中,使得PC機可以不運行Zune的情況下,建立於手機的串連。
由於這個功能的限制,我們使用者不得不關閉Zune,或者斷開與手機的串連。但最好的方法是,在程式中檢測這種情況,在發生時,我們知道出現這種現象的原因。Local FM Radio應用程式在StartRadio方法中檢測這種情況。它假設PowerMode設定失敗就是手機串連Zune的緣故,這不失為一種安全的假設。
檢測這種情況的另一種方法就是,檢查NetworkInterface. InterfaceType屬性值(位於Microsoft.Phone.Net.NetworkInformation命名空間中)是否是Ethernet,它只有在與Zune建立串連後,值變為Ethernet。但是,這是一個並不可靠的屬性,因為擷取它的值,需要經曆一個長時間的阻塞過程。如果我們決定使用這種方式的話,最好是在後台線程中使用它。
➔由於收音機的訊號強度值是可變的,但它並沒有與收音機相關的事件,所以首頁面的建構函式使用定時器對訊號強度值每隔兩秒進行重新整理一次。雖然這種迴圈的方式比較耗電,但一般情況下,使用者不會長時間地運行該應用程式。那是因為在應用程式退出以後,收音機仍舊保持工作(重要的是,該應用程式在鎖屏狀態下停止運行)。建構函式同時初始化FM頻率為上一次設定的FM頻率值。
FMRadio中的Frequency屬性是一個全域設定!
如果我們改變了收音機的電台,這會影響內建的收音機應用(同樣,其他任何使用收音機的第三方應用程式也會受影響)。一方面,這個操作非常的方便,因為在應用程式啟動時,不需要記住上一次的收音機頻率(事實上,Local FM Radio應用程式並沒有在隔離儲存空間中存放任何的資料)。另一方面,如果我們希望應用程式與手機內建的收音機進行隔離,那麼我們就需要做一些額外的工作。
StartRadio 和 StopRadio這兩個方法可以改變PowerMode屬性的值。如果接收訊號強度為0,StartRadio方法同樣顯示與內建收音機應用程式一樣的資訊,32.2所示。本應用程式假設這種情況發生時,使用者的耳機線沒有處於插入狀態,因為對於當前的手機來說,耳機線就充當了FM廣播的接收天線。
圖32.2 在沒有串連手機的耳機線時,應用程式無法擷取任何FM訊號。
FMRadio的PowerMode屬性在Windows Phone 7.0版本中存在bug!
在一些手機上,把PowerMode設定為Off後,收音機會停止一小段時間,但隨後,即使PowerMode不設定回來,收音機仍舊處於工作狀態。這就使得無法實現一個顯示與收音機狀態同步的按鈕。相反,該應用程式中的power按鍵表現得非常怪異。在這種情況下,假如應用程式啟動時,由於串連Zune的原因,導致收音機無法工作,那麼這種方式就可以用於啟動收音機。
➔ 在收音機開啟的情況下,將頻率設定為一個無效的值會引發異常。有效或者無效的值是相對於本地電台頻率來說的,如果這通過使用者邏輯來實現的話,就顯得有些複雜。因此,本應用程式採用了最簡單的方法,那就是在異常發生時,將顯示的頻率值變紅(當然,如果當前的佈景主題色彩是紅色,那就無法看到效果了)。
➔ 在使用者離開應用程式後(這時應用程式還在運行),我們仍舊可以通過點擊volume-up 或者是 volume-down 按鈕來控制收音機。應用程式這時會在螢幕上方彈出一個介面,32.3所示。有趣的是,通過後退或者是前進按鈕,我們還可以搜尋上一個/下一個電台,所以,如果在Local FM Radio運行過程中,我們按了上述的兩個按鈕,當前播放的電台就會和顯示的頻率值不一致。雖然本應用程式可以通過它定時器的Tick事件處理常式來檢測並驗證這種情況,但是,這並不是一個什麼大問題。
圖32.3 除了更改音量以外,音量控制介面還可以進行開啟收音機或者停止收音機的操作,甚至還可以通過接收訊號的強度,來搜尋前一個或者後一個電台。
我們是否可以擷取當前播放電台的本機號碼、名稱、或者是“當前播放節目”的資訊?
答案是否定的,雖然內建的收音機應用程式可以顯示這些資訊,但是從目前向開發人員開放的API來看,我們無法做到這些。