Bagikan melalui


ILocation::Metode GetReportStatus (locationapi.h)

[API Lokasi Win32 tersedia untuk digunakan dalam sistem operasi yang ditentukan di bagian Persyaratan. Ini mungkin diubah atau tidak tersedia dalam versi berikutnya. Sebagai gantinya, gunakan API Windows.Devices.Geolocation . ]

Mengambil status untuk jenis laporan yang ditentukan.

Sintaks

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

Parameter

[in] reportType

REFIID yang menentukan jenis laporan untuk mendapatkan interval.

[out] pStatus

Alamat LOCATION_REPORT_STATUS yang menerima status saat ini untuk laporan yang ditentukan.

Mengembalikan nilai

Metode mengembalikan HRESULT. Nilai yang mungkin termasuk, tetapi tidak terbatas pada, yang ada dalam tabel berikut.

Menampilkan kode Deskripsi
S_OK
Metode berhasil.
HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED)
reportType selain IID_ILatLongReport atau IID_ICivicAddressReport.
E_INVALIDARG
pStatus adalah NULL.

Keterangan

Metode ini mengambil status laporan untuk laporan baru. Laporan terbaru tetap tersedia melalui ILocation::GetReport, terlepas dari status yang dilaporkan oleh metode ini.

Masalah yang Diketahui

Saat aplikasi pertama kali dimulai, atau saat sensor lokasi baru diaktifkan, GetReportStatus dapat melaporkan status REPORT_RUNNING tak lama sebelum laporan lokasi tersedia.

Oleh karena itu, panggilan awal ke GetReport akan mengembalikan kesalahan (ERROR_NO_DATA) atau nilai yang bukan dari sensor lokasi yang diharapkan, bahkan jika GetReportStatus menunjukkan status REPORT_RUNNING. Hal ini dapat terjadi dalam situasi berikut:

  1. Aplikasi melakukan polling untuk status dengan menggunakan GetReportStatus hingga status laporan REPORT_RUNNING dikembalikan, lalu memanggil GetReport.
  2. GetReportStatus dipanggil saat aplikasi dimulai. Ini dapat terjadi setelah pembuatan objek lokasi, atau setelah memanggil RequestPermissions.

Aplikasi dapat mengurangi masalah dengan menerapkan solusi berikut. Solusinya melibatkan berlangganan peristiwa laporan lokasi.

Solusi sementara: Berlangganan Peristiwa

Aplikasi dapat berlangganan untuk melaporkan peristiwa dan menunggu laporan dari peristiwa OnLocationChanged atau peristiwa OnStatusChanged . Aplikasi harus menunggu waktu yang ditentukan.

Contoh berikut menunjukkan aplikasi yang menunggu laporan lokasi jenis ILatLongReport. Jika laporan berhasil diambil dalam jumlah waktu yang ditentukan, laporan akan mencetak pesan yang menunjukkan bahwa data diterima.

Contoh kode berikut menunjukkan bagaimana aplikasi dapat memanggil fungsi bernama WaitForLocationReport yang mendaftar untuk peristiwa dan menunggu laporan lokasi pertama. WaitForLocationReport menunggu peristiwa yang diatur oleh objek panggilan balik. Fungsi WaitForLocationReport dan objek panggilan balik ditentukan dalam contoh yang mengikuti yang satu ini.

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

Contoh kode berikut dipisahkan menjadi WaitForLocationReport.h dan WaitForLocationReport.cpp. WaitForLocationReport.h berisi header untuk fungsi WaitForLocationReport . WaitForLocationReport.cpp berisi definisi fungsi WaitForLocationReport dan definisi objek panggilan balik yang digunakannya. Objek panggilan balik menyediakan implementasi metode panggilan balik OnLocationChanged dan OnStatusChanged . Dalam metode ini, ia mengatur peristiwa yang memberi sinyal ketika laporan tersedia.

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

Persyaratan

   
Klien minimum yang didukung Windows 7 [hanya aplikasi desktop],Windows 7
Server minimum yang didukung Tidak ada yang didukung
Target Platform Windows
Header locationapi.h
DLL LocationAPI.dll

Lihat juga

ILokasi