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

原文  如何在 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 的按钮,以及一些文本块来显示维度、经度和应用的状态。

    XAML

     

    <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 语句。

    C#

     

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

    C#

     

    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。如果在已经部署应用之后发生这种情况,则可能意味着用户已在手机“设置”中禁用了此应用的位置。

    C#

     

    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> 来代表获取手机位置的异步操作。重要的一点是,获取位置时该对象没有超出范围,因此最好在标头中声明它的类成员变量。

    C++

     

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

    C++

     

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

    C++

     

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

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

    C++

     

    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
    				}
                }
            });
    }
    
  5.  
时间: 2024-10-23 15:13:26

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

如何在Windows 2000环境中Kill掉单个Oracle线程

oracle|window  如何在Windows 2000环境中Kill掉单个Oracle线程   来源:http://metalink.oracle.com 关键字:Oracle Thread Kill 描述:本文说明在Windows环境下, Orakill工具的使用 正文:        你遇到过下面类似的情况吗?一个用户进程长期占用资源而不释放,导致Oracle进程占用了系统的大量资源,Oralce系统的效率变得很低.如果简单的关闭重启Oracle 实例,势必影响所有的用户.有没有办法仅

服务器-如何在Windows Server2012系统中搭建VPN服务

问题描述 如何在Windows Server2012系统中搭建VPN服务 想在Windows Server2012系统中搭建一个VPN服务,,,然后用其他电脑连接 通过网上按别人的方法自己操作了一遍,,但是连接不上VPN服务器(我的是XP系统)一直报721错误 不知道是否还有哪些服务没有关闭,,还是因为我(客户端)连接的宽带之上的路由器没有开启相关功能(但那是移动说了算啊) 解决方案 怎样才能凑够10个字符呢 解决方案二: 如果你的服务器配置没问题,那么可能是你的客户端的问题,特别是一些山寨盗版

如何在Windows 8/7中建立WebDAV服务器

  WebDAV是一种类FTP的协议,你可以用它在互联网上远程访问或共享你的文件.与FTP相反,WebDAV可以更好地通过防火墙,并且有密码保护和加密.我们马上就来介绍一下如何在Windows中建立WebDAV服务器. 首先,你必须安装互联网信息服务(IIS)和WebDAV publishing.在Win7中,点击"开始",输入"Windows features",然后按下回车.在Win8中,在开始屏幕上,输入"Windows features"

如何在Windows Server 2012中使用NIC Teaming

  NIC Teaming是Windows Server 2012 Hyper-V 3.0中引入的众多网络功能之一.NIC Teaming最初设计用于Windows Server 2012,现在也可以用来为Hyper-V虚拟机配置绑定的适配器. 本文主要介绍如何在Windows Server 2012或更高版本上配置NIC Teaming.当然,Windows管理员可以使用第三方工具在Windows上配置NIC teaming,但具有以下缺点: 供应商提供支持,而非微软. 你只能在来自同一制造商

Android中获取手机屏幕大小的方法_Android

本文为大家解析Android中如何获取手机屏幕大小,提供一个解决方法,分享给大家供大家参考,具体内容如下 运行效果图: 运行程序后,当我们点击Button按钮时,可以看到下面的效果图: 具体代码: 我们可以通过使用类DisplayMetrics来获取手机屏幕的分辨率大小.DisplayMetrics类是获取手机屏幕各种属性的关键类.下面通过例子来展示如何获取手机屏幕的分辨率. 在布局文件main.xml中添加一个TextView对象,一个Button对象.其中TextView对象用来显示获得的分

windows应用程序中获取控制台输出信息

问题描述 我在一个C#Windows应用程序中启动一个控制台程序,这个控制台程序输了很多信息我怎么才能在C#windows应用程序中获得这些信息 解决方案 解决方案二:是不是什么重定向??学习解决方案三:专业接分,参考http://blog.csdn.net/jinjazz/archive/2008/05/07/2413039.aspx解决方案四:引用2楼jinjazz的回复: 专业接分,参考http://blog.csdn.net/jinjazz/archive/2008/05/07/2413

android开发中获取手机上可用SD卡方法分享

现在的android手机型号复杂多样,造成了开发过程中使用官方的获取sd卡的方法在部分的手机上并不适用,所以需要进行开发的自己封装,以下就是代码,希望分享出来,大家共同学习 /*** 获取手机sd卡的工具类* @author wy*/public class SDCardUtils {/** avoid initializations of tool classes*/private SDCardUtils() {// TODO Auto-generated constructor stub}

Android中获取手机屏幕大小的方法

本文为大家解析Android中如何获取手机屏幕大小,提供一个解决方法,分享给大家供大家参考,具体内容如下 运行效果图: 运行程序后,当我们点击Button按钮时,可以看到下面的效果图: 具体代码: 我们可以通过使用类DisplayMetrics来获取手机屏幕的分辨率大小.DisplayMetrics类是获取手机屏幕各种属性的关键类.下面通过例子来展示如何获取手机屏幕的分辨率. 在布局文件main.xml中添加一个TextView对象,一个Button对象.其中TextView对象用来显示获得的分

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

概述 在开发Silverlight应用程序时,我们经常会遇到这样一种情况,需要在Silverlight应用程序的 UserControl中获取ASP.NET页面参数,这个参数不一定来自于当前Silverlight应用程序的宿主页面,而 有可能来自于其它的ASP.NET页面. 需求 如下面的项目结构,我们会在Default.aspx页面中需要传递两个值到SilverlightTestPage.aspx页面 ,并且需要在SilverlightTestPage.aspx页面所宿主的Silverligh