LocationProvider Interface¶
Sometimes the user asks Alexa a question that requires she know the location in order to answer properly. For example, a user in San Francisco, California might say "Alexa, what's the weather?". This user probably wants to hear Alexa say something like "The weather in San Francisco is sixty-five degrees and overcast..." rather than something like "I can't find your exact location right now...". Similarly, the user might say "Alexa, take me to the nearest Whole Foods" and wants Alexa to start navigation to a Whole Foods that is actually nearby.
To provide the user with accurate responses to local search commands, weather questions, and more, obtain the user's consent to share their location with Alexa and use the LocationProvider
interface.
Your application should subscribe to the LocationProvider.GetLocation
and LocationProvider.GetCountry
messages to provide location data, such as geographic coordinates and vehicle operating country, when the Engine requests it. These messages are synchronous-style and require your application to send the corresponding reply messages right away. To avoid blocking the MessageBroker outgoing thread and delaying user requests to Alexa, your application should keep the location data in a cache that you update frequently. Pull the location from the cache when the Engine requests it.
The Engine won't publish the GetLocation
message if it knows your application has lost access to the location data. Keep the Engine in sync with the state of your application's location provider availability by proactively publishing the LocationServiceAccessChanged
message at startup and each time the state changes. For example, your application might publish this message with access
set to DISABLED
if the system revokes your application's access to location or if GPS turns off.
Note: The Engine does not persist this state across device reboots. To ensure the Engine always knows the initial state of location availability, publish a
LocationServiceAccessChanged
message each time you start the Engine. This includes notifying the Engine thataccess
isENABLED
.
Click to expand or collapse C++ example code
#include <AACE/Core/MessageBroker.h>
#include <AASB/Message/Location/LocationProvider/GetCountryMessage.h>
#include <AASB/Message/Location/LocationProvider/GetLocationMessage.h>
#include <AASB/Message/Location/LocationProvider/LocationServiceAccessChangedMessage.h>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
class MyLocationProviderHandler {
// Call before you start the Engine
void MyLocationProviderHandler::subscribeToAASBMessages() {
messageBroker->subscribe(
[=](const std::string& message) { handleGetCountryMessage(message); },
GetCountryMessage::topic(),
GetCountryMessage::action());
messageBroker->subscribe(
[=](const std::string& message) { handleGetLocationMessage(message); },
GetLocationMessage::topic(),
GetLocationMessage::action());
}
void MyLocationProviderHandler::handleGetCountryMessage(const std::string& message) {
GetCountryMessage msg = json::parse(message);
// Quickly publish the GetCountry reply message
auto country = getCountryFromCache(); // implement this stub
GetCountryMessageReply replyMsg;
replyMsg.header.messageDescription.replyToId = msg.header.id;
replyMsg.payload.country = country;
messageBroker->publish(replyMsg.toString());
}
void MyLocationProviderHandler::handleGetLocationMessage(const std::string& message) {
GetLocationMessage msg = json::parse(message);
// Quickly publish the GetCountry reply message
auto location = getLocationFromCache(); // implement this stub
GetLocationMessageReply replyMsg;
replyMsg.header.messageDescription.replyToId = msg.header.id;
// parse "location" and populate the fields of the reply message
aasb::message::location::locationProvider::Location replyLocation;
replyLocation.latitude = ... ; // the latitude from "location";
replyLocation.longitude = ... ; // the longitude from "location";
replyMsg.payload.location = replyLocation;
messageBroker->publish(replyMsg.toString());
}
// Call when the application access to location data changes
// and after starting the Engine
void MyLocationProviderHandler::locationServiceAccessChanged(bool hasAccess) {
LocationServiceAccessChangedMessage msg;
if (hasAccess) {
msg.payload.access = aasb::message::location::locationProvider::LocationServiceAccess::ENABLED;
} else {
msg.payload.access = aasb::message::location::locationProvider::LocationServiceAccess::DISABLED;
}
messageBroker->publish(msg.toString());
}
}