Hey Cortana, how to handle multiple VCD languages in code?

296 Views Asked by At

In my app, I want to give the user the opportunity to switch a light on and off with voice commands (via Cortana for example). I understand the VCD concept and really like but I don't know how to handle the different languages in my code.

Given I have two languages (English and German):

<CommandSet xml:lang="en" Name="LightSwitch_en">
    <CommandPrefix>Switch the light</CommandPrefix>
    <Example>Switch the light on.</Example>
    <Command Name="switchLight">
        <Example>on</Example>
        <ListenFor>{status}</ListenFor>
        <Feedback>Light will be switched {status}.</Feedback>
        <Navigate />
    </Command>
    <PhraseList Label="status">
        <Item>on</Item>
        <Item>off</Item>
    </PhraseList>        
</CommandSet>

<CommandSet xml:lang="de" Name="LightSwitch_de">
    <CommandPrefix>Schalte das licht</CommandPrefix>
    <Example>Schalte das Licht ein.</Example>
    <Command Name="switchLight">
        <Example>ein</Example>
        <ListenFor>{status}</ListenFor>
        <Feedback>Licht wird {status}geschaltet.</Feedback>
        <Navigate />
    </Command>
    <PhraseList Label="status">
        <Item>ein</Item>
        <Item>aus</Item>
    </PhraseList>        
</CommandSet>

When my app launches by a voice command, I can easily extract the spoken words and can access the status parameter. But because it's a string I will get a different result depending on which language the user has spoken.

So if the user speaks English, the string is "on", but if he speaks German, the string would be "ein". So how do I know, which string I need to listen for inside my app? I am targeting something like this:

if (arg.Equals("on"))
    Light.On();
else if (arg.Equals("off"))
    Light.Off();

But this only works in English of cause, not in German. I resent checking for all different strings in all languages, that can't be the right way. Unfortuantely it is also not possible to give the <Item> tags an additional attribute due to they are just strings.

I could do something like if (arg.Equals("on") || arg.Equals("ein")) Light.On(); but as you can see this is really ugly and I have to adjust it every time I change something and well, imagine I had about 15 languages to check...

Do you know a smarter solution?

2

There are 2 best solutions below

2
On

As Cortana will use the same localization as the built in app localization method can you not put all your strings in resource files and then compare the returned string with the localized resource?

3
On

In case you just need to solve that particular case you can do the following, instead a list just define two commands per language:

 <Command Name="oncommand" >
    <Example>switch on</Example>
    <ListenFor>switch on</ListenFor>
    <Feedback>Light will be switched on.</Feedback>
    <Navigate />
</Command>

<Command Name="offcommand">
    <Example>switch off</Example>
    <ListenFor>switch off</ListenFor>
    <Feedback>Light will be switched off.</Feedback>
    <Navigate />
</Command>

and then detect in code what command was called:

if (args.Kind == ActivationKind.VoiceCommand)
        {
            var commandArgs = args as VoiceCommandActivatedEventArgs;
            var speechRecognitionResult = commandArgs.Result;
            string voiceCommandName = speechRecognitionResult.RulePath.First();
            string textSpoken = speechRecognitionResult.Text;
            return voiceCommandName;
        }

where voiceCommandName is 'oncommand' or 'offcommand'.