ILocation::GetReportStatus メソッド (locationapi.h)
[Win32 Location API は、[要件] セクションで指定されたオペレーティング システムで使用できます。 今後のバージョンでは変更されるか、利用できなくなる場合もあります。 代わりに、 Windows.Devices.Geolocation API を使用します。 ]
指定したレポートの種類の状態を取得します。
構文
HRESULT GetReportStatus(
[in] REFIID reportType,
[out] LOCATION_REPORT_STATUS *pStatus
);
パラメーター
[in] reportType
間隔を取得するレポートの種類を指定する REFIID。
[out] pStatus
指定 したレポート の現在の状態を受け取るLOCATION_REPORT_STATUSのアドレス。
戻り値
このメソッドは HRESULT を返します。 有効な値を次の表に示しますが、これ以外にもあります。
リターン コード | 説明 |
---|---|
|
メソッドが成功しました。 |
|
reportType は、 IID_ILatLongReport または IID_ICivicAddressReport以外です。 |
|
pStatus は NULL です。 |
解説
このメソッドは、新しいレポートのレポートの状態を取得します。 このメソッドによって報告された状態に関係なく、最新のレポートは ILocation::GetReport を通じて引き続き使用できます。
既知の問題
アプリケーションが最初に起動されたとき、または新しい場所センサーが有効になっている場合、 GetReportStatus は、場所レポートが使用可能になる直前に 、REPORT_RUNNING の状態を報告する場合があります。したがって、 GetReportStatus がREPORT_RUNNINGの状態を示している場合でも、 GetReport を最初に呼び出すと、エラー ( ERROR_NO_DATA) または予期される場所センサーからの値が返されます。 これは、次のケースで発生する可能性があります。
- アプリケーションは、REPORT_RUNNINGのレポートの状態が返されるまで GetReportStatus を使用して状態をポーリングし、GetReport を呼び出します。
- 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 関数の定義と、その関数が使用するコールバック オブジェクトの定義が含まれています。 コールバック オブジェクトは、OnLocationChanged および OnStatusChanged コールバック メソッドの実装を提供します。 これらのメソッド内では、レポートが使用可能になったときに通知するイベントを設定します。
// 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 |