共用方式為


ILocation::GetReportStatus 方法 (locationapi.h)

[Win32 位置 API 可用於需求一節中指定的作業系統。 它在後續版本中可能會變更或無法使用。 請改用 Windows.Devices.Geolocation API。 ]

擷取指定報表類型的狀態。

語法

HRESULT GetReportStatus(
  [in]  REFIID                 reportType,
  [out] LOCATION_REPORT_STATUS *pStatus
);

參數

[in] reportType

REFIID ,指定要取得間隔的報表類型。

[out] pStatus

接收指定報表目前狀態 之LOCATION_REPORT_STATUS 位址。

傳回值

方法會傳回 HRESULT。 可能的值包括 (但不限於) 下表中的這些值。

傳回碼 描述
S_OK
此方法已成功。
HRESULT_FROM_WIN32 (ERROR_NOT_SUPPORTED)
reportType 不是 IID_ILatLongReportIID_ICivicAddressReport
E_INVALIDARG
pStatusNull

備註

此方法會擷取新報表的報表狀態。 不論此方法所報告的狀態為何,最新的報告仍可透過 ILocation::GetReport取得。

已知問題

當應用程式第一次啟動時,或啟用新的定位感應器時, GetReportStatus 可能會在位置報告可用之前立即回報 REPORT_RUNNING 狀態。

因此, GetReport 的初始呼叫會傳回錯誤 (ERROR_NO_DATA) 或不是來自預期定位感應器的值,即使 GetReportStatus 指出 REPORT_RUNNING的狀態也一樣。 此錯誤會於下列情況發生:

  1. 應用程式會使用 GetReportStatus 輪詢狀態,直到傳回 REPORT_RUNNING 的報表狀態,然後呼叫 GetReport
  2. 應用程式啟動時會呼叫GetReportStatus。 這可能是在建立位置物件或呼叫 RequestPermissions之後發生。

應用程式可以藉由實作下列因應措施來減輕問題。 因應措施牽涉到訂閱位置報告事件。

因應措施:訂閱事件

應用程式可以訂閱報表事件,並等候 OnLocationChanged 事件或 OnStatusChanged 事件的報告。 應用程式應該等候指定的有限時間量。

下列範例顯示等候 ILatLongReport類型之位置報表的應用程式。 如果報表在指定的時間內成功擷取,則會印出訊息,指出已收到資料。

下列範例程式碼示範應用程式如何呼叫名為 WaitForLocationReport 的函式,以註冊事件並等候第一個位置報表。 WaitForLocationReport 會等候回呼物件所設定的事件。 WaitForLocationReport函式和回呼物件定義于遵循此函式的範例中。

// main.cpp
// An application that demonstrates how to wait for a location report.
// This sample waits for latitude/longitude reports but can be modified
// to wait for civic address reports by replacing IID_ILatLongReport 
// with IID_ICivicAddressReport in the following code.

#include "WaitForLocationReport.h"

#define DEFAULT_WAIT_FOR_LOCATION_REPORT 500 // Wait for half a second.

int wmain()
{
    // You may use the flags COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE
    // to specify the multi-threaded concurrency model.
    HRESULT hr = ::CoInitializeEx(NULL,
        COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); 
    if (SUCCEEDED(hr))
    {
        int args;
        PWSTR *pszArgList = ::CommandLineToArgvW(::GetCommandLineW(), &args);

        DWORD const dwTimeToWait = 
            (2 == args) ? static_cast<DWORD>(_wtoi(pszArgList[1])) : DEFAULT_WAIT_FOR_LOCATION_REPORT;

        ::LocalFree(pszArgList);

        wprintf_s(L"Wait time set to %lu\n", dwTimeToWait);

        ILocation *pLocation; // This is the main Location interface.
        hr = CoCreateInstance(CLSID_Location, NULL, CLSCTX_INPROC, IID_PPV_ARGS(&pLocation));
        if (SUCCEEDED(hr))
        {
            // Array of report types to listen for.
            // Replace IID_ILatLongReport with IID_ICivicAddressReport
            // for civic address reports.
            IID REPORT_TYPES[] = { IID_ILatLongReport }; 

            // Request permissions for this user account to receive location data for all the
            // types defined in REPORT_TYPES (which is currently just one report)
            // TRUE means a synchronous request.
            if (FAILED(pLocation->RequestPermissions(NULL, REPORT_TYPES, ARRAYSIZE(REPORT_TYPES), TRUE))) 
            {
                wprintf_s(L"Warning: Unable to request permissions.\n");
            }

            ILocationReport *pLocationReport; // This is our location report object
            // Replace IID_ILatLongReport with IID_ICivicAddressReport for civic address reports
            hr = ::WaitForLocationReport(pLocation, IID_ILatLongReport, dwTimeToWait, &pLocationReport);
            if (SUCCEEDED(hr))
            {
                wprintf_s(L"Successfully received data via GetReport().\n");
                pLocationReport->Release();
            }
            else if (RPC_S_CALLPENDING == hr)
            {
                wprintf_s(L"No LatLong data received.  Wait time of %lu elapsed.\n", dwTimeToWait);
            }
            pLocation->Release();
        }

        ::CoUninitialize();
    }

    return 0;
}

下列範例程式碼會分成 WaitForLocationReport.h 和 WaitForLocationReport.cpp。 WaitForLocationReport.h 包含 WaitForLocationReport 函式的標頭。 WaitForLocationReport.cpp 包含 WaitForLocationReport 函式的定義,以及其所使用的回呼物件定義。 回檔物件提供 OnLocationChangedOnStatusChanged 回 呼方法的實作。 在這些方法中,它會設定事件,以在報表可供使用時發出訊號。

// WaitForLocationReport.h
// Header for the declaration of the WaitForLocationReport function.

#pragma once

#include <windows.h>
#include <LocationApi.h>
#include <wchar.h>

HRESULT WaitForLocationReport(
    ILocation* pLocation,              // Location object.
    REFIID reportType,                 // Type of report.
    DWORD dwTimeToWait,                // Milliseconds to wait.
    ILocationReport** ppLocationReport // Receives the location report.
);

// WaitForLocationReport.cpp
// Contains definitions of the WaitForLocationReport function and
// the callback object that it uses.

#include "WaitForLocationReport.h"
#include <shlwapi.h>
#include <new>

// Implementation of the callback interface that receives location reports.
class CLocationCallback : public ILocationEvents
{
public:
    CLocationCallback() : _cRef(1), _hDataEvent(::CreateEvent(
        NULL,  // Default security attributes.
        FALSE, // Auto-reset event.
        FALSE, // Initial state is nonsignaled.
        NULL)) // No event name.
    {
    }

    virtual ~CLocationCallback()
    {
        if (_hDataEvent)
        {
            ::CloseHandle(_hDataEvent);
        }
    }

    IFACEMETHODIMP QueryInterface(REFIID riid, void **ppv)
    {
        if ((riid == IID_IUnknown) || 
            (riid == IID_ILocationEvents))
        {
            *ppv = static_cast<ILocationEvents*>(this);
        }
        else
        {
            *ppv = NULL;
            return E_NOINTERFACE;
        }
        AddRef();
        return S_OK;
    }

    IFACEMETHODIMP_(ULONG) AddRef()
    {
        return InterlockedIncrement(&_cRef);
    }

    IFACEMETHODIMP_(ULONG) Release()
    {
        long cRef = InterlockedDecrement(&_cRef);
        if (!cRef)
        {
            delete this;
        }
        return cRef;
    }

    // ILocationEvents

    // This is called when there is a new location report.
    IFACEMETHODIMP OnLocationChanged(REFIID /*reportType*/, ILocationReport* /*pLocationReport*/)
    {
        ::SetEvent(_hDataEvent);
        return S_OK;
    }

    // This is called when the status of a report type changes.
    // The LOCATION_REPORT_STATUS enumeration is defined in LocApi.h in the SDK
    IFACEMETHODIMP OnStatusChanged(REFIID /*reportType*/, LOCATION_REPORT_STATUS status)
    {
        if (REPORT_RUNNING == status)
        {
            ::SetEvent(_hDataEvent);
        }
        return S_OK;
    }

    HANDLE GetEventHandle()
    {
        return _hDataEvent;
    }

private:
    long _cRef;
    HANDLE _hDataEvent;    // Data Event Handle
};

// Waits to receive a location report. 
// This function waits for the callback object to signal when
// a report event or status event occurs, and then calls GetReport.
// Even if no report event or status event is received before the timeout,
// this function still queries for the last known report by calling GetReport.
// The last known report may be cached data from a location sensor that is not
// reporting events, or data from the default location provider.
//
// Returns S_OK if the location report has been returned
// or RPC_S_CALLPENDING if the timeout expired.
HRESULT WaitForLocationReport(
    ILocation* pLocation,               // Location object.
    REFIID reportType,                 // Type of report to wait for.
    DWORD dwTimeToWait,                // Milliseconds to wait.
    ILocationReport **ppLocationReport // Receives the location report.
    )
{
    *ppLocationReport = NULL;

    CLocationCallback *pLocationCallback = new(std::nothrow) CLocationCallback();
    HRESULT hr = pLocationCallback ? S_OK : E_OUTOFMEMORY;
    if (SUCCEEDED(hr))
    {
        HANDLE hEvent = pLocationCallback->GetEventHandle();
        hr = hEvent ? S_OK : E_FAIL;
        if (SUCCEEDED(hr))
        {
            // Tell the Location API that we want to register for a report. 
            hr = pLocation->RegisterForReport(pLocationCallback, reportType, 0);
            if (SUCCEEDED(hr))
            {
                DWORD dwIndex;
                HRESULT hrWait = CoWaitForMultipleHandles(0, dwTimeToWait, 1, &hEvent, &dwIndex);
                if ((S_OK == hrWait) || (RPC_S_CALLPENDING == hrWait))
                {
                    // Even if there is a timeout indicated by RPC_S_CALLPENDING
                    // attempt to query the report to return the last known report.
                    hr = pLocation->GetReport(reportType, ppLocationReport);
                    if (FAILED(hr) && (RPC_S_CALLPENDING == hrWait))
                    {
                        // Override hr error if the request timed out and
                        // no data is available from the last known report.  
                        hr = hrWait;    // RPC_S_CALLPENDING
                    }
                }
                // Unregister from reports from the Location API.
                pLocation->UnregisterForReport(reportType);
            }
        }
        pLocationCallback->Release();
    }
    return hr;
}

需求

   
最低支援的用戶端 Windows 7 [僅限傳統型應用程式],Windows 7
最低支援的伺服器 都不支援
目標平台 Windows
標頭 locationapi.h
Dll LocationAPI.dll

另請參閱

ILocation