Condividi tramite


Metodo ILocation::GetReportStatus (locationapi.h)

[L'API Location Win32 è disponibile per l'uso nei sistemi operativi specificati nella sezione Requisiti. È possibile che in versioni successive sia stata modificata o non sia più disponibile. Usare invece l'API Windows.Devices.Geolocation . ]

Recupera lo stato per il tipo di report specificato.

Sintassi

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

Parametri

[in] reportType

REFIID che specifica il tipo di report per il quale ottenere l'intervallo.

[out] pStatus

Indirizzo di un LOCATION_REPORT_STATUS che riceve lo stato corrente per il report specificato.

Valore restituito

Il metodo restituisce un valore HRESULT. I valori possibili includono, ma non sono limitati a, quelli indicati nella tabella seguente.

Codice restituito Descrizione
S_OK
Il metodo è riuscito.
HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED)
reportType è diverso da IID_ILatLongReport o IID_ICivicAddressReport.
E_INVALIDARG
pStatus è NULL.

Commenti

Questo metodo recupera lo stato del report per i nuovi report. I report più recenti rimangono disponibili tramite ILocation::GetReport, indipendentemente dallo stato segnalato da questo metodo.

Problemi noti

Quando un'applicazione viene avviata per la prima volta o quando è abilitato un nuovo sensore di posizione, GetReportStatus potrebbe segnalare uno stato di REPORT_RUNNING poco prima che il report sulla posizione sia disponibile.

Pertanto, una chiamata iniziale a GetReport restituirà un errore (ERROR_NO_DATA) o un valore che non proviene dal sensore di posizione previsto, anche se GetReportStatus indica lo stato di REPORT_RUNNING. Ciò può verificarsi nei casi seguenti:

  1. L'applicazione esegue il polling dello stato usando GetReportStatus fino a quando non viene restituito lo stato del report di REPORT_RUNNING e quindi chiama GetReport.
  2. GetReportStatus viene chiamato all'avvio dell'applicazione. Ciò può verificarsi dopo la creazione dell'oggetto location o dopo aver chiamato RequestPermissions.

Un'applicazione può attenuare il problema implementando la soluzione alternativa seguente. La soluzione alternativa prevede la sottoscrizione degli eventi del report sulla posizione.

Soluzione alternativa: sottoscrizione di eventi

L'applicazione può sottoscrivere eventi di report e attendere il report dall'evento OnLocationChanged o dall'evento OnStatusChanged . L'applicazione deve attendere un periodo di tempo finito specificato.

Nell'esempio seguente viene illustrata un'applicazione che attende un report sulla posizione di tipo ILatLongReport. Se un report viene recuperato correttamente entro l'intervallo di tempo specificato, viene visualizzato un messaggio che indica che i dati sono stati ricevuti.

Il codice di esempio seguente illustra come un'applicazione può chiamare una funzione denominata WaitForLocationReport che registra gli eventi e attende il primo report sulla posizione. WaitForLocationReport attende un evento impostato da un oggetto callback. La funzione WaitForLocationReport e l'oggetto callback sono definiti negli esempi seguenti.

// 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;
}

Il codice di esempio seguente è separato in WaitForLocationReport.h e WaitForLocationReport.cpp. WaitForLocationReport.h contiene l'intestazione per la funzione WaitForLocationReport . WaitForLocationReport.cpp contiene la definizione della funzione WaitForLocationReport e la definizione dell'oggetto callback utilizzato. L'oggetto callback fornisce implementazioni dei metodi di callback OnLocationChanged e OnStatusChanged . All'interno di questi metodi, imposta un evento che segnala quando è disponibile un report.

// 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;
}

Requisiti

   
Client minimo supportato Windows 7 [solo app desktop],Windows 7
Server minimo supportato Nessuno supportato
Piattaforma di destinazione Windows
Intestazione locationapi.h
DLL LocationAPI.dll

Vedi anche

ILocation