정보
요청한 주제가 아래에 표시됩니다. 그러나 이 주제는 이 라이브러리에 포함되지 않습니다.

Windows Phone 8에 대한 휴대폰의 현재 위치를 가져오는 방법

2014-06-18

적용 대상: Windows Phone 8 및 Windows Phone Silverlight 8.1만

 

이 항목에서는 Windows Phone 위치 API를 사용하여 휴대폰의 현재 위치를 확인하는 방법을 보여 줍니다. 앱에 현재 시간의 사용자 위치만 필요한 경우(예: 특정 위치에서 사용자를 체크인하기 위해 또는 위치 기반 검색을 수행하기 위해)에는 위치 정보를 가져오는 데 이 방법을 사용하는 것이 좋습니다. 이 방법은 연속 추적을 사용하는 것보다 휴대폰 배터리 수명에 훨씬 더 좋습니다. 연속적으로 위치를 업데이트해야 하는 경우 Windows Phone 8에 대한 휴대폰의 위치를 연속적으로 추적하는 방법을 참조하세요.

중요중요:

앱에서 위치 API를 사용하려면 앱 매니페스트 파일에 ID_CAP_LOCATION 기능을 넣어야 합니다. 이렇게 하지 않으면 개발하는 동안 앱을 배포할 때 앱에 예외가 발생되고 앱을 Windows Phone 스토어 로 전송할 때 앱이 통합되지 못합니다. 자세한 내용은 Windows Phone 8의 앱 기능 및 하드웨어 요구 사항을 참조하세요.

팁팁:

Windows 런타임 위치 API는 Windows Phone 8 앱과 Windows Phone 8.1 앱에서 모두 지원됩니다. 이 항목은 Windows Phone 8 설명서의 일부입니다. 이 기능에 대한 정보를 보려면 휴대폰 및 PC의 개발 정보를 포함하고 있는 Windows Phone 8.1 설명서에서 지리적 위치 검색을 참조하세요.

휴대폰의 현재 위치 가져오기

  1. Visual Studio 에서 새 Windows Phone 앱을 만듭니다.

  2. 솔루션 탐색기에서 속성 폴더를 확장한 다음 WMAppManifest.xml을 두 번 클릭합니다.

  3. 매니페스트 디자이너의 기능 탭에서 ID_CAP_LOCATION 옆에 있는 확인란을 선택합니다.

  4. MainPage.xaml에서 ContentPanel이라는 기존 Grid 요소에 다음 XAML 코드를 붙여 넣습니다. 이 코드는 위치 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" 키에 저장됩니다. 이 키는 앱이 사용자의 위치에 액세스하려고 하기 전에 확인됩니다.

  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)
    {
        Geolocator geolocator = new Geolocator();
        geolocator.DesiredAccuracyInMeters = 50;
    
        try
        {
            Geoposition geoposition = await geolocator.GetGeopositionAsync(
                maximumAge: TimeSpan.FromMinutes(5),
                timeout: TimeSpan.FromSeconds(10)
                );
    
            Dispatcher.BeginInvoke(() =>
            {
                LatitudeTextBlock.Text = geoposition.Coordinate.Latitude.ToString("0.00");
                LongitudeTextBlock.Text = geoposition.Coordinate.Longitude.ToString("0.00");
            });
        }
        catch (UnauthorizedAccessException)
        {
            // the application does not have the right capability or the location master switch is off
            StatusTextBlock.Text = "location  is disabled in phone settings.";
        }
        catch (Exception ex)
        {
            // something else happened acquring the location
            // ex.HResult can be read to know the specific error code but it is not recommended
        }
    }
    
    
    

네이티브 코드를 사용하여 휴대폰의 현재 위치 가져오기

  1. 이 연습에서는 IAsyncOperation을 사용하여 휴대폰 위치 가져오기의 비동기 작업을 보여 줍니다. 이 개체는 위치를 가져오는 동안 범위를 벗어나지 않으므로 헤더에서 해당 개체에 대한 클래스 멤버 변수를 선언하는 것이 좋습니다.

    
    	Windows::Foundation::IAsyncOperation<Windows::Devices::Geolocation::Geoposition^>^ m_getOperation;
    
    
    
  2. 이 예제에서는 위치 API가 사용된 GetOneShotLocation 메서드도 선언합니다. 이 메서드는 결과의 원하는 정확도(미터), 시스템이 시간 초과되기 전에 위치 결과를 가져올 때까지 대기해야 하는 최대 시간(초 수) 및 위치 결과의 최대 사용 기간(초)을 나타내는 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 개체를 반환합니다.

    다음으로 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
    				}
                }
            });
    }
    
    
    

표시: