在Windows Phone里要做Background Service的方式,除了Background Agent、Background Audio、Background FileTransfer之外,
到了WP8针对Location的部分也提供允许背景执行的任务,这样一来就做可以做例如:背景记录慢跑的路线…这类型的应用。
?
对於Location的技术用於App上,可透过GPS、Wi-Fi与Cellular来取得座标搭配後端的Web Service或其他网路服务,
让用户得可location相关的整合剧情。
?
Windows Phone提供了二种APIs提供开发Location相关的服务,往下便针对这二个APIs加以介绍:
?
〉Windows Phone Runtime Location API:
??? 属於新的API在WP8开始才有支援,主要提供几个重点特性:
a. 适用於Native Code与管理型的应用程式使用。例如:如果您写Direct3D或管粴类型的应用程式均建议使用该API。
b. 对於一次性(one-shot)位置取得提供更大的支援。
??? API允许应用程式设指定位置的相关特性,例如:结果所需要的精准度、期望获取的结果、平衡精准度与回应的最长时间;
??? 需注意,如果实作的是Tracking(路线追踨),不要使用一次性(one-shot)位置取得,这样可以有比较好使用者体验,
??? 也可以让电力的使用比较少;
c. 在做Tracking location时,应用程式可以设定在固定的时间间隔或是位置移动多少距离(从上一个请求到目前移动的位置距离)後,
??? 请求取得location的更新。
d. 该API虽然在Windows 8上也有,但API仍有些差距,但支援了大部分的功能。
?
?
〉.NET Location API:
???? 该API与Windows Phone Runtime Location API不一样,它是专用於Windows Phone上。所以该API同时也支援了WP 7.1,
这样一来就可以将既有的App同时支援二个平台,不过未来会比较建议使用Windows Phone Runtime Location API。
相关内容可以参考<Windows Phone 7 - 学习Location Service与Map地图>或<.NET Location API for Windows Phone 8>。
?
?
本篇将针对Windows Phone Runtime Location API加以介绍与说明。
?
[注意]
a. 要操作Location API别忘了至WMAppManifest.xml加上必要的<Capabilities/>的宣告:ID_CAP_LOCATION 。
b. 要记得在App中加上宣告该App将会取得用户的Location资料,并弹出对话框让用户知道,并且实作管理Location权限的管理。
?
?
(1) 利用API取得电话目前所在的Location资讯;
???? 这部分介绍是做用於Check-in、利用Location-based资料进行搜寻…等,一次性使用的情境,如果您的App是这类的应用,
就可以参考这个部分的介绍。以下是简单作法的说明:
????? a. 宣告必要的Capabilities,并在OnNavigatedTo时判断是否要宣告使用座标资讯提示让用户知道;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
?
//在进入画面时即要宣告使用座标资讯
if (IsolatedStorageSettings.ApplicationSettings.Contains("AllowLocation") == false)
{
// 代表未显示过宣告该App会使用location资讯让用户资料
MessageBoxResult result =
MessageBox.Show("是否允许本应用程式将万您电话的地理座标资讯?",
"Location",
MessageBoxButton.OKCancel);
// 保存用户选择的值
if (result == MessageBoxResult.OK)
IsolatedStorageSettings.ApplicationSettings["AllowLocation"] = true;
else
IsolatedStorageSettings.ApplicationSettings["AllowLocation"] = false;
//保存设定值
IsolatedStorageSettings.ApplicationSettings.Save();
}
}
????????? 这个是必要的,而且要额外提供让用户可以管理该权限的功能,不然送审至DevCenter会被退件。
????
????? b. 透过Geolocator物件设定DesiredAccuracyInMeters属性,呼叫GetGeopositionAsync非同步取得座标资讯;
private async void OneShotLocation_Click(object sender, EventArgs e)
{
if (bool.Parse(IsolatedStorageSettings.ApplicationSettings["AllowLocation"].ToString()) == false)
//代表用户不允许使用他的座标资讯
return;
?
//初始化Geolocator物件,并设定DesiredAccuracyInMeters
Geolocator geolocator = new Geolocator();
//设定当从Location service返回的值以m为单位所需要精准度
geolocator.DesiredAccuracyInMeters = 50;
?
try
{
//要求取得Location资讯,并且设定最大暂存时间长度与timeout时间
Geoposition geoposition = await geolocator.GetGeopositionAsync(
maximumAge: TimeSpan.FromMinutes(5),
timeout: TimeSpan.FromSeconds(10));
?
LatitudeTextBlock.Text = geoposition.Coordinate.Latitude.ToString("0.00");
LongitudeTextBlock.Text = geoposition.Coordinate.Longitude.ToString("0.00");
}
catch (Exception ex)
{
if ((uint)ex.HResult == 0x80004004)
{
// the application does not have the right capability or the location master switch is off
StatusTextBlock.Text = "location is disabled in phone settings.";
}
//else
//{
// // something else happened acquring the location
//}
}
}
????? 这个部分多设定最大座标资讯保存时间与取得座标的timeout时间,让座标资讯取得可以有较好的回应。?????
???? 上述仅撷录了C#的部分,更详细的内容可以参考<How to get the phone's current location for Windows Phone 8>。
?
?
(2) 持续更新手机的Location资讯;
????? 如果需要在App在前景执行时,持续取得座标资讯,则需要考虑以下的作法。但需注意持续取得座标资讯将使用大量电力。
延用(1)的程式范例,针对Geolocator的几事件加以处理进行控制与更新画面中的值。
????? a. 为新的按钮注册启动追踪,并且注册了相关的事件:
private void TrackLocation_Click(object sender, EventArgs e)
{
if (bool.Parse(IsolatedStorageSettings.ApplicationSettings["AllowLocation"].ToString()) == false)
//代表用户不允许使用他的座标资讯
return;
?
if (tracking == false)
{
//启动持续定位追踪功能
geolocator = new Geolocator();
//设定精准度品质
geolocator.DesiredAccuracy = PositionAccuracy.High;
//设定座标移动间距多少了触发事件,单位公尺
geolocator.MovementThreshold = 100;
?
//注册监测状态与座标变动的事件
geolocator.PositionChanged += geolocator_PositionChanged;
geolocator.StatusChanged += geolocator_StatusChanged;
?
tracking = true;
TrackLocationButton.Content = "stop tracking";
}
else
{
tracking = false;
geolocator.StatusChanged -= geolocator_StatusChanged;
geolocator.PositionChanged -= geolocator_PositionChanged;
geolocator = null;
?
TrackLocationButton.Content = "track location";
StatusTextBlock.Text = "stopped";
}
}
????????? 始化Geolocator物件时并给予了精准度程度与移动间距,因此,当设备从上一个位置开始移动超过指定的移动间距,
????????? 将会触发事件以请求得到新的座标资讯。需要注册StatusChanged与PositionChanged来注意目前Geolocator状态与座标的改变。
?
???? b. 注册依状态改变与座标随着用户移动的距离来触发挡件,进一步取得值来显示与画面:
void geolocator_StatusChanged(Geolocator sender, StatusChangedEventArgs args)
{
string status = "";
?
switch (args.Status)
{
case PositionStatus.Disabled:
// 应用程式没有能式操作location功能或被关闭
status = "location is disabled in phone settings";
break;
case PositionStatus.Initializing:
// geolocator初始化进行tracking operation
status = "initializing";
break;
case PositionStatus.NoData:
// location service没有可用正确座标
status = "no data";
break;
case PositionStatus.Ready:
// location service 已准备开始建立geopositions经由换指定的参数
status = "ready";
break;
case PositionStatus.NotAvailable:
status = "not available";
// not used in WindowsPhone, Windows desktop uses this
// value to signal that there is no hardware capable to acquire location information
break;
case PositionStatus.NotInitialized:
// the initial state of the geolocator, once the tracking operation
// is stopped by the user the geolocator moves back to this state
break;
}
?
Dispatcher.BeginInvoke(() =>
{
StatusTextBlock.Text = status;
});
}
?????? 注册StatusChanged的事件可观查目前取得Location的状态,例如:Disabled代表用户未允许应用程式操作座标权限…等。
?
void geolocator_PositionChanged(Geolocator sender, PositionChangedEventArgs args)
{
//随着移动的座标改变修改画面内容
Dispatcher.BeginInvoke(() =>
{
LatitudeTextBlock.Text = args.Position.Coordinate.Latitude.ToString("0.00");
LongitudeTextBlock.Text = args.Position.Coordinate.Longitude.ToString("0.00");
});
}
????? 该段程式码内容撷录於<How to continuously track the phone's location for Windows Phone 8>里的内容。其中对於StatusChanged与
PositionChanged事件的处理才是重点,因为App既是做持续取得座标的资讯,必须让用户有感该App是有在运作的,不然很容易被退件。
?
?
从上述得知了几个重要的类别与事件,往下先解释这几个元素的功能。
??? 提供取得目前所在的座标资讯的运作元件。主要透过该类别提供的属性与事件加以设定撷取座标资讯的参数,
另外,搭配注册处理StatusChanged与PositionChanged事件来提供具反应的运作。
?
类型 | 名称 | 说明 |
属性 | DesiredAccuracy | 设定/取得Geolocator提供座标资讯的精准度等级。 搭配:PositionAccuracy enumeration使用, ?Default:最佳化电力、效能与其他成本的节省; ?High:尽可能提供最准确的报告。 ??????????????? 可能会降低系统的性能,应该只在必要时使用。 |
? | DesiredAccuracyInMeters | 获取或设置从位置服务返回的数据以米为单位所需的精度。 未给予值时,视为default。 根据给予的值有所不同: ?大於或等於100米,则为default; ?小於100米,则视为high; 不可以给予null值。 |
? | LocationStatus | 取得识别目前Geolocator的可用性以识别是否有办法取得座标资讯。 |
? | MovementThreshold | 设定/取得移动距离。以公尺(米)为单位,从最後一个PositionChanged撷取的座标至目前移动的座标差距。 |
? | ReportInterval | 位置更新的要求最小时间间隔,单位为毫秒。如果您的应用程序需要经常更新,设置这个值,以便该位置提供者可以通过仅在需要时计算位置的节省电力。 |
方法 | GetGeopositionAsync() | 开始非同步撷取设备现在的座标资讯。 |
? | GetGeopositionAsync(TimeSpan, TimeSpan) | 开始非同步撷取设备现在的座标资讯。搭配二个参数: ?maximunAge:缓存座标资讯的最大时间。 ?timeout:撷取超时的时间。 |
事件 | PositionChanged | 当座标被更新时所触发的事件。第一次使用Geolocator物件时要记得宣告让用户知道,才能通过审查<Guidelines for devices that access personal data>。 主要过事件参数PositionChangedEventArgs进行座标资讯的取得与操作。 【注意】 Geolocator在连线待机时永远可以被实例化,但Geolocator在叫调用GetGeopositionAsync()时,超过7秒没有回应时,PositionChanged事件将永远不会被呼叫,而StatusChanged将收到一个NoData的状态。 |
? | StatusChanged | 当Geolocator状态改变时,所触发的事件。例如:像Geolocator撷取到可用资料时触发事件通知、或是初始化的过程…等状态。 主要透过事件参数StatusChangedEventArgs进行状态的取得与操作。 【注意】 Geolocator在连线待机时永远可以被实例化,但Geolocator在叫调用GetGeopositionAsync()时,超过7秒没有回应时,PositionChanged事件将永远不会被呼叫,而StatusChanged将收到一个NoData的状态。 具有的PositionStatus清单: ?Ready ?Initializing ?NoData ?Disabled ?NotInitialized ?NotAvailable |
?
?
??? 呈现由GetGeopositionAsync()取得的结果,其中可能包括了Latitude、Longitude或civic address资料。
二个重要的属性如下:
名称 | 说明 |
CivicAddress | 唯读。取得包含Civic Address相关的座标资讯。 属性均是唯读,包括: ?City ?Country ?PostalCode ?State ?Timestanp |
Coordinate | 唯读。取得包含Latitude、Longitude相关的座标资讯。 属性均是唯读,包括: ?Accuracy:座标精准度,以公尺(米)为主; ?Latitude ?Longitude ?Point ?PositionSource ?SatelliteData ?Speed ?Timstanp |
?
?
[补充]
?PositionStatus enumeration:
Member | Value | Description |
Ready | ready | 0 | 座标资讯是可用的。 |
Initializing | initializing | 1 | 代表Location Provider正在初始化。例如:GPS接收器尚未接收完毕所需卫星数量的资料源时。 |
NoData | noData | 2 | 代表无法从Location Provider取得可用的座标。 LocationStatus will have this value if the application calls GetGeopositionAsync or registers an event handler for the PositionChanged event, before data is available from a location sensor. Once data is available LocationStatus transitions to the Ready state. |
Disabled | disabled | 3 | Location Provider不可使用。这状态代表用户未允许应用程式取得座标的权限。 |
NotInitialized | notInitialized | 4 | An operation to retrieve location has not yet been initialized. LocationStatus will have this value if the application has not yet called GetGeopositionAsync or registered an event handler for the PositionChanged event. |
NotAvailable | notAvailable | 5 | The Windows Sensor and Location Platform is not available on this version of Windows. |
======
以上是介绍WP8提供与Win8 Store App使用相同取得Location能力的APIs。
下一篇将介绍如何搭配背景执行的方式来实作像是runing轨迹的App应用。
希望该篇文章对太家有所帮助,谢谢。
?
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
?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
?
enjoy developing application and learning new technology time.
posted on 2014/3/6 01:12 我要推荐 | 阅读数 : 207 | 文章分类 [ Windows Phone ] 订阅