Unable to display data on Cortana canvas - c#

I am developing an UWP app in which i want to display some data in canvas. But I'm facing a lot of issues in it and now i can't find out what the problem is in it.
I made a VCD file,added the command in it,edited the OnActivated function,made the Windows Runtime Component for Background task,and also made the declaration in Package.appxmanifest file, but it is not working.
Here is the VoiceCommandDefinition.xml file:
<?xml version="1.0" encoding="utf-8" ?>
<VoiceCommands xmlns="http://schemas.microsoft.com/voicecommands/1.2">
<CommandSet xml:lang="en-us" Name="NormalCommands">
<CommandPrefix>in app</CommandPrefix>
<Example>Show data in canvas</Example>
<Command Name="CanvasView">
<Example>test cortana</Example>
<ListenFor RequireAppName="ExplicitlySpecified"> {builtin:Cortinnum}test cortana</ListenFor>
<Feedback>Okay Boss</Feedback>
<VoiceCommandService Target="CanvasViewService"/>
</Command>
</CommandSet>
</VoiceCommands>
Here is the OnActivated function from App.xaml.cs code:
protected override void OnActivated(IActivatedEventArgs args)
{
if (args.Kind == Windows.ApplicationModel.Activation.ActivationKind.VoiceCommand)
{
var CommandArgs = args as Windows.ApplicationModel.Activation.VoiceCommandActivatedEventArgs;
var result = CommandArgs.Result;
var CommandName = result.RulePath[0];
var text = result.Text;
}
else
base.OnActivated(args);
}
Here is the Background Service component's code:
using System;
using Windows.ApplicationModel.AppService;
using Windows.ApplicationModel.Background;
using Windows.ApplicationModel.VoiceCommands;
namespace BackgroundService
{
public sealed class service:IBackgroundTask
{
VoiceCommandServiceConnection voiceServiceConnection;
BackgroundTaskDeferral serviceDeferral;
public async void Run(IBackgroundTaskInstance taskInstance)
{
serviceDeferral = taskInstance.GetDeferral();
taskInstance.Canceled += OnTaskCanceled;
var triggerDetails = taskInstance.TriggerDetails as AppServiceTriggerDetails;
if (triggerDetails != null && triggerDetails.Name == "CanvasView")
{
try
{
voiceServiceConnection =
VoiceCommandServiceConnection.FromAppServiceTriggerDetails(
triggerDetails);
voiceServiceConnection.VoiceCommandCompleted += OnVoiceCommandCompleted;
VoiceCommand voiceCommand = await voiceServiceConnection.GetVoiceCommandAsync();
// perform the appropriate command.
switch (voiceCommand.CommandName)
{
case "CanvasView":
VoiceCommandUserMessage userMessage = new VoiceCommandUserMessage();
userMessage.DisplayMessage = "Test Data";
userMessage.SpokenMessage = "Test data view successful";
var response = VoiceCommandResponse.CreateResponse(userMessage);
await voiceServiceConnection.ReportSuccessAsync(response);
break;
default:
VoiceCommandUserMessage userMessage1 = new VoiceCommandUserMessage();
userMessage1.DisplayMessage = "Nothing";
userMessage1.SpokenMessage = "NO data to show";
var response1 = VoiceCommandResponse.CreateResponse(userMessage1);
await voiceServiceConnection.ReportSuccessAsync(response1);
break;
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("Handling Voice Command failed " + ex.ToString());
}
}
}
private void OnVoiceCommandCompleted(VoiceCommandServiceConnection sender, VoiceCommandCompletedEventArgs args)
{
if (this.serviceDeferral != null)
{
this.serviceDeferral.Complete();
}
}
private void OnTaskCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
{
System.Diagnostics.Debug.WriteLine("Task cancelled, clean up");
if (this.serviceDeferral != null)
{
//Complete the service deferral
this.serviceDeferral.Complete();
}
}
}
}
Edit:
Here is the code of Extensions tag from Package.appxmanifest:
<Extensions>
<uap:Extension Category="windows.appService" EntryPoint="Cortinnum.backgroundService.service">
<uap:AppService Name="service" />
</uap:Extension>
</Extensions>

Related

Send speech recognition args.Result as parameter in UWP desktop-bridge package

I'm trying to figure out, if it is possible send using Windows.Media.SpeechRecognition; args.Result.Text as parameter from UWP to Console application.
For example by following scenario I'm sending TextToSpeech(args.Result.Text); with args.Result.Text; value, where using Windows.Media.SpeechSynthesis; text-to-speech pronounces the recognition result each time when args.Result.Text; appears. textBlock2.Text = args.Result.Text; also displays result:
private async void ContinuousRecognitionSession_ResultGenerated(
SpeechContinuousRecognitionSession sender, SpeechContinuousRecognitionResultGeneratedEventArgs args)
{
await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
textBlock1.Text = args.Result.Text;
TextToSpeech(args.Result.Text);
});
}
but if I'm trying to send args.Result.Text; as parameter to console application, included with UWP in Desktop-Bridge package:
private async void ContinuousRecognitionSession_ResultGenerated(
SpeechContinuousRecognitionSession sender, SpeechContinuousRecognitionResultGeneratedEventArgs args)
{
await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
textBlock1.Text = args.Result.Text;
SendTTSResult(args.Result.Text);
});
}
to the requested function:
private async void SendTTSResult(string res)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
if (ApiInformation.IsApiContractPresent("Windows.ApplicationModel.FullTrustAppContract", 1, 0))
{
ApplicationData.Current.LocalSettings.Values["parameters"] = res;
await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync("Parameters");
}
});
}
Behavior of failure looks to me not really clear:
With first recognition result, it sends parameter to console application, which successfully loads, gets and displays this parameter. But with second request the problem backs away from this processing level, even if parameters sending function is unambiguously the cause of a failure SendTTSResult(args.Result.Text); function does not receives args.Result.Text but this happens already before function will comes in action, because preceding output display textBlock1.Text = args.Result.Text; also does not receives event anymore.
With async() => behavior is a bit different, it successfully receives event and sends value as parameter to console, in this case it happens 2-3 times from beginning of execution and voice requesting, then event disappears, when it is not even passed through SendTTSResult(string res), to imagine that the something in SendTTSResult(string res) does not allows pass string from recognition, but just stops, even if I put it in the end of TextToSpeech(string text) function, text to speech also stops receive event:
private async void SendTTSResult(string res)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async() =>
{
if (ApiInformation.IsApiContractPresent("Windows.ApplicationModel.FullTrustAppContract", 1, 0))
{
ApplicationData.Current.LocalSettings.Values["parameters"] = res;
await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync("Parameters");
}
});
}
It looks like sending of args.Result.Text value as parameter with SendTTSResult(string res) function works fine, sends string successfully, but at the same time presence of this function in ContinuousRecognitionSession_ResultGenerated somehow affects receiving of event inside of it. At the same time behavior of ContSpeechRecognizer_HypothesisGenerated looks completely different, args.Hypothesis.Text event appears each time and result successfully passes as parameter with same SendTTSResult(string res).
What can prevent an event from being executed when the function of sending a parameter is involved in its process, and how to fix it if possible?
Full code of continuous speech recognition added to my question on Windows Dev Center Send speech recognition args.Result as parameter in UWP desktop-bridge package
EDIT 1: **************************************************************************************************
Behind parameter function, Console Connector.exe only shows parameter without running of any app or anything else:
static void Main(string[] args)
{
string result = Assembly.GetExecutingAssembly().Location;
int index = result.LastIndexOf("\\");
string rootPath = $"{result.Substring(0, index)}\\..\\";
if (args.Length > 2)
{
switch (args[2])
{
case "/parameters":
string parameters = ApplicationData.Current.LocalSettings.Values["parameters"] as string;
Console.WriteLine("Parameter: " + parameters);
Console.ReadLine();
break;
}
}
}
Packeage.appxmanifest:
<uap:Extension Category="windows.appService">
<uap:AppService Name="SampleInteropService" />
</uap:Extension>
<desktop:Extension Category="windows.fullTrustProcess" Executable="Connector\Connector.exe">
<desktop:FullTrustProcess>
<desktop:ParameterGroup GroupId="Parameters" Parameters="/parameters" />
</desktop:FullTrustProcess>
</desktop:Extension>
EDIT 2: **************************************************************************************************
I've tried SendTTSResult(SpeechRecogVal); with change of variable value:
private async void ContinuousRecognitionSession_ResultGenerated(
SpeechContinuousRecognitionSession sender, SpeechContinuousRecognitionResultGeneratedEventArgs args)
{
await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
SpeechRecogVal = args.Result.Text;
});
}
but it is same behavior tbRec.Text = SpeechRecogVal; shows output successfully until I add SendTTSResult(SpeechRecogVal);,
private string _srVal;
public string SpeechRecogVal
{
get
{
return _srVal;
}
set
{
_srVal = value;
ValueChanged();
}
}
void ValueChanged()
{
tbRec.Text = SpeechRecogVal;
// SendTTSResult(SpeechRecogVal);
}
So, seems like problem is something between await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () => and if (ApiInformation.IsApiContractPresent("Windows.ApplicationModel.FullTrustAppContract", 1, 0)) and await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => of private async voidContinuousRecognitionSession_ResultGenerated(SpeechContinuousRecognitionSession sender, SpeechContinuousRecognitionResultGeneratedEventArgs args)
Also, I've tried:
private async void ContinuousRecognitionSession_ResultGenerated(
SpeechContinuousRecognitionSession sender, SpeechContinuousRecognitionResultGeneratedEventArgs args)
{
await SendTTSResult(args.Result.Text);
}
as Task:
async Task SendTTSResult(string res)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
{
if (ApiInformation.IsApiContractPresent("Windows.ApplicationModel.FullTrustAppContract", 1, 0))
{
ApplicationData.Current.LocalSettings.Values["parameters"] = res;
await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync("Parameters");
}
});
}
And it is also successful only with first request event instance response, then goes quite. So seems like ContinuousRecognitionSession_ResultGenerated is someway different from other options in Windows.Media.SpeechRecognition Namespace and not compatible with something in async Task SendTTSResult(string res) or rather with this code lines content:
ApplicationData.Current.LocalSettings.Values["parameters"] = args.Result.Text;
await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync("Parameters");
System.NullReferenceException occurs appservice disconnect scenario, Could you check the apservice's connection before send message?
For explain this, I create sample project that refer Stefanwick blog. And I also reproduce your issue when I does not invoke InitializeAppServiceConnection method in WPF client. If you want to send text to wpf, you could invoke Connection.SendMessageAsync method just like below SendMesssage click envent .
Capability
<Extensions>
<uap:Extension Category="windows.appService">
<uap:AppService Name="SampleInteropService" />
</uap:Extension>
<desktop:Extension Category="windows.fullTrustProcess" Executable="AlertWindow\AlertWindow.exe" />
</Extensions>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
<rescap:Capability Name="runFullTrust" />
</Capabilities>
WPF
private AppServiceConnection connection = null;
public MainWindow()
{
InitializeComponent();
InitializeAppServiceConnection();
}
private async void InitializeAppServiceConnection()
{
connection = new AppServiceConnection();
connection.AppServiceName = "SampleInteropService";
connection.PackageFamilyName = Package.Current.Id.FamilyName;
connection.RequestReceived += Connection_RequestReceived;
connection.ServiceClosed += Connection_ServiceClosed;
AppServiceConnectionStatus status = await connection.OpenAsync();
if (status != AppServiceConnectionStatus.Success)
{
MessageBox.Show(status.ToString());
this.IsEnabled = false;
}
}
private void Connection_ServiceClosed(AppServiceConnection sender, AppServiceClosedEventArgs args)
{
Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
{
Application.Current.Shutdown();
}));
}
private async void Connection_RequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
{
// retrive the reg key name from the ValueSet in the request
string key = args.Request.Message["KEY"] as string;
if (key.Length > 0)
{
Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
{
InfoBlock.Text = key;
}));
ValueSet response = new ValueSet();
response.Add("OK", "SEND SUCCESS");
await args.Request.SendResponseAsync(response);
}
else
{
ValueSet response = new ValueSet();
response.Add("ERROR", "INVALID REQUEST");
await args.Request.SendResponseAsync(response);
}
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
ValueSet response = new ValueSet();
response.Add("OK", "AlerWindow Message");
await connection.SendMessageAsync(response);
}
UWP
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (ApiInformation.IsApiContractPresent("Windows.ApplicationModel.FullTrustAppContract", 1, 0))
{
App.AppServiceConnected += MainPage_AppServiceConnected;
App.AppServiceDisconnected += MainPage_AppServiceDisconnected;
await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync();
}
}
private async void MainPage_AppServiceDisconnected(object sender, EventArgs e)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
Reconnect();
});
}
private void MainPage_AppServiceConnected(object sender, AppServiceTriggerDetails e)
{
App.Connection.RequestReceived += AppServiceConnection_RequestReceived;
}
private async void AppServiceConnection_RequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
{
string value = args.Request.Message["OK"] as string;
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
InfoBlock.Text = value;
});
}
private async void Reconnect()
{
if (App.IsForeground)
{
MessageDialog dlg = new MessageDialog("Connection to desktop process lost. Reconnect?");
UICommand yesCommand = new UICommand("Yes", async (r) =>
{
await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync();
});
dlg.Commands.Add(yesCommand);
UICommand noCommand = new UICommand("No", (r) => { });
dlg.Commands.Add(noCommand);
await dlg.ShowAsync();
}
}
private int count = 0;
private async void SendMesssage(object sender, RoutedEventArgs e)
{
count++;
ValueSet request = new ValueSet();
request.Add("KEY", $"Test{count}");
AppServiceResponse response = await App.Connection.SendMessageAsync(request);
// display the response key/value pairs
foreach (string value in response.Message.Values)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
StatusBlock.Text = value;
});
}
}
This is complete code sample.

Different behaviors when instantiated from button or timer in c#

I have a function called getMessages that can be called by a Button click (using the RelayCommand trigger) or that is called in a timer every 15s.
The desired behavior is:
webservice > deserialize answer > system notification > updatelistview > insert localDB
But when the function is called by the timer the updatelistview is not done. Why does this happen if the function is the same and works perfectly in the button command?
CODE:
// Get messages for the logged in user
public async void getMessages()
{
try
{
List<FriendGetMessage> msg = new List<FriendGetMessage>();
var response = await CommunicationWebServices.GetCHAT("users/" + au.idUser + "/get", au.token);
if (response.StatusCode == HttpStatusCode.OK) // If there are messages for me.
{
var aux = await response.Content.ReadAsStringAsync();
IEnumerable<FriendGetMessage> result = JsonConvert.DeserializeObject<IEnumerable<FriendGetMessage>>(aux);
if (result != null)
{
foreach (var m in result)
{
msg.Add(m);
}
//MsgList=msg;
foreach (var f in Friends)
{
if (f.msg == null || f.msg.Count() == 0)
{
f.msg = new ObservableCollection<Messages>();
}
foreach (var mess in msg)
{
if (mess.idUser == f.idUser)
{
Messages mm = new Messages();
mm.received = mess.message;
mm.timestamp = "Received " + mess.serverTimestamp;
mm.align = "Right";
// Add to the friend list.
f.msg.Add(mm);
// Add to Local DB
InsertMessage(null, au.idUser.ToString(), f.idUser, mess.message, mess.serverTimestamp);
var notification = new System.Windows.Forms.NotifyIcon()
{
Visible = true,
Icon = System.Drawing.SystemIcons.Information,
BalloonTipIcon = System.Windows.Forms.ToolTipIcon.Info,
BalloonTipTitle = "New Message from " + f.name,
BalloonTipText = "Message: " + mess.message,
};
// Display for 5 seconds.
notification.ShowBalloonTip(5);
// The notification should be disposed when you don't need it anymore,
// but doing so will immediately close the balloon if it's visible.
notification.Dispose();
}
}
}
counterChat = 1; // resets the counter
}
}
else {
counterChat = counterChat * 2;
}
//var sql = "select * from chat";
//var respo = GetFromDatabase(sql);
OnPropertyChanged("Friends");
}
catch (Exception e)
{
MessageBox.Show("GetMessages: " + e);
Debug.WriteLine("{0} Exception caught.", e);
}
}
CODE TIMER:
public void chatUpdate()
{
_timerChat = new DispatcherTimer(DispatcherPriority.Render);
_timerChat.Interval = TimeSpan.FromSeconds(15);
_timerChat.Tick += new EventHandler(timerchat_Tick);
_timerChat.Start();
}
public void timerchat_Tick(object sender, EventArgs e)
{
if (counterChat != incChat)
{
incChat++;
}
else
{
getMessages();
OnPropertyChanged("Friends");
incChat = 0;
}
}
ADDED - I've also tried this and didn't worked (it seems that is some kind of concurrency problem to the ObservableCollection called Friends (is a friendslist) each friend has an ObservableCollection of messages (is a chat))
public void chatUpdate()
{
_timerChat = new DispatcherTimer(DispatcherPriority.Render);
_timerChat.Interval = TimeSpan.FromSeconds(15);
_timerChat.Tick += new EventHandler(timerchat_Tick);
_timerChat.Start();
}
public async void timerchat_Tick(object sender, EventArgs e)
{
if (counterChat != incChat)
{
incChat++;
}
else
{
Application.Current.Dispatcher.Invoke((Action)async delegate { await getMessages(); });
incChat = 0;
}
}
Best regards,
I think you need to make the timer handler be an async method as follows:
public async void timerchat_Tick(object sender, EventArgs e)
{
if (counterChat != incChat)
{
incChat++;
}
else
{
await getMessages();
OnPropertyChanged("Friends");
incChat = 0;
}
}
This way OnPropertyChanged("Friends") is guaranteed to fire after the work in getMessages is done.
The methods need to change to:
DispatcherTimer _timerChat = new DispatcherTimer(DispatcherPriority.Render);
_timerChat.Interval = TimeSpan.FromSeconds(15);
_timerChat.Tick += new EventHandler(timerchat_Tick);
_timerChat.Start();
public async void timerchat_Tick(object sender, EventArgs e)
{
//...
await getMessages();
//...
}
public async Task getMessages()
{
try
{
// ... your code here
string result = await response.Content.ReadAsStringAsync();
// .... rest of your code
}
catch (Exception e)
{
MessageBox.Show("GetMessages: " + e);
}
}
It is solved. The problem was in my ViewModels I was opening multiple threads and sometimes the right one would update the UI and sometimes no.
Thanks for all the answers.

Wp 8.1 app crashing when its not connected to debugger

Application works when its connected to PC and run with debugger. The problem starts when I disconnect phone from PC, run app from phone and try to open gallery and set image to image control. I tried to write error in a file on try/catch but catch is never called, like there is no error on app executing.
This is code where i select img:
private async void galleryBtn_Click(object sender, RoutedEventArgs e)
{
try
{
FileOpenPicker filePicker = new FileOpenPicker();
filePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
filePicker.ViewMode = PickerViewMode.Thumbnail;
// Filter to include a sample subset of file types
filePicker.FileTypeFilter.Clear();
filePicker.FileTypeFilter.Add(".bmp");
filePicker.FileTypeFilter.Add(".png");
filePicker.FileTypeFilter.Add(".jpeg");
filePicker.FileTypeFilter.Add(".jpg");
filePicker.PickSingleFileAndContinue();
view.Activated += viewActivated;
}
catch (Exception err)
{
string error = err.StackTrace.ToString();
await saveStringToLocalFile("test11", error);
}
}
And than it goes to :
private async void viewActivated(CoreApplicationView sender, IActivatedEventArgs args1)
{
try
{
FileOpenPickerContinuationEventArgs args = args1 as FileOpenPickerContinuationEventArgs;
if (args != null)
{
if (args.Files.Count == 0) return;
view.Activated -= viewActivated;
StorageFile storageFile = args.Files[0];
var stream = await storageFile.OpenAsync(Windows.Storage.FileAccessMode.Read);
var bitmapImage = new Windows.UI.Xaml.Media.Imaging.BitmapImage();
await bitmapImage.SetSourceAsync(stream);
var decoder = await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(stream);
var obj = App.Current as App;
obj.ImageToEdit = bitmapImage;
obj.fileTransfer = storageFile;
checkTorch = -1;
await newCapture.StopPreviewAsync();
Frame.Navigate(typeof(EditImage));
}
}
catch (Exception err) {
string error = err.StackTrace.ToString();
await saveStringToLocalFile("test11", error);
}
}
When img is selected i open screen for image editing and run this
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
try
{
var obj = App.Current as App;
slika = obj.ImageToEdit;
original = obj.ImageToEdit;
ImagePreview.Source = slika;
RotateTransform myRotateTransform = new RotateTransform();
myRotateTransform.Angle = 0;
ImagePreview.RenderTransform = myRotateTransform;
var localSettings = ApplicationData.Current.LocalSettings;
}
catch (Exception err)
{
string error = err.StackTrace.ToString();
await saveStringToLocalFile("test11", error);
}
}
That is all, any advice is appreciated;
Problem was with my MediaCapture. First use mediaCapture.stopPreviewAsync(); to stop preview and than you must release the mediaCapture.
Before you call fileOpener use this code:
newCapture.Dispose();
In order to catch unhandled exceptions you can use a global exception catcher,
in App.xaml.cs file define:
public App()
{
this.InitializeComponent();
this.Suspending += this.OnSuspending;
this.UnhandledException += UnhandledExceptionHandler;
}
private void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs e)
{
log.Critical(e.Exception);
}
It's important to understand that not all exceptions can be caught using try\catch such as Corrupt State Exceptions:
https://msdn.microsoft.com/en-us/magazine/dd419661.aspx#id0070035
In this case you can debug the issue by viewing the .dmp file generated by your application found in: {Phone}\Documents\Debug

UWP Cortana not registering app commands

I am trying to implement Cortana to my app so when the user says "Hey Cortana, in test app read step one" the app will read the first element from a listbox. The problem I am having is that when I say this, the app just opens up a bing web page with the sentence I say.
<?xml version="1.0" encoding="utf-8" ?>
<VoiceCommands xmlns="http://schemas.microsoft.com/voicecommands/1.1">
<CommandSet xml:lang="en-US" Name="CommandSet_en-US">
<CommandPrefix> Test App</CommandPrefix>
<Example> read step one </Example>
<Command Name="step">
<Example> read step one </Example>
<ListenFor> read step {number} </ListenFor>
<Feedback> Reading Instruction </Feedback>
<Navigate Target="Page1"/>
</Command>
<PhraseList Label= "number">
<Item> one </Item>
<Item> two </Item>
</PhraseList>
</CommandSet>
</VoiceCommands>
In app.xaml.cs:
protected async override void OnLaunched(LaunchActivatedEventArgs e)
//code
Window.Current.Activate();
}
try
{
StorageFile vcdStorageFile = await Package.Current.InstalledLocation.GetFileAsync( #"CortanaCommands.xml");
await VoiceCommandDefinitionManager.InstallCommandDefinitionsFromStorageFileAsync(vcdStorageFile);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("There was an error Registering the Voice Command Definitions", ex);
}
}
protected override void OnActivated(IActivatedEventArgs e)
{
if (e.Kind != Windows.ApplicationModel.Activation.ActivationKind.VoiceCommand)
{
return;
}
var commandArgs = e as Windows.ApplicationModel.Activation.VoiceCommandActivatedEventArgs;
var speechRecognitionResult = commandArgs.Result;
string voiceCommandName = speechRecognitionResult.RulePath[0];
string textSpoken = speechRecognitionResult.Text;
string spokenStep = "";
try
{
spokenStep = speechRecognitionResult.SemanticInterpretation.Properties["number"][0];
}
catch
{
}
Frame rootFrame = Window.Current.Content as Frame;
MainPage page = rootFrame.Content as MainPage;
if (page == null)
{
return;
}
switch (spokenStep)
{
case "one":
page.Count1 = 0;
break;
default:
//no match
break;
}
switch (voiceCommandName)
{
case "step":
page.StepOne();
break;
default:
break;
}
}
I got your problem, your StepOne method is like this:
public void StepOne(int count1) { readText(SteplistBox.Items[count1].ToString()); }
There is an argument in this method, but you call this method like this: page.StepOne(); there is no arguments in this method. Please notice that StepOne() method and StepOne(int i) are two different methods.
Possible this problem is a typo, but I assume what you want to do is using cortana to open your app and reading items of ListBox from the MainPage according to the voice command. Plus the possible problems in my comments, here I wrote a sample for you:
App.xaml.cs code:
private string count = null;
protected override void OnActivated(IActivatedEventArgs args)
{
if (args.Kind == ActivationKind.VoiceCommand)
{
VoiceCommandActivatedEventArgs vargs = (VoiceCommandActivatedEventArgs)args;
SpeechRecognitionResult res = vargs.Result;
string cmdName = res.RulePath[0];
if (cmdName == "step")
{
var interpretation = res.SemanticInterpretation;
string item = interpretation.Properties["number"].FirstOrDefault();
if (!string.IsNullOrEmpty(item))
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame == null)
{
rootFrame = new Frame();
Window.Current.Content = rootFrame;
}
switch (item)
{
case "one":
count = "one";
break;
case "two":
count = "two";
break;
default:
count = null;
break;
}
rootFrame.Navigate(typeof(MainPage), count);
}
}
}
count = null;
Window.Current.Activate();
}
MainPage.cs code:
public void StepOne(int i)
{
readText(SteplistBox.Items[i].ToString());
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (e.Parameter != null)
{
if ((string)e.Parameter == "one")
{
StepOne(0);
}
else if ((string)e.Parameter == "two")
{
StepOne(1);
}
}
}
Update
If you don't want to use OnNavigatedTo method and e.Patameter of the Mainpage, you can change the code in the App.xaml.cs like this:
protected override void OnActivated(IActivatedEventArgs args)
{
if (args.Kind == ActivationKind.VoiceCommand)
{
VoiceCommandActivatedEventArgs vargs = (VoiceCommandActivatedEventArgs)args;
SpeechRecognitionResult res = vargs.Result;
string cmdName = res.RulePath[0];
if (cmdName == "step")
{
var interpretation = res.SemanticInterpretation;
string item = interpretation.Properties["number"].FirstOrDefault();
if (!string.IsNullOrEmpty(item))
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame == null)
{
rootFrame = new Frame();
Window.Current.Content = rootFrame;
}
rootFrame.Navigate(typeof(MainPage));
MainPage page = rootFrame.Content as MainPage;
switch (item)
{
case "one":
page.StepOne(0);
break;
case "two":
page.StepOne(1);
break;
default:
break;
}
}
}
}
Window.Current.Activate();
}
And keep the StepOne(int i) method in the MainPage.cs like this:
public void StepOne(int i)
{
readText(SteplistBox.Items[i].ToString());
}

How to communicate between a c# server (WinRT/Metro) and android client?

I am looking for a way to communicate either over TCP or HTTP between android and C# 2012. Here is what I have so far
JAVA CLIENT:
package com.example.test;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
TextView tc;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = (Button)this.findViewById(R.id.button1);
tc = (TextView) this.findViewById(R.id.textView1);
btn.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
Thread th = new Thread(new Runnable() {
public void run() {
connect();
}
});
th.start();
}
});
}
private void connect() {
InetAddress[] server;
try {
server = InetAddress.getAllByName("192.168.1.100");
Socket socket = new Socket(server[0], 3975);
if (socket.isConnected()){
Log.d("connected", "connected");
}
PrintWriter w = null;
BufferedReader r = null;
w = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true);
r = new BufferedReader(new InputStreamReader(socket.getInputStream()));
w.println("test");
/*String m = null;
while ((m=r.readLine())!= null) {
w.write(m,0,m.length());
w.flush();
}*/
} catch (Exception e) {
// TODO Auto-generated catch block
Log.d("error", e.getMessage());
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
C# SERVER:
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached. The Parameter
/// property is typically used to configure the page.</param>
protected override void OnNavigatedTo(NavigationEventArgs e)
{
}
public async void ServiceButtonClick(object sender, RoutedEventArgs e)
{
StreamSocketListener listener = new StreamSocketListener();
listener.ConnectionReceived += OnConnection;
try
{
await listener.BindServiceNameAsync("3975");
lblMessage.Text = "We are listening for connections...";
}
catch (Exception ee)
{
lblMessage.Text = "Unable to bind service.. " + ee.Message;
}
}
private async void OnConnection(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
{
DataReader reader = new DataReader(args.Socket.InputStream);
this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
lblMessage.Text = "We are connected to the client";
});
try
{
while (true)
{
uint sizeFieldCount = await reader.LoadAsync(sizeof(uint));
if (sizeFieldCount != sizeof(uint))
{
this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
lblMessage.Text = "the underlying socket was closed before we were able to read the whole data - 1";
});
return;
}
uint stringLength = reader.ReadUInt32();
uint actualStringLength = await reader.LoadAsync(stringlength);
if (stringLength != actualStringLength)
{
this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
lblMessage.Text = "the underlying socket was closed before we were able to read the whole data - 2";
});
return;
}
string temp;
temp = reader.ReadString(actualStringLength);
this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
lblMessage.Text = "Client said - " + reader.ReadString(3);
});
}
}
catch (Exception e)
{
this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
lblMessage.Text = "ERROR: " + e.Message + " - " + e.Source + " - " + e.StackTrace;
});
}
}
}
Now when I click the button on the client, the socket is connected, but when I send data to the C# server from my phone, nothing shows up on the server. Is there anything I am doing wrong on the receiving or sending end? I am just trying to send basic strings over TCP.

Categories

Resources