Windows Phone 8 - Runtime Location API - 2
在<Windows Phone 8 - Runtime Location API - 1>介紹基本的APIs資訊與操作元件,裡面介紹面的內谷主要專注
在於App需在前景模式下,如果您希望App是做像常見的,例如:美食導航、慢跑路線、約會地點連結…等,
那麼接下來該篇將討論如何在背景模式下持續取得座標資訊的能力。
[觀念]
‧WP上的App如果不在前景運作中(例如:開其他程式或按Start鍵回到桌面),該App是被暫停的;
如果其他App需要更大的Memory被暫停的App可能會被關閉或進入tombstoned的;
參考資料<App activation and deactivation for Windows Phone>。
‧WP8允許如果app屬於「location-tracking」類型,它被允許在背景模式下持續進行,這個與Background Agent
屬於不同的處理機制。
‧實作「location-tracking」類型的App,自動支援Fast resume特性。
參考<Fast app resume for Windows Phone 8>或<Windows Phone 8 – Launch Apps與Fast Resume>。
‧由於app是執行於行動設備上,電力的考量是最重要的部分,所以在App執行於背景時需要特別注意:
a. 最小化次數/數量的網路請求;
=>如果可以的話,應統合所有請求改用批次的方式或是固定時間區間來發出請求。
b. 如果使用Timer與DispatcherTimer物件只為了更新前景的UI,請不要使用;
c. 停止使用所有的XAML動畫;
d. 如果App並非常時間需要做背景執行,可以搭配PositionChanged與StatusChanged的事件來停止座標追踨;
[背景可用APIs]
‧背景執行的App具有些限制但也有開發一些可用的APIs,
可參考<Features that can be used while running in the background for Windows Phone 8>。
例如:ShellToast、ApplicationModel.Store、Speech.Synthesis、Notification、IsolatedStorage、HttpWebRequest、Sockets…等。
〉Location-tracking被系統通知Deactivation的條件:
WP為了維持系統的穩定性,雖允許Location-Tracking類型的App可在背景執行,但具某些條件時系統會通知
Deactivated事件給App加以關閉。Deactivated事件就跟一般應用程式在前景模式收到Deactivated事件相同,這點與
Background Agent是不同的。
根據<Running location-tracking apps in the background for Windows Phone 8>中介紹,被通知Deactivated的條件:
‧App本身停止座標追蹤能力。App可在PositionChanged與StatusChanged事件搭配Geolocator或GeoCoordinateWatcher
停止持續座標追蹤。
‧App處於背景執行4個小時,但沒有用戶加以互動。
‧省電模式被啟動。
‧設備記憶體過低。
‧用戶關閉了設備的位置服務。
‧其他應用程式開始在背景模式執行。
這些條件發生後系統觸發Deactivated事件,可搭配事件中的Reason參數來加以了解是什麼狀態。
在撰寫好的App時這些條件最好均要測試,以免在送審過程被退件。
有了以上的觀念後,往下便來看看<How to run location-tracking apps in the background for Windows Phone 8>要怎麼實作吧。
A. 在WMAppManifest.xml宣告必要的特性 ID_CAP_LOCATION與設定DefaultTask具有<BackgroundExecution />;
在<DefaultTask />中宣告該App支援Background模式下的任務:
<Tasks>
<DefaultTask Name="_default" NavigationPage="MainPage.xaml">
<!-- 宣告為BackgroundExecution,固定的Name = LocationTracking -->
<BackgroundExecution>
<ExecutionType Name="LocationTracking" />
</BackgroundExecution>
</DefaultTask>
</Tasks>
宣告使用的是<BackgroundExecution />與<BackgroundServiceAgent />二者不同,
並且使用固定的Type Name:LocationTracking。
B. 在App.xaml中覆寫 shell:PhoneApplicationService 中的RunningInBackground事件;
在一般的App裡 shell:PhoneApplicationService僅註冊了四個事件:Launching、Closing、Activated與Deactivated。
在此,增加了新的事件處理:RunningInBackground。它主要觸發於當App執行於背景模式時。
目前僅開放在location-aware型的App才可以有這樣的功能。那麼一來需要將App.xaml修改成如下:
<Application.ApplicationLifetimeObjects>
<!--Required object that handles lifetime events for the application-->
<shell:PhoneApplicationService
Launching="Application_Launching" Closing="Application_Closing"
Activated="Application_Activated" Deactivated="Application_Deactivated"
RunningInBackground="Application_RunningInBackground"/>
</Application.ApplicationLifetimeObjects>
C. 實作最重要的RunningInBackground事件;
在App.xaml.cs中宣告二個重要的變數:
‧Geolocator:用於同時儲存App在前景與背景模式下所取得座標資訊;
‧RunningInBackground:用於識別目前處於前景或背景模式下;
有了這二個變數的使用,便在Application_Activated與Application_RunningInBackground分別
設定RunningInBackground的變數值,如下:
private void Application_RunningInBackground(object sender, RunningInBackgroundEventArgs args)
{
RunningInBackground = true;
// 當進入背景模式時,要記把相關UI更新或動畫全部取消;
}
private void Application_Activated(object sender, ActivatedEventArgs e)
{
RunningInBackground = false;
// 回到前景時,則設定關閉背景的執行任務,以節省電力
}
為何不寫在Application_Launch呢?因為有可能用戶是從暫存區開啟程式它就不會經過Launch, 而Activated則不管是第一次開啟或
從暫存區返回均可以使用。
D. 根據範例建立一個Page用於放置當Geolocator取得座標資訊時用於顯示座標的畫面;
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel>
<TextBlock x:Name="LatitudeTextBlock" Text="latitude"/>
<TextBlock x:Name="LongitudeTextBlock" Text="longitude"/>
</StackPanel>
</Grid>
E. 在該Page的OnNavigatedTo時,實例化Geolocator並註冊PositionChanged的事件;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
// 實例化宣告於App.xaml的Geolocator
if (App.Geolocator == null)
{
App.Geolocator =
new Windows.Devices.Geolocation.Geolocator();
App.Geolocator.DesiredAccuracy =
Windows.Devices.Geolocation.PositionAccuracy.High;
App.Geolocator.MovementThreshold = 100;
App.Geolocator.PositionChanged += Geolocator_PositionChanged;
}
}
F. 實作在PositionChanged事件下,前景模式更新畫面中的資料、背景模式下透過ShellToast通知座標已更新;
void Geolocator_PositionChanged(Geolocator sender, PositionChangedEventArgs args)
{
if (App.RunningInBackground == false)
{
//代表處於前景畫面可以直接更新畫面;
Dispatcher.BeginInvoke(() =>
{
LatitudeTextBlock.Text = args.Position.Coordinate.Latitude.ToString("0.00");
LongitudeTextBlock.Text = args.Position.Coordinate.Longitude.ToString("0.00");
});
}
else
{
//代表處於背景模式,僅能利用ShellToas來通知;
Microsoft.Phone.Shell.ShellToast toast = new Microsoft.Phone.Shell.ShellToast();
toast.Content =string.Format("{0},{1}",
args.Position.Coordinate.Latitude.ToString("0.00"),
args.Position.Coordinate.Longitude.ToString("0.00"));
toast.Title = "Location: ";
toast.NavigationUri = new Uri("/Page2.xaml", UriKind.Relative);
toast.Show();
}
}
G. 覆寫重要的事件PhoneApplicationPage.OnRemovedFromJournal;
為什麼需要覆寫這樣的功能呢?為了就是當我們實作的Page是用於支援LocationTracking時,該頁如果被關閉時,
註冊於該頁擷取Geolocator的事件需要被取消,以免造成不同Thread的Exception問題。而該事件會被呼叫,也代表該
Page已經被呼叫從journal移除掉了,例如:呼叫RemoveBackEntry()事件之後。
protected override void OnRemovedFromJournal(JournalEntryRemovedEventArgs e)
{
//在該Page被移除之前,先取消註冊處理PositionChanged的事件
App.Geolocator.PositionChanged -= Geolocator_PositionChanged;
App.Geolocator = null;
base.OnRemovedFromJournal(e);
}
[執行畫面]
測試的方式我是使用Emulator加上Additional Tools一起模擬目前移動的座標位置。相關於如何使用Additional Tool來模擬座標,
可參以下的步驟:
[範例程式]
======
以上是分享如何實作LocationTracking的App,其中內容主要擷取MSDN上的內容來加以說明,
希望對大家有所幫助。
References:
‧How to get the phone's current location for Windows Phone 8
‧How to continuously track the phone's location for Windows Phone 8
‧How to run location-tracking apps in the background for Windows Phone 8 (重要)
‧Location Sample for Windows Phone 8
‧NET Location API for Windows Phone 8.
‧Acquiring a single Geoposition in Windows Phone 8
‧Windows Phone 8 and Windows 8 platform comparison
‧Using the Location API in Your Windows Phone 8 Applications
‧Features that can be used while running in the background for Windows Phone 8
‧Fast app resume for Windows Phone 8 (重要)
‧App activation and deactivation for Windows Phone (重要)
‧Features that can be used while running in the background for Windows Phone 8 (重要)
‧Maps in Windows Phone 8 and Phone toolkit: a winning team – Part 1
‧Maps in Windows Phone 8 and Phone toolkit: a winning team – Part 2