Google Glass XE 17.3 - Multiple Actions From One Voice Trigger Broken? - google-glass

One of my pairs of Glass updated itself to XE 17.3 this morning, and now, any Voice Triggers I have defined that are used for more than one activity no longer work. On previous versions, (and I've tested my code on an XE 17.2 pair I have to make sure I didn't break anything today), if multiple activities were set to use the same Voice Trigger, the system would prompt you to select from a list upon hearing that voice trigger. This is expected behavior (in case two applications use the same trigger), and actually was quite useful for creating a sub-launcher for your application (which is what I was using it for...say main launch name -> get a list of activities to choose from within the app, all automatic and handled by the system).
Now, however, if my Voice Trigger is assigned to two or more activities within my manifest, it will show up in the list, but will never trigger when you say "OK Glass - [voice trigger]" (it does still work with taps, however). As I mentioned, I tested the exact same code on a pair running XE 17.2 and it worked fine. I also removed the trigger from all but one activity, and it works on 17.3 when you do that...so the problem is when you have more than one possible activity that handles a given voice trigger.
The way I have my manifest set up seems correct to me (and works on older versions of the firmware):
<uses-permission android:name="com.google.android.glass.permission.DEVELOPMENT" />
...
<!-- one of the activities. this is inside the application element, of course -->
<activity
android:name="com.someapp.MainActivity"
android:label="Option 1" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
</intent-filter>
<meta-data
android:name="com.google.android.glass.VoiceTrigger"
android:resource="#xml/voiceinput_main" />
</activity>
<!-- another activity, again inside the application element, sharing the same trigger -->
<activity
android:name="com.someapp.AnotherActivity"
android:label="Option 2" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
</intent-filter>
<meta-data
android:name="com.google.android.glass.VoiceTrigger"
android:resource="#xml/voiceinput_main" />
</activity>
And, this manifest works fine on XE 17.2. Anyone know of something that has changed in 17.3 that would break this, or see anything that looks wrong? I know that the <action android:name="android.intent.action.MAIN" /> line isn't necessary, but removing it doesn't fix the problem.
Thanks!

in my case, I change my voice trigger string "all in lower case" thing solved my problem, maybe you could give it a try, custom Voice trigger command XE17.31

This seems to only affect custom voice triggers. I'm seeing the same thing with an app I'm developing where I use "Debug ..." as a trigger to let me do a number of things to reset state or launch test actions.
If you change the trigger to an existing command listed here then it should start working again. If you're using the mechanism in the same way I am, you can probably just pick an obscure existing command to use for testing purposes (I'm using FIND_A_DOCTOR, which seems apropos for debugging purposes).
If you're simply using a custom command as part of normal flow, presumably it will either become an accepted command, or you'll have to switch to an existing command eventually, since the custom commands only work in debugging anyway.

Related

Case Sensitive URL

I've launched a small website.
I have found that I'm getting errors by users and upon investigation see that the urls they are trying to use are all lowercase whereas I've declared them as camelCase.
I've no idea why these users should be trying to use all lower case (I can't imagine anyone would actually take the time to change:
www.mysite.com/myAction.do
to
www.mysite.com/myaction.do
However I can't think of anyway this would otherwise be changed. Has anyone else experienced this where:
yourAction.do in your mapping file is then attempted to be accessed by users as youraction.do ?
I'm using Struts2.3.1, sitemesh 2.4.2 - I've never heard of or encountered such a situation and would like advice on what may be causing it if any of you have encountered the same or similar.
Are there any browsers out there that remap camelCase.do to camelcase.do ? For whatever reason.
The only 'solution' I can think of (the best out of two very ugly and inelegant workarounds) is to duplicate the action mappings in struts.xml
<action name="myAction" class="myActionClass" />
<action name="myaction" class="myActionClass" /> //added extra but what a 'dumb' solution
Edit:
Is is possible to do the same with methods?
So that:
myAction!clear.do
will still be correctly mapped with the URL:
myaction!clEAr.do
?
I notice from re-reading my error logs that it's the 'wrong case' method in the ULR which is causing most errors.
You can use regex pattern matcher with (?i) to "embed" the matching flag(s) in the regex body. For example
<constant name="struts.patternMatcher" value="regex" />
<action name="{(?i)myaction}" class="myActionClass" />

VersionFromLanguage module crashes on Sitecore 8.0

One of our clients has recently upgraded their sitecore from 7.0 to 8.0 and they used to work with VersionFromLanguage module to duplicate same content to multiple languages. But after upgrade, the content editor crashes with following error if the module gets activated (by enabling its config file):
Could not load type 'Sitecore.Shell.Applications.WebEdit.Commands.WebEditCommand' from assembly 'Sitecore.Client, Version=8.0.5245.0, Culture=neutral, PublicKeyToken=null'
I was thinking about better techniques such as language fallback in long term but is there any quick fix to this module? (It must be something about the way buttons get registered on SPEAK UI comparing to older shell API, I guess)
A quick fix is to switch to Sheer UI.
In Sitecore 8, the Experience editor by default uses SPEAK for the ribbon.
To use old Sheer UI (if is an option for you ) you need to modify Sitecore.ExperienceEditor.config
<pageextenders>
<!-- Uncomment the page extenders below and comment the "Sitecore.ExperienceEditor.Speak.Ribbon.PageExtender.RibbonPageExtender" to switch to old SheerUI-based Experience Editor ribbon. -->
<pageextender type="Sitecore.Layouts.PageExtenders.PreviewPageExtender, Sitecore.ExperienceEditor" />
<pageextender type="Sitecore.Layouts.PageExtenders.WebEditPageExtender, Sitecore.ExperienceEditor" />
<pageextender type="Sitecore.Layouts.PageExtenders.DebuggerPageExtender, Sitecore.ExperienceEditor" />
<pageextender type="Sitecore.Shell.Applications.Preview.SimulatedDevicePreview.PageExtenders.PreviewExtender, Sitecore.ExperienceEditor" />
<!-- Page extender for SPEAK-based Experience Editor ribbon. -->
<!--<pageextender type="Sitecore.ExperienceEditor.Speak.Ribbon.PageExtender.RibbonPageExtender, Sitecore.ExperienceEditor.Speak.Ribbon" />-->
</pageextenders>
On next links you will find information about how to customize ribbons in Sitecore 8 and what steps you need to follow to fix your issues into Sitecore 8.
http://www.programmingbynumbers.com/2015/01/31/creating-a-new-experience-editor-button-in-sitecore-8/
https://doc.sitecore.net/sitecore_experience_platform/the_editing_tools/customize_the_experience_editor_ribbon

Google glass Immersive app icon doesn't show

My app icon has disappeared, I've sourced it to the activity alias's I am using. I want them to display as sub menu voice commands so in the manifest I've added the VOICE_TRIGGER action. When I remove this the icon re-appears.
Any ideas for a work around?
Here'a an example of an alias:
<activity-alias
android:label="#string/do_thing"
android:name="#string/do_thing"
android:theme="#android:style/Theme.DeviceDefault"
android:immersive="true"
android:targetActivity="com.x.MainActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
</intent-filter>
<meta-data
android:name="com.google.android.glass.VoiceTrigger"
android:resource="#xml/voice_trigger" />
</activity-alias>
Maybe the text of the menu item is too long? I have had this before and with a long text, my icon also disappeared. When I shortened the menu text, the icon appeared again.
This is because you need to use the voice command in here:
https://developers.google.com/glass/develop/gdk/reference/com/google/android/glass/app/VoiceTriggers.Command
if you use the your own voice command, the icon won't show on XE18.3
I believe this is a known issue with 18.3 (https://code.google.com/p/google-glass-api/issues/detail?id=559) and was indicated fixed around July 8th.
So hopefully you aren't seeing this anymore in any release past 18.3.

HTML5 PushState Regex Issue

I've been experimenting with Backbone for a project I'm working on, and I've been having problems with getting Backbone's 'pushState' functioning how I'd like to.
I've got a simple project consisting of 4 views, and a router. I'm routing via the id of the elements if it matters in this case. When I go to the hash for one of the views (http://example.com/backbonetest/#step1), it's displayed correctly, and the url is changed. This is what I'd expect to happen here, but the problem comes when I try and navigate to the same thing without the hash in it (http://example.com/backbonetest/step1). I get a 404 on the server (IIS) which is to be expected, as the page doesn't exist.
What I've been trying to do all day is write a regex expression for IIS which would catch and rewrite the url, removing the fragment at the end of the url so the page is served correctly. I'd rather simply rewrite the url than having a physical file with the same name, as the content of the page will be dynamically generated, and will require scripts to get the content anyway.
The issue I've come across may be related to how I need to have the folders/scripts/styles structured on the file system. I was hoping to be able to have the whole example contained within the /backbonetest/ folder. For scripts, 'backbonetest/scripts' and so on.
I made a list of URLs which I've been testing my regex expressions against, and the results I've been trying to achieve:
Input: Output:
2
a2
ab2
ab22
step2
script.js script.js
scripts/ scripts/
555/stuff 555/stuff
scripts/script.js scripts/script.js
Edit: I've since found that the url which is used does not include the preceding slash,
which is why Qtax's solution doesn't work in IIS. The new input structure is shown above.
The '/555/stuff' url I would expect to 404 as normal. I only want to rewrite the url if there are no subdirectories defined other than the current one, and if the url doesn't reference an explicit file (one with an extension for example).
I've been scouring the net all day for a solution to this, as well as experimenting with regexr, but not managed to come up with the proper solution to my problem. After not finding a single thing anywhere, I'm thinking I must be looking at this the wrong way...
Can anyone help me out please?
After much head/desk banging, I've come up with the solution. It's irritatingly simple for all the fuss it's caused:
^[^\./]+$
Essentially:
Replace if the url doesn't contain a '/' or a '.' anywhere in it.
This should now be a solution for anyone using IIS with Backbone and HTML5 push state. Just pop it in the web.config in the root of your app, and change the rewrite action to ".", and it should just work.
This melted my brain all morning!
I've added to this - In my scenario, I have an API project which sits in an API virtual directory (to eliminate the need for CORS) - I obviously don't want to rewrite any of the PAI calls, so I re-wrote mine as follows - you can do similar for your API URLs if needed...
<rule name="Handle PushState">
<match url="^[^\./]+[^\./api]+(.*)$" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="." />
</rule>

Ivy and Snapshots (Nexus)

I'm using ant, ivy and nexus repo manager to build and store my artifacts. I managed to get everything working: dependency resolution and publishing. Until I hit a problem... (of course!).
I was publishing to a 'release' repo in nexus, which is locked to 'disable redeploy' (even if you change the setting to 'allow redeploy' (really lame UI there imo). You can imagine how pissed off I was getting when my changes weren't updating through the repo before I realised that this was happening.
Anyway, I now have to switch everything to use a 'Snapshot' repo in nexus. Problem is that this messes up my publish. I've tried a variety of things, including extensive googling, and haven't got anywhere whatsoever. The error I get is a bad PUT request, error code 400.
Can someone who has got this working please give me a pointer on what I'm missing.
Many thanks,
Alastair
fyi, here's my config:
Note that I have removed any attempts at getting snapshots to work as I didn't know what was actually (potentially) useful and what was complete guff. This is therefore the working release-only setup.
Also, please note that I've added the XXX-API ivy.xml for info only. I can't even get the xxx-common to publish (and that doesn't even have dependencies).
Ant task:
<target name="publish" depends="init-publish">
<property name="project.generated.ivy.file" value="${project.artifact.dir}/ivy.xml"/>
<property name="project.pom.file" value="${project.artifact.dir}/${project.handle}.pom"/>
<echo message="Artifact dir: ${project.artifact.dir}"/>
<ivy:deliver
deliverpattern="${project.generated.ivy.file}"
organisation="${project.organisation}"
module="${project.artifact}"
status="integration"
revision="${project.revision}"
pubrevision="${project.revision}" />
<ivy:resolve />
<ivy:makepom
ivyfile="${project.generated.ivy.file}"
pomfile="${project.pom.file}"/>
<ivy:publish
resolver="${ivy.omnicache.publisher}"
module="${project.artifact}"
organisation="${project.organisation}"
revision="${project.revision}"
pubrevision="${project.revision}"
pubdate="now"
overwrite="true"
publishivy="true"
status="integration"
artifactspattern="${project.artifact.dir}/[artifact]-[revision](-[classifier]).[ext]"
/>
</target>
Couple of ivy files to give an idea of internal dependencies:
XXX-Common project:
<ivy-module version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
<info
organisation="com.myorg.xxx"
module="xxx_common"
status="integration"
revision="1.0">
</info>
<publications>
<artifact name="xxx_common" type="jar" ext="jar"/>
<artifact name="xxx_common" type="pom" ext="pom"/>
</publications>
<dependencies>
</dependencies>
</ivy-module>
XXX-API project:
<ivy-module version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
<info
organisation="com.myorg.xxx"
module="xxx_api"
status="integration"
revision="1.0">
</info>
<publications>
<artifact name="xxx_api" type="jar" ext="jar"/>
<artifact name="xxx_api" type="pom" ext="pom"/>
</publications>
<dependencies>
<dependency org="com.myorg.xxx" name="xxx_common" rev="1.0" transitive="true" />
</dependencies>
</ivy-module>
IVY Settings.xml:
<ivysettings>
<properties file="${ivy.project.dir}/project.properties" />
<settings
defaultResolver="chain"
defaultConflictManager="all" />
<credentials host="${ivy.credentials.host}" realm="Sonatype Nexus Repository Manager" username="${ivy.credentials.username}" passwd="${ivy.credentials.passwd}" />
<caches>
<cache name="ivy.cache" basedir="${ivy.cache.dir}" />
</caches>
<resolvers>
<ibiblio name="xxx_publisher" m2compatible="true" root="${ivy.xxx.publish.url}" />
<chain name="chain">
<url name="xxx">
<ivy pattern="${ivy.xxx.repo.url}/com/myorg/xxx/[module]/[revision]/ivy-[revision].xml" />
<artifact pattern="${ivy.xxx.repo.url}/com/myorg/xxx/[module]/[revision]/[artifact]-[revision].[ext]" />
</url>
<ibiblio name="xxx" m2compatible="true" root="${ivy.xxx.repo.url}"/>
<ibiblio name="public" m2compatible="true" root="${ivy.master.repo.url}" />
<url name="com.springsource.repository.bundles.release">
<ivy pattern="http://repository.springsource.com/ivy/bundles/release/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
<artifact pattern="http://repository.springsource.com/ivy/bundles/release/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
</url>
<url name="com.springsource.repository.bundles.external">
<ivy pattern="http://repository.springsource.com/ivy/bundles/external/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
<artifact pattern="http://repository.springsource.com/ivy/bundles/external/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
</url>
</chain>
</resolvers>
</ivysettings>
w00h00t.
(There's something cathartic about asking the world for help. Usually you fix the problem much faster, even without a response).
Anyway, for the interested it came down to a couple of things:
a) the addition of -SNAPSHOT to all revisions. This involved forking a second ivy.xml -> ivy.SNAPSHOT.xml and referencing that explicitly in the ivy ant tasks.
b) given that this is a manual addition I had to go through my entire tree of build files and provide parallel paths for release and snapshot flows. This, in my opinion, is lame. But, as I guess we're extremely unlikely to invent any other type of flow, this probably won't bloat, and 2 parallel flows is where it will stay.
c) I specified various hints to ivy to check for updates to the snapshots. e.g. checkUpdated="true" and changePattern=".*-SNAPSHOT" on the resolver. And the addition of
<modules org="myorg" name=*" resolveMode="dynamic" />
Still, it'd be nice if there had been automatic integration with snapshot stuff. A bit of (optional) cleverness on the part of ivy. Let's face it, maven repos like nexus ARE really useful and I'm certainly using ivy only to get round maven's crappy build process. I like using nexus.
Anyway. If anyone ever wants to question further on this, feel free.
I'm not sure if this would help with the problem of having 2 sets of configurations, but at least the build.xml would be a little bit simpler.
You can define the revision attribute on the info element in ivy.xml as ${project.revision}.
You can then omit the revision="${project.revision}" attributes on ivy elements in build.xml.
See my answer on this another question for example:
https://stackoverflow.com/a/8853823/1148030
It should be noted, the only necessary step is to include the '-SNAPSHOT' to revision when publishing to Nexus. The other steps listed in the answer are optional/improvements. To pull the published item down, you need to add '-SNAPSHOT' to the revision as well.