原文 如何在 Windows Phone 8 中获取手机的当前位置

适用于:仅限于 Windows Phone 8。

本主题演示如何使用 Windows Phone 位置 API 确定手机的当前位置。如果您的应用仅需要用户当时的位置,例如,记录某位置的用户,或进行基于位置的搜索,则这是用于获取位置的建议方法。相比使用持续跟踪,此方法对于手机电池寿命更为有利。如果您确实需要持续更新位置,请参见如何在 Windows Phone 8 中持续跟踪手机位置

重要说明:

您必须在您的应用清单文件中包含 ID_CAP_LOCATION 功能,才能在您的应用中使用位置 API。如果不这样做,将导致在开发期间部署应用时在应用中引发异常,并且,在您将应用提交到 Windows Phone 商店 时,它将无法被接收。有关更多信息,请参见 Windows Phone 应用的功能和硬件要求

获取手机的当前位置

  1. 在 Visual Studio 中创建新的 Windows Phone 应用。

  2. 在“解决方案资源管理器”中,展开“属性”文件夹,然后双击 WMAppManifest.xml。

  3. 在清单设计器的“功能”选项卡上,选中“ID_CAP_LOCATION”旁边的复选框。

  4. 在 MainPage.xaml 中,将下列 XAML 代码粘贴到现有的名为 ContentPanel 的 Grid 元素上。此代码定义一个将启动位置 API 的按钮,以及一些文本块来显示维度、经度和应用的状态。

     
    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <StackPanel>
    <Button x:Name="OneShotLocationButton" Click="OneShotLocation_Click" Content="get one-shot location"/>
    <TextBlock x:Name="LatitudeTextBlock"/>
    <TextBlock x:Name="LongitudeTextBlock"/>
    <TextBlock x:Name="StatusTextBlock"/>
    </StackPanel>
    </Grid>
  5. 在 MainPage.xaml.cs 文件的顶部添加以下 using 语句。

     
    using System.Threading.Tasks;
    using Windows.Devices.Geolocation;
  6. 添加同意提示以允许用户选择不让您的应用访问其位置。所有应用在使用位置 API 之前,应取得用户同意。本例检查 MainPage 类的 OnNavigatedTo(NavigationEventArgs) 方法中的用户同意,只要应用启动,就会调用它。代码首先检查 ApplicationSettings 字典,以了解是否存在“LocationConsent”密钥。如果发现该密钥,则意味着用户已经选择或退出位置,因此该方法立即返回。如果未发现该密钥,那么将显示 MessageBox,寻求用户同意。MessageBox 操作的结果受到检查,指示用户同意状态的布尔值存储在 ApplicationSettings 中的“LocationConsent”密钥内。在应用尝试访问用户位置之前,此密钥将受到检查。

     
    protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
    {
    if (IsolatedStorageSettings.ApplicationSettings.Contains("LocationConsent"))
    {
    // User has opted in or out of Location
    return;
    }
    else
    {
    MessageBoxResult result =
    MessageBox.Show("This app accesses your phone's location. Is that ok?",
    "Location",
    MessageBoxButton.OKCancel); if (result == MessageBoxResult.OK)
    {
    IsolatedStorageSettings.ApplicationSettings["LocationConsent"] = true;
    }else
    {
    IsolatedStorageSettings.ApplicationSettings["LocationConsent"] = false;
    } IsolatedStorageSettings.ApplicationSettings.Save();
    }
    }
  7. 将下列处理程序粘贴到用于按钮单击事件的 MainPage.xaml.cs 中。该方法首先检查ApplicationSettings 字典中用户同意的状态。如果值为 false,则该方法立即退出。一旦确定用户同意,则该方法初始化 Geolocator 对象,并设置 DesiredAccuracyInMeters 属性。随后,将调用 GetGeopositionAsync 方法。此方法尝试获取手机的当前位置。此为异步操作,因此在获取位置时不会阻止 UI 线程。您可以使用 await 操作符将代码置于异步调用之后,将在调用完成后执行。这需要该处理程序方法被申明为 async。因为可以确保使用 await 发起的调用返回在调用开始的线程上,而且 await 调用从 UI 线程发起,因此代码可以在调用返回时,直接访问并修改 UI。

    整个位置操作都包装在 try 块中,以防止引发任何异常。如果在开发时引发UnauthorizedAccessException 异常,可能意味着您的应用清单中未包含 ID_CAP_LOCATION。如果在已经部署应用之后发生这种情况,则可能意味着用户已在手机“设置”中禁用了此应用的位置。

     
    private async void OneShotLocation_Click(object sender, RoutedEventArgs e)
    { if ((bool)IsolatedStorageSettings.ApplicationSettings["LocationConsent"] != true)
    {
    // The user has opted out of Location.
    return;
    } Geolocator geolocator = new Geolocator();
    geolocator.DesiredAccuracyInMeters = 50; try
    {
    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
    }
    }
    }

使用本机代码获取手机的当前位置

  1. 本演练使用 IAsyncOperation<TResult> 来代表获取手机位置的异步操作。重要的一点是,获取位置时该对象没有超出范围,因此最好在标头中声明它的类成员变量。

     
    	Windows::Foundation::IAsyncOperation<Windows::Devices::Geolocation::Geoposition^>^ m_getOperation;
    
  2. 就本例而言,我们也声明方法 GetOneShotLocation,将在其中使用位置 API 。该方法以 3 个整数作为参数,用它们表示结果的所需精度(以米为单位)、系统为获取位置结果而在超时前应等待的最长秒数以及位置结果的最长生存期(以秒为单位)。

     
    	void GetOneShotLocation(int accuracyInMeters, int timeoutSeconds, int maxAgeSeconds);
    
  3. 在 .cpp 实现文件中,using 语句用于引用 Windows.Devices.Geolocation 命名空间。

     
    using namespace Windows::Devices::Geolocation;
    
  4. 该步骤演示示例 GetOneShotLocation 方法的定义。首先实例化 Geolocator 对象。然后使用DesiredAccuracyInMeters 属性设置结果的所需精度。如果已提供超时或最长生存期值,则使用这些值调用 GetGeopositionAsync(),否则调用无参数的版本。该方法返回IAsyncOperation<TResult> 对象(存储在我们的类变量中)。

    其次,定义 Completed 事件处理程序。一旦该事件处理程序被挂钩,系统开始异步获取手机的位置。在本例中,使用内联匿名委托而非单独的事件处理程序。异步操作完成时,内联代码将运行。当委托运行时,它首先检查 AsyncStatus 参数。如果没有错误,则调用 GetResults(),它返回Geoposition 对象,可使用该对象获取纬度、经度、位置结果的精度以及其他数据。如果出现错误,则检查错误代码值是否为 E_ABORT。如果是,则意味着用户已经在手机设置中禁用了此应用的位置服务。如果是这种情况,您可以选择向用户发出警报,然后提供不需要位置的回退应用行为。

     
    void WPNativeLocationExample::GetOneShotLocation(int accuracyInMeters, int timeoutSeconds, int maxAgeSeconds)
    { Geolocator^ geolocator = ref new Geolocator(); geolocator->DesiredAccuracyInMeters = (Platform::IBox<UINT>^)(PropertyValue::CreateUInt32(accuracyInMeters)); m_getOperation = nullptr; if(timeoutSeconds > 0 || maxAgeSeconds > 0)
    {
    TimeSpan maxAge;
    maxAge.Duration = maxAgeSeconds * 10000; TimeSpan timeout;
    timeout.Duration = timeoutSeconds * 10000;
    m_getOperation = geolocator->GetGeopositionAsync(maxAge, timeout);
    }
    else
    {
    // Use the API with defaults
    m_getOperation = geolocator->GetGeopositionAsync();
    } // Start location acquisition.
    // Setting the completion callback implicitly starts acquisition.
    m_getOperation->Completed = ref new AsyncOperationCompletedHandler<Geoposition^>(
    [=] (IAsyncOperation<Geoposition^>^ asyncOperation, AsyncStatus status) mutable
    {
    if(status != AsyncStatus::Error)
    {
    Geoposition^ geoposition = asyncOperation->GetResults(); // use the location information
    double latitude = geoposition->Coordinate->Latitude;
    double longitude = geoposition->Coordinate->Longitude;
    double accuracy = geoposition->Coordinate->Accuracy;
    MyUseLocationFunction(latitude, longitude, accuracy);
    }
    else
    {
    if(asyncOperation->ErrorCode.Value == E_ABORT)
    {
    // The user has disable location in the phone settings
    }
    else
    {
    // There was another error
    }
    }
    });
    }

如何在 Windows Phone 8 中获取手机的当前位置的更多相关文章

  1. windowsphone中获取手机位置信息

    首先在界面中加入一个textblock控件以显示信息 using System; using System.Collections.Generic; using System.IO; using Sy ...

  2. Android中获取手机电量信息

    有些时候我们需要在我们的应用上为用户展示当前手机的电量,这时候我们就需要用到广播了,我们都知道在动态注册广播的时候,我们需要传入一个BroadcastReceiver类对象,还有一个意图过滤器Inte ...

  3. 如何在Silverlight应用程序中获取ASP.NET页面参数

    asp.net Silverlight应用程序中获取载体aspx页面参数 有时候SL应用中需要使用由aspx页面中传递过来的参数值,此时通常有两种方法获取 1. 使用InitParameters属性, ...

  4. Windows Store 应用中获取程序集版本号的方法

    本文为个人博客备份文章,原文地址: http://validvoid.net/windows-store-app-get-assembly-version/ WinRT 中对反射做了很多限制,假设 W ...

  5. 如何在Windows Server 2003中配置FTP站点服务

    前面写过一篇文章<怎样给你的网站注册一个好域名?> ,讲到“玉米”,笔者有很深的情节,也希望与大家交流“米事”,可以站内私信我或者直接回复文章. 有了好域名只是做网站的开始.我们还要买主机 ...

  6. 如何在ASP.NET MVC 中获取当前URL、controller、action

    一.URL的获取很简单,ASP.NET通用: [1]获取 完整url (协议名+域名+虚拟目录名+文件名+参数) string url=Request.Url.ToString(); [2]获取 虚拟 ...

  7. 如何在Windows应用商店中提交您的Windows 8.1 应用更新

    翘首以盼的Windows 8.1 不负众望的与大家见面了,与此同时也带来了全新的应用商店,小伙伴儿们要赶紧升级系统啦! 今天给大家介绍下如何提交一个Windows 8.1 的应用,其实微软针对这次系统 ...

  8. [转]如何在Windows Server 2012中安装.Net Framework 3.5?

    http://www.cnblogs.com/westsource/archive/2012/12/26/2834876.html If you have Windows Server 2012 is ...

  9. 如何在ashx处理页中获取Session值

    本文章摘自:http://www.cnblogs.com/vihone/archive/2010/06/04/1751490.html 在一般事务处理页面,可以轻松的得到 Request,Respon ...

随机推荐

  1. POJ 1466 最大独立集入门

    题意:n个学生,给你每个学生浪漫的学生学号(男女之间浪漫),问你找出一个最大的集合保证集合内的任意两个学生之间没有相互浪漫关系,输出最大集合的人数. 注意:这里的浪漫边是双向的,如果1对2浪漫, 那么 ...

  2. Boost::Asio::Error的用法浅析

    一般而言我们创建用于接收error的类型大多声明如下: boost::system::error_code error 我们用这个类型去接受在函数中产生的错误 如 socket.connect( en ...

  3. Linux终端颜色和标题设置

    Linux给人最大的享受就是可以根据个人喜好去定制令自己舒服的系统配置,像终端颜色的设置就是一个典型的例子. 图1 系统默认状态下的终端显示 在没有经过自定义配置的终端下工作久了,难免容易疲劳,因为所 ...

  4. System Request 进入KDB模式过程详解

    0   echo g > /proc/sysrq-trigger   怎么让系统停下来,进入进入KDB循环? 1   需要简单了解下:Linux Magic System Request 2   ...

  5. Java中ArrayList和LinkedList差别

    一般大家都知道ArrayList和LinkedList的大致差别: 1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构.  2.对于随机訪问get和set.A ...

  6. ExtJs4 笔记(13) Ext.menu.Menu 菜单、Ext.draw.Component 绘图、Ext.resizer.Resizer 大小变更

    本篇讲解菜单.绘图.还有大小变更控件.菜单控件可以附加到各种其他控件中,比如按钮.工具栏等,甚至可以直接通过通过右键打开(模拟右键菜单):ext对绘图的支持可以让我们通过js来绘图:大小变更控件可以让 ...

  7. centos 安装ganglia监控工具

    一个.ganglia基本介绍 ganglia它是一个分布式监控系统,那里有两个Daemon,每间:clientGangliaMonitoring Daemon (gmond)和服务端GangliaMe ...

  8. 让盘古分词支持最新的Lucene.Net 3.0.3

    原文:让盘古分词支持最新的Lucene.Net 3.0.3 好多年没升级过的Lucene.Net最近居然升级了,到了3.0.3后接口发生了很大变化,原来好多分词库都不能用了,所以上次我把MMSeg给修 ...

  9. Swift - 使用网格(UICollectionView)的自定义布局实现复杂页面

    网格UICollectionView除了使用流布局,还可以使用自定义布局.实现自定义布局需要继承UICollectionViewLayout,同时还要重载下面的三个方法: 1 2 3 4 5 6 7 ...

  10. vdsm的SSL证书验证过程

    1. Copy the VDSM certificate of the RHEV-H(Red Hat Enterprise Virtualization Hypervisor ) host to th ...