ILocation::GetReportStatus-Methode (locationapi.h)
[Die Win32-Standort-API ist für die Verwendung in den im Abschnitt Anforderungen angegebenen Betriebssystemen verfügbar. Es kann in nachfolgenden Versionen geändert oder entfernt werden. Verwenden Sie stattdessen die Windows.Devices.Geolocation-API . ]
Ruft die status für den angegebenen Berichtstyp ab.
Syntax
HRESULT GetReportStatus(
[in] REFIID reportType,
[out] LOCATION_REPORT_STATUS *pStatus
);
Parameter
[in] reportType
REFIID , das den Berichtstyp angibt, für den das Intervall abgerufen werden soll.
[out] pStatus
Adresse eines LOCATION_REPORT_STATUS, der die aktuelle status für den angegebenen Bericht empfängt.
Rückgabewert
Die Methode gibt ein HRESULT zurück. Mögliches Werte (aber nicht die Einzigen) sind die in der folgenden Tabelle.
Rückgabecode | BESCHREIBUNG |
---|---|
|
Die Methode wurde erfolgreich ausgeführt. |
|
reportType ist nicht IID_ILatLongReport oder IID_ICivicAddressReport. |
|
pStatus ist NULL. |
Hinweise
Diese Methode ruft Berichts-status für neue Berichte ab. Die neuesten Berichte bleiben über ILocation::GetReport verfügbar, unabhängig von den von dieser Methode gemeldeten status.
Bekannte Probleme
Wenn eine Anwendung zum ersten Mal gestartet wird oder ein neuer Standortsensor aktiviert ist, meldet GetReportStatus möglicherweise eine status REPORT_RUNNING, kurz bevor der Standortbericht verfügbar ist.Daher gibt ein anfänglicher Aufruf von GetReport einen Fehler (ERROR_NO_DATA) oder einen Wert zurück, der nicht vom erwarteten Standortsensor stammt, auch wenn GetReportStatus eine status von REPORT_RUNNING angibt. Dies kann in den folgenden Situationen auftreten:
- Die Anwendung ruft status mithilfe von GetReportStatus ab, bis ein Bericht status von REPORT_RUNNING zurückgegeben wird, und ruft dann GetReport auf.
- GetReportStatus wird aufgerufen, wenn die Anwendung gestartet wird. Dies kann nach der Erstellung des Location-Objekts oder nach dem Aufruf von RequestPermissions auftreten.
Eine Anwendung kann das Problem beheben, indem sie die folgende Problemumgehung implementiert. Die Problemumgehung umfasst das Abonnieren von Standortberichtsereignissen.
Problemumgehung: Abonnieren von Ereignissen
Die Anwendung kann Berichtsereignisse abonnieren und auf den Bericht aus dem OnLocationChanged-Ereignis oder dem OnStatusChanged-Ereignis warten. Die Anwendung sollte auf eine bestimmte begrenzte Zeit warten.Das folgende Beispiel zeigt eine Anwendung, die auf einen Speicherortbericht vom Typ ILatLongReport wartet. Wenn ein Bericht innerhalb der angegebenen Zeitspanne erfolgreich abgerufen wurde, wird eine Meldung ausgegeben, die angibt, dass Daten empfangen wurden.
Der folgende Beispielcode veranschaulicht, wie eine Anwendung eine Funktion namens WaitForLocationReport aufrufen kann, die sich für Ereignisse registriert und auf den ersten Standortbericht wartet. WaitForLocationReport wartet auf ein Ereignis, das von einem Rückrufobjekt festgelegt wird. Die Funktion WaitForLocationReport und das Rückrufobjekt sind in den folgenden Beispielen definiert.
// 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;
}
Der folgende Beispielcode ist in WaitForLocationReport.h und WaitForLocationReport.cpp getrennt. WaitForLocationReport.h enthält den Header für die WaitForLocationReport-Funktion . WaitForLocationReport.cpp enthält die Definition der WaitForLocationReport-Funktion und die Definition des rückrufobjekts, das sie verwendet. Das Rückrufobjekt stellt Implementierungen der Rückrufmethoden OnLocationChanged und OnStatusChanged bereit. Innerhalb dieser Methoden wird ein Ereignis festgelegt, das signalisiert, wann ein Bericht verfügbar ist.
// 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;
}
Anforderungen
Unterstützte Mindestversion (Client) | Windows 7 [nur Desktop-Apps],Windows 7 |
Unterstützte Mindestversion (Server) | Nicht unterstützt |
Zielplattform | Windows |
Kopfzeile | locationapi.h |
DLL | LocationAPI.dll |