I am getting the following message when trying to analyze an utterance with LUIS using the cognitive service android SDK:
Final result received: Intent failed with Canceled. Did you enter your Language Understanding subscription? WebSocket Upgrade failed with an authentication error (403). Please check the subscription key or the authorization token, and the region name., intent:
I am able to get an utterance evaluation via REST using the same Subscription key , and App ID passed to the SpeechFactory methods.
Moreover, continuous recognition through the Android SDK works as well.
Anyone is getting my same issue ?
source available at https://github.com/Azure-Samples/cognitive-services-speech-sdk/blob/master/samples/java/android/sdkdemo/app/src/main/java/com/microsoft/cognitiveservices/speech/samples/sdkdemo/MainActivity.java .
Code here:
recognizeIntentButton.setOnClickListener(view -> {
final String logTag = "intent";
final ArrayList<String> content = new ArrayList<>();
disableButtons();
clearTextBox();
content.add("");
content.add("");
try {
final SpeechFactory intentFactory = SpeechFactory.fromSubscription(LanguageUnderstandingSubscriptionKey, LanguageUnderstandingServiceRegion);
final IntentRecognizer reco = intentFactory.createIntentRecognizerWithStream(createMicrophoneStream());
LanguageUnderstandingModel intentModel = LanguageUnderstandingModel.fromAppId(LanguageUnderstandingAppId);
for (Map.Entry<String, String> entry : intentIdMap.entrySet()) {
reco.addIntent(entry.getKey(), intentModel, entry.getValue());
}
reco.IntermediateResultReceived.addEventListener((o, intentRecognitionResultEventArgs) -> {
final String s = intentRecognitionResultEventArgs.getResult().getText();
Log.i(logTag, "Intermediate result received: " + s);
content.set(0, s);
setRecognizedText(TextUtils.join(System.lineSeparator(), content));
});
final Future<IntentRecognitionResult> task = reco.recognizeAsync();
setOnTaskCompletedListener(task, result -> {
Log.i(logTag, "Continuous recognition stopped.");
String s = result.getText();
if (result.getReason() != RecognitionStatus.Recognized) {
s = "Intent failed with " + result.getReason() + ". Did you enter your Language Understanding subscription?" + System.lineSeparator() + result.getErrorDetails();
}
String intentId = result.getIntentId();
String intent = "";
if (intentIdMap.containsKey(intentId)) {
intent = intentIdMap.get(intentId);
}
Log.i(logTag, "Final result received: " + s + ", intent: " + intent);
content.set(0, s);
content.set(1, " [intent: " + intent + "]");
setRecognizedText(TextUtils.join(System.lineSeparator(), content));
enableButtons();
});
} catch (Exception ex) {
System.out.println(ex.getMessage());
displayException(ex);
}
});
}
Related
How do I get this Default response in Android?
I want to get the same response as I get doing this CURL request in android. Is there a way to do this using API.AI SDK or otherwise?
You can use Dialogflow Android SDK. Check the documentation for integration and accessing the Dialogflow agent.
Get action
final Result result = response.getResult();
Log.i(TAG, "Action: " + result.getAction());
Get speech
final Result result = response.getResult();
final String speech = result.getFulfillment().getSpeech();
Log.i(TAG, "Speech: " + speech);
Get metadata
final Result result = response.getResult();
final Metadata metadata = result.getMetadata();
if (metadata != null) {
Log.i(TAG, "Intent id: " + metadata.getIntentId());
Log.i(TAG, "Intent name: " + metadata.getIntentName());
}
Get parameters
final Result result = response.getResult();
final HashMap<String, JsonElement> params = result.getParameters();
if (params != null && !params.isEmpty()) {
Log.i(TAG, "Parameters: ");
for (final Map.Entry<String, JsonElement> entry : params.entrySet()) {
Log.i(TAG, String.format("%s: %s", entry.getKey(), entry.getValue().toString()));
}
}
My Referee watch creates a Google Fit Session using the following code:
private void insertFitSession(final Game currentGame, final Period period,
final long periodStartTime, final long periodEndTime) {
//add the detailed Sensor data (using History API) if available
boolean activityWasInserted = false;
if (!RefWatchUtil.isRefWatchFree()) {
//If there are speeds then we will insert an activity
//4.5.09: Unfortunately mFitnessDataSets[] can have leftover data from a period where you did track fitness
//So we had to replace with period-by-period dataSets
activityWasInserted = (period.getFitnessDataSet(SPEED_LISTENER_IDX) != null)
&& !period.getFitnessDataSet(SPEED_LISTENER_IDX).isEmpty();
}
//create a Session in Google Fit for the period that just completed
//(this happens even for Free)
try {
String sessionBaseName = currentGame.getTitle();
if (sessionBaseName.isEmpty()) sessionBaseName = currentGame.getLocation();
if (sessionBaseName.isEmpty()) sessionBaseName = RefWatchUtil.timeMillisToDefaultShortDateTime(currentGame.getStartTimeMillis());
final String sessionName = sessionBaseName + ": " + String.format(getResources().getString(R.string.fitness_period_label), period.getPeriodNum());
final Session.Builder fitnessSessionBuilder = new Session.Builder();
fitnessSessionBuilder
.setName(sessionName)
.setIdentifier(sessionName)
.setDescription(mCurrentGame.getDescription())
.setStartTime(periodStartTime, TimeUnit.MILLISECONDS)
.setEndTime(periodEndTime, TimeUnit.MILLISECONDS);
//If we're Free, then we don't have real fitness session data and just guess at Jogging
// (also if we have no Activity data in Pro)
if (RefWatchUtil.isRefWatchFree() || !activityWasInserted) {
fitnessSessionBuilder.setActivity(FitnessActivities.RUNNING_JOGGING);
}
final Session fitSession = fitnessSessionBuilder.build();
SessionInsertRequest insertRequest = new SessionInsertRequest.Builder()
.setSession(fitSession)
.build();
Fitness.SessionsApi.insertSession(mFitnessApiClient, insertRequest)
.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(#NonNull Status status) {
if (status.isSuccess()) {
Log.d(TAG, "Successfully inserted Session " + sessionName);
} else {
Log.d(TAG, "There was a problem inserting the session " + sessionName
+ ": " + status.getStatusCode() + " " + status.getStatusMessage());
}
}
});
} catch (RuntimeException e){
Log.e(TAG, "There was a runtime exception inserting the session: " + e.getLocalizedMessage());
}
}
Note the sessionName defaults to either Title, Location, or Time appended with the current Period. This has been working great.
Recently (last month or so?) the Fit session is correctly inserted (I can track it in the log) but the Name doesn't stick. Instead I get "25 min running" for some, but not all, of them.
Has anybody else experienced this type of override by Fit?
Receiving:
SignatureDoesNotMatchThe request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.
With the following:
String associateTag = "example-20";
String awsAccessKeyId = "accessKeyId";
String awsSecretKey = "secretKey";
String endpoint = "webservices.amazon.com";
String uri = "/onca/xml";
String charset = "UTF8";
private String buildQueryString(String keywords) {
Map<String,String> params = new ArrayMap<>();
List<String> pairs = new ArrayList<>();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
params.put("Service","AWSECommerceService");
params.put("Operation","ItemSearch");
params.put("AWSAccessKeyId",awsAccessKeyId);
params.put("AssociateTag",associateTag);
params.put("SearchIndex","All");
params.put("ResponseGroup","Images,ItemAttributes");
params.put("Timestamp",sdf.format(new Date()));
params.put("Keywords", keywords);
Map<String, String> treeMap = new TreeMap<>(params);
try {
for (Map.Entry<String, String> param : treeMap.entrySet()) {
pairs.add(URLEncoder.encode(param.getKey(), charset) + "=" + URLEncoder.encode(param.getValue(), charset));
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String queryString = "";
for (int i = 0; i < pairs.size(); i++) {
if (i != 0) {
queryString += "&";
}
queryString += pairs.get(i);
}
Log.d(TAG, "queryString: " + queryString);
return queryString;
}
private String buildSignature(String queryString) {
String hash = "";
try {
String message = "GET\n" + endpoint + "\n" + uri + "\n" + queryString;
Log.d(TAG, "message: " + message);
Mac sha_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(awsSecretKey.getBytes(charset), "HmacSHA256");
sha_HMAC.init(secret_key);
hash = Base64.encodeToString(sha_HMAC.doFinal(message.getBytes(charset)), Base64.DEFAULT);
}
catch (Exception e){
System.out.println("Error");
}
return hash;
}
public void searchProducts(String keywords) {
String requestUrl = "";
String queryString = buildQueryString(keywords);
String signature = buildSignature(queryString);
Log.d(TAG, "signature: " + signature);
try {
requestUrl = "http://" + endpoint + uri + "?" + queryString + "&Signature=" + URLEncoder.encode(signature, charset);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
Log.d(TAG, "requestUrl: " + requestUrl);
Ion.with(context)
.load(requestUrl)
.asString()
.setCallback(new FutureCallback<String>() {
#Override
public void onCompleted(Exception e, String result) {
Log.d(TAG, "searchProducts result: " + result);
}
});
}
What could be the problem?
Make sure that your system clock is correct. It will be good idea to sync it using NTP. In the past I have seen signature errors when the time is out of sync.
What I've seen before is that this is normally down to permissions . Check access and secret key is correct and you have adequate permissions.
Changed:
Base64.DEFAULT;
To:
Base64.NO_WRAP;
It's hard to tell from the code. A few things to check:
Make sure the service you want to reach uses SigV2 signing (or query string signing). New services follow version 4 signing standard.
URLEncoder.encode doesn't meet AWS' encoding requirement RFC 3986. You need to apply some fixes to the encoded string.
Query strings should be sorted in a case insensitive way.
Your credentials are indeed correct.
It's a good idea to see how QueryStringSigner.java is implemented in the official SDK , and Signature Version 2 Signing Process.
PS: what's the reason of not using the offical SDK?
In the past when I have had this issue, it was to do with system time. Syncing time with NTP fix issue for me
Can be caused by
A space in the name (or path) of the file.
Characters that are not being properly encoded. Mostly / or +.
Generating new keys that does not contain these characters could help. More info on this issue or this one.
I have developed application for two different sensors. They are working fine separately but when I try to use them togather and create two diffent buses than Alljoyn gives this exception.
org.alljoyn.services.common.BusAlreadyExistException: The object has
been set previously with a BusAttachment.
Below is my source code for connection. Can anyone tell me why I'm having this issue.
private void connect()
{ org.alljoyn.bus.alljoyn.DaemonInit.PrepareDaemon(getApplicationContext());
bus = new BusAttachment("ControlPanelBrowser", BusAttachment.RemoteMessage.Receive);
bus.registerBusListener(new BusListener());
Status status = bus.registerBusObject(mControlPanelSignalInterface, Constants.SERVICE_PATH);
if (status != Status.OK) {
Log.d(TAG, "Problem while registering bus object");
}
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
srpPassword = settings.getString(PREFS_PASSWORD, DEFAULT_SECURED_SRP_PASSWORD);
SrpAnonymousKeyListener authListener = new SrpAnonymousKeyListener(this, logger, AUTH_MECHANISMS);
Status authStatus = bus.registerAuthListener(authListener.getAuthMechanismsAsString(),
authListener, getKeyStoreFileName());
if ( authStatus != Status.OK ) {
Log.e(TAG, "Failed to register AuthListener");
}
status = bus.connect();
if (Status.OK == status){
String daemonName = Constants.DAEMON_NAME_PREFIX + ".ControlPanelBrowser.G" +
bus.getGlobalGUIDString();
int flag = BusAttachment.ALLJOYN_REQUESTNAME_FLAG_DO_NOT_QUEUE;
Status reqStatus = bus.requestName(daemonName, flag);
if (reqStatus == Status.OK) {
Status adStatus = bus.advertiseName(Constants.DAEMON_QUIET_PREFIX +
daemonName, SessionOpts.TRANSPORT_ANY);
if (adStatus != Status.OK){
bus.releaseName(daemonName);
Log.e(TAG, "Failed to advertise daemon name: '" + daemonName + "', Error: '" + status + "'");
}
else{
Log.d(TAG, "Succefully advertised daemon name: '" + daemonName + "'");
}
}
else {
Log.e(TAG, "Failed to request daemon name: '" + daemonName + "', Error: '" + status + "'");
}
}
status = bus.registerSignalHandlers(mControlPanelSignalInterface);
if (status != Status.OK) {
Log.d(TAG, "Problem while registering signal handlers");
}
// Initialize AboutService
aboutClient = AboutServiceImpl.getInstance();
aboutClient.setLogger(logger);
try {
aboutClient.startAboutClient(bus);
for (String iface : ANNOUNCE_IFACES) {
aboutClient.addAnnouncementHandler(this, new String[] {iface});
}
} catch (Exception e) {
logger.error(TAG, "Unable to start AboutService, Error: " + e.getMessage());
}
}
use registerBusObject twince and then you can make one signle bus attachment
why dont you create two Interfaces, one interface for one sensor respectively. then add these two interfaces in a class which implements these two interfaces and the busObject and register an implemntation of this class as a BusObject.
For example
Sensor1_interface.java and Sensor2_interface.java //are my two interface classes
create a new class Sensor_InterfaceList which inplements the two interfaces and the BusObject
class Sensor_InterfaceList implements Sensor1_interface,Sensor2_interface,BusObject
{
// implment your interfaces here
.....
}
private Sensor_InterfaceList mySensor_InterfaceList;
mySensor_InterfaceList = new Sensor_InterfaceList();
myBus.registerBusObject(mySensor_InterfaceList,"/your/path");
This should solve your problem :)
We have a process that broadcasts a message using the following code. This message is received and processed by a BroadcastReceiver (given below). We have a curious problem on some Android tablets and phones. The message that is broadcast is not received by the receiver for exactly 60 seconds. It is as if there is something that prevents the message from being broadcasted/delivered for 60 seconds. We have triple checked the code and there is no artificial delay being introduced in the code. Has anyone else seen this issue? We will appreciate any insight on the issue.
We are using Xamarin.Android 4.1.0 and have seen the issue on Samsung Note 10.1 and Note 3. We have not seen it on Nexus 7 or Sony tablets.
public static void BroadcastResult(string SN, string result, string errorMessage, string commandType = "DataBatch")
{
try
{
Android.Content.Intent broadcastIntent = new Android.Content.Intent("com.GoServicePro.ProcessorResults");
broadcastIntent.PutExtra("Type", commandType);
broadcastIntent.PutExtra("SN", SN.ToString());
broadcastIntent.PutExtra("RESULT", result);
broadcastIntent.PutExtra("EXCEPTION", errorMessage);
if (Global.gCustomizerCol != null)
{
if (Global.gCustomizerCol.Count > 0)
{
}
}
if (Global.CurrentContext == null)
Android.App.Application.Context.SendBroadcast(broadcastIntent);
else
Global.CurrentContext.SendBroadcast(broadcastIntent);
Logging.LogToProcessorLog("Broadcasted results: <" + commandType + ":" + SN + ":" + result + ":" + errorMessage + ">");
}
catch (Exception ex)
{
Logging.LogToProcessorLog("EXCEPTION: " + ex.Message + "\n" + ex.StackTrace);
}
}
[BroadcastReceiver(Enabled = true, Label = "GoServicePro Receiver")]
[IntentFilter(new string[] { "com.GoServicePro.ProcessorResults" })]
public class ProcessorReceiver : BroadcastReceiver
{
/// <summary>
/// Handler for processing completed message brodcasted by GoServiceProProcessorService.
/// </summary>
/// <param name="context"></param>
/// <param name="intent"></param>
public override void OnReceive(Context context, Intent intent)
{
string commandType = intent.GetStringExtra("Type");
try
{
string sn = intent.GetStringExtra("SN");
string result = intent.GetStringExtra("RESULT");
string error = intent.GetStringExtra("EXCEPTION");
switch (commandType)
{
case "DataBatch":
if (result == "SUCCESS")
{
Global.gintGSASeqNumIn += 1;
Database.UpdateBootDataSeqInfo();
Communication.QueueAck(Global.gintGSASeqNumIn);
Logging.LogMsg("Batch# " + sn + " was processed successfully.");
if (Global.SendRefresh != null)
Global.SendRefresh.Invoke(true, "ACTIVE_TAB", true, "GENERAL", 0, true);
Logging.LogMsg("Refresh sent to Main and WO forms", 2);
}
else if (result == "ABORT_FOR_BEGIN_REFRESH")
Logging.LogMsg("Batch# " + sn + " was aborted by SECONDARY process because it had BEGIN_FULL_REFRESH command. It will be processed by PRIMARY process");
else
{
Logging.LogMsg("Batch with serial# " + sn + " was NOT saved successfully. Error was:\n" + error);
Logging.LogMsg("Will retry batch with serial# " + sn);
}
break;
.
.
.
.