Opening GDK Glassware through Mirror API Glassware MenuItem - google-glass

I have problem integrating GDK Glassware and Mirror API Glassware as described here. I need to open GDK glassware application using Mirroe api Glassware app MenuItem. Can I send data bundle with intent. Does anybody have an idea about that.
Thank you.

I have finally figured out a way to do that
First add your custom scheme to android activity tag in AndroidManifest.xml
<activity
android:name="com.sanath.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<data android:scheme="com.sanath.scheme" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data android:name="com.google.android.glass.VoiceTrigger"
android:resource="#xml/vision_voice_trigger" />
</activity>
Then in Glassware timeline MenuItem add like following
new MenuItem(){
Action = "OPEN_URI",
Payload = "com.sanath.scheme://open/Welcome/2014",
Values = new MenuValue[]
{
new MenuValue()
{
DisplayName = "Open",
State = "DEFAULT"
},
new MenuValue()
{
DisplayName = "Launching",
State = "PENDING"
},
new MenuValue()
{
DisplayName = "Launched",
State = "CONFIRMED"
},
},
},
}
Then inside your Activity OnCreate method you can get data as following
Uri data = getIntent().getData();
List params = data.getPathSegments();
String param0 = params.get(0); // "welcome"
String param1 = params.get(1); //"2014"
String welcomeMsg = param0+" to "+param1;
/*show time line card
* */
Card welcomeCard =new Card(this);
welcomeCard.setText(welcomeMsg);
welcomeCard.setFootnote(param1);
View view =welcomeCard.toView();
setContentView(view);
Hope this will help others

It is not possible to provide data through bundle, but you can use query parameters or hash fragment in your URI to provide the necessary data.
Example:
myscheme://<SOME_PATH>?param1=value1&param2&value2
Then, in your GDK Glassware, simply parse the query parameters and process their values.

Related

SAPUI5 List CustomListItem / Rerender Issue

I got a split-app, left Hand side a master list with persons. right-hand side a Detail page with info and RatingIndicator element. Two lists on the detail-page which are bound via associations: /Master/Detail/Rating.
Whenever I use the Rating Indicator, it seems like the page is rerendering, which makes everything slow at the end. I tried both, two-way binding and one-way-binding with manually updating the model. It still rerenders/reloads the page every time I use the Rating indicator.
Any idea someone?
SAPUI5 library is on Version 1.28.31.
Edit: In the meantime I reduced complexity (no lists within lists, thought this might be the issue, but it isnt), and still the issue occurs. Even now when I use the Rating indicator the whole Detail page reloads/rerenders.
What can I do?
Before Clicking the Rating indicator:
Directly after cliking the Rating indicator, right-hand Detail page disappears and reappears withing seconds.
View:
<mvc:View controllerName="split.controller.Detail" xmlns="sap.m"
xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns:footerbar="sap.ushell.ui.footerbar"
xmlns:f="sap.ui.layout.form" xmlns:l="sap.ui.layout">
<Page id="page" navButtonPress="onNavBack" showNavButton="{device>/system/phone}"
title="{i18n>detailTitle}" busy="{detailView>/busy}"
busyIndicatorDelay="{detailView>/delay}" class="sapUiResponsiveContentPadding">
<content>
<List items="{ path: 'WorklistToDocument' }">
<CustomListItem>
<VBox class="sapUiSmallMargin" }">
<Title titleStyle="H3" text="{Title}" }" />
<Text text="{Description}" }" />
</VBox>
<VBox class="sapUiSmallMargin">
<Text text="{Description}" />
<CheckBox selected="{NotApplicable}" select="onNACheckBoxSelect" />
<RatingIndicator value="{RatingValue}" maxValue="{MaxValue}" change="onRatingChanged" />
<Text
text="{ path: 'RatingValue', formatter: '.formatter.ratingText' }" />
</VBox>
</CustomListItem>
</List>
</content>
</Page>
Controller:
onRatingChanged: function(oEvent) {
var oSource = oEvent.getSource();
var oModel = this.getModel();
var sPath = oSource.getBindingContext().sPath;
var sCtxPath = sPath + "/RatingValue";
var sCtxPathNA = sPath + "/NotApplicable";
var iValue = oEvent.getParameter("value");
oModel.setProperty(sCtxPath, iValue);
oModel.setProperty(sCtxPathNA, false);
},
Is this line
var sCtxPath = sPath + "/RatingValue";
not leading to another "change" event trigger?
Additionally, is there a loop in your formatter that could cause a 'hang'?
And what about any events in your master with the same odata path?

Get item based on displayname in sitecore

I need to get a specific item based on it's displayname, how do I do that?
For example I want to get this item /sitecore/content/mysite/about
But on the site is translated to multiple languages and could be something like www.site.com/om (in Sitecore it would be /sitecore/content/mysite/om)
There are a couple approaches you can take. The most efficent is to leverage the Content Search API, but the challenge is that Display Name is excluded from the index by default. A simple patch file can fix this:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<contentSearch>
<indexConfigurations>
<defaultLuceneIndexConfiguration>
<exclude>
<__display_name>
<patch:delete />
</__display_name>
</exclude>
</defaultLuceneIndexConfiguration>
</indexConfigurations>
</contentSearch>
</sitecore>
</configuration>
Then your code would be something like:
public Item GetItemByDisplayName(string displayName)
{
var searchIndex = ContentSearchManager.GetIndex("sitecore_master_index"); // sub your index name
using (var context = searchIndex.CreateSearchContext())
{
var searchResultItems =
context.GetQueryable<SearchResultItem>().Where(i => i["Display Name"].Equals(displayName)).FirstOrDefault();
return searchResultItems == null ? null : searchResultItems.GetItem();
}
}
This all is assuming you are on Sitecore 7. If you're on Sitecore 6, your option are limited and are probably not going to perform well if you content tree is large. Nonetheless, your function might look like:
public Item GetItemByDisplayName(string displayName)
{
var query = string.Format("fast:/sitecore/content//*[#__Display Name='{0}']", displayName);
var item = Sitecore.Context.Database.SelectSingleItem(query);
return item;
}
Please note that this will be horribly inefficent since under the covers this is basically walking the content tree.
Often, you wouldn't need to. LinkManager (responsible for generating all your item URLs) has an option to base the URLs on Display Name instead of Item.Name.
var d = LinkManager.GetDefaultUrlOptions();
d.UseDisplayName = true;
This can also be configured in configuration. Find and amend this section in your Web.config (or patch it via include files):
<linkManager defaultProvider="sitecore">
<providers>
<clear />
<add name="sitecore" type="Sitecore.Links.LinkProvider, Sitecore.Kernel"
addAspxExtension="false" alwaysIncludeServerUrl="false" encodeNames="true"
languageEmbedding="never" languageLocation="filePath" lowercaseUrls="true"
shortenUrls="true" useDisplayName="false" />
</providers>
</linkManager>
To truly do exactly what you ask is a quite involved process. If you point DotPeek to Sitecore.Pipelines.HttpRequest.ItemResolver, you can step through the ResolveUsingDisplayName() method. It essentially loops through child items, comparing the URL Part to the "__Display Name" field. You would have to cook up something similar.

Glass XE17.1 - tap on "ok glass" menu with custom voice command is broken

I used to create one voice trigger that prompts user to speak additional commands before starting my Activity or Service, like:
ok glass
+-David
++-find me a parking lot
++-show me stock chart
in XE17 or early version(XE16.2), either using voice command or tap on "ok glass" menu will shows a list(vertical list with voice) or a list of command cards (horizontal menu), but in XE17.1 update, when I tap on 'ok glass', it just hangs and no menu cards shows up, only ok glass launcher, no other default voice triggers cards, after a short debug, I found it's the same voice trigger
"android:resource="#xml/voice_trigger"
declare in AndroidMenifest.xml caused the issue, but voice command still works, could someone help? Thanks!
ps. and also, Im trying input prompt with two more prompt won't work.
<input prompt="#string/glass_voice_prompt"/>
MY CODE (GDK API19, rev.5)
<> AndroidManifest.xml
<uses-permission android:name="com.google.android.glass.permission.DEVELOPMENT"/>
<activity
android:name=".PromptActivity"
android:label="#string/app_name"
android:theme="#style/MenuTheme"
android:icon="#drawable/ic"
android:enabled="true" />
<activity-alias
android:name="find me a parking lot"
android:label="find me a parking lot"
android:targetActivity=".PromptActivity"
android:icon="#drawable/hippo_icon" >
<intent-filter>
<action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
</intent-filter>
<meta-data
android:name="com.google.android.glass.VoiceTrigger"
android:resource="#xml/hippo_voice_trigger_david" /> <!---HERE IS THE PROBLEM(two same voice trigger won't allow any more->
</activity-alias>
<activity-alias
android:name="show me stock chart"
android:label="show me stock chart"
android:targetActivity=".PromptActivity"
android:icon="#drawable/hippo_icon" >
<intent-filter>
<action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
</intent-filter>
<meta-data
android:name="com.google.android.glass.VoiceTrigger"
android:resource="#xml/hippo_voice_trigger_david" /> <!---HERE IS THE PROBLEM->
</activity-alias>
<> hippo_voice_trigger_david.xml
<?xml version="1.0" encoding="utf-8"?>
<trigger keyword="#string/glass_voice_david_prompt">
<constraints network="true" camera="true" />
</trigger>
<> res/values/strings.xml
<string name="glass_voice_david_prompt">David</string>
<> Here is the LogCat Exception:
FATAL EXCEPTION: main
Process: com.google.glass.home, PID: 5738
java.lang.NullPointerException
at com.google.glass.home.voice.TouchMainMenuActivity.onCreateOptionsMenu(TouchMainMenuActivity.java:122)
at android.app.Activity.onCreatePanelMenu(Activity.java:2543)
at com.android.internal.policy.impl.PhoneWindow.preparePanel(PhoneWindow.java:439)
at com.android.internal.policy.impl.PhoneWindow.openPanel(PhoneWindow.java:602)
at com.android.internal.policy.impl.PhoneWindow.openPanel(PhoneWindow.java:555)
at android.app.Activity.openOptionsMenu(Activity.java:2878)
at com.google.glass.app.GlassVoiceActivity.openOptionsMenu(GlassVoiceActivity.java:456)
at com.google.glass.home.voice.TouchMainMenuActivity.onAttachedToWindow(TouchMainMenuActivity.java:93)
at com.android.internal.policy.impl.PhoneWindow$DecorView.onAttachedToWindow(PhoneWindow.java:2793)
at android.view.View.dispatchAttachedToWindow(View.java:12592)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2458)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1242)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1025)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5699)

Way to nest multiple voice triggers when launching an app with GDK

Is there a way to nest voice triggers when launching an app on Google Glass using the GDK? For example instead of just saying "ok, glass" -> "What's its power level?" I'd like to have the app present an option. For example "ok, glass" -> "What's its power level?" -> "Over 9000" OR "Under 9000". Any help would be great!
If you have multiple activities/services installed on Glass that have the same voice trigger intent filter, all of their names (based on the android:label attribute of the <activity> or <service> tag in AndroidManifest.xml) will appear in a disambiguation "submenu" when you speak that voice trigger.
For example (assume that res/xml/play_a_game_trigger.xml represents a voice trigger for the string "play a game"):
<activity android:label="Tennis">
<intent-filter>
<action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
</intent-filter>
<meta-data android:name="com.google.android.glass.VoiceTrigger"
android:resource="#xml/play_a_game_trigger" />
</activity>
<activity android:label="Bowling">
<intent-filter>
<action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
</intent-filter>
<meta-data android:name="com.google.android.glass.VoiceTrigger"
android:resource="#xml/play_a_game_trigger" />
</activity>
would give you a voice menu flow that looks like
ok glass → play a game → Tennis
Bowling
Do note, however, that this menu would also include activities/services from other APKs that use the same voice trigger as well.
You can find more details at the Voice Input page of the GDK documentation.
The proper way to do this is using an input tag inside the trigger
<trigger keyword="#string/start_app" >
<input prompt="#string/promt_text" />
</trigger>
This prompts an input and waits for more audio speech.
Then in your activity you can capture this text with:
ArrayList<String> text = getIntent().getExtras().getStringArrayList(RecognizerIntent.EXTRA_RESULTS);

Magento: template based on attribute set

I want to create different product views based on the attribute set the product belongs to:
does Magento provide a way to do this?
- UPDATE -
Following dan.codes suggestion I've added
$update->addHandle('PRODUCT_ATTRIBUTE_SET_ID_'.$product->getAttributeSetId());
to Mage_Catalog_ProductController (I duplicated ProductController.php and put it in local/Mage/Catalog/controllers/).
Then I added this to catalog.xml
<PRODUCT_ATTRIBUTE_SET_ID_9> // PRODUCT ID of Book Attribute Set
<label>Catalog Product View (Book)</label>
<reference name="product.info">
<block type="catalog/product_view_type_book" name="product.info.book" as="product_type_data" template="catalog/product/view/attribute_set/book.phtml">
<block type="core/text_list" name="product.info.book.extra" as="product_type_data_extra"/>
</block>
</reference>
</PRODUCT_ATTRIBUTE_SET_ID_9>
just after
<PRODUCT_TYPE_virtual translate="label" module="catalog">
<label>Catalog Product View (Virtual)</label>
<reference name="product.info">
<block type="catalog/product_view_type_virtual" name="product.info.virtual" as="product_type_data" template="catalog/product/view/type/virtual.phtml">
<block type="core/text_list" name="product.info.virtual.extra" as="product_type_data_extra"/>
</block>
</reference>
</PRODUCT_TYPE_virtual>
I then created catalog/product/view/attribute_set/book.phtml, but it is not displayed in my product view page.
- UPDATE MAGENTO 1.5 -
I've noticed that the handler update has moved in the last Magento release.
$update->addHandle('PRODUCT_TYPE_'.$product->getTypeId());
$update->addHandle('PRODUCT_'.$product->getId());
is in Mage/Catalog/Helper/Product/View.php now.
I've tested and it still works great!
No it doesn't but you can extend the functionality to do so by extending the _initProductLayout method in Mage_Catalog_ProductController under where the code is this
$update = $this->getLayout()->getUpdate();
$update->addHandle('default');
$this->addActionLayoutHandles();
$update->addHandle('PRODUCT_TYPE_'.$product->getTypeId());
$update->addHandle('PRODUCT_'.$product->getId());
You could add
$update->addHandle('PRODUCT_ATTRIBUTE_SET_ID_'.$product->getAttributeSetId());
Then in your layout.xml you could have
<PRODUCT_ATTRIBUTE_SET_ID_IDHERE>
<reference name="root">
<action method="setTemplate"><template>template/path/here.html</template></action>
</reference>
</PRODUCT_ATTRIBUTE_SET_ID_IDHERE>
If in case you want to switch view.phtml based on the attribute set then here is what you need to do:
<PRODUCT_ATTRIBUTE_SET_ID_9>
<label>Catalog Product View (Default)</label>
<reference name="product.info">
<action method="setTemplate"><template>catalog/product/custom-view.phtml</template></action>
</reference>
</PRODUCT_ATTRIBUTE_SET_ID_9>
Just add this in your catalog.xml or local.xml
Hope this helps.
Thanks
There is a good tutorial on this: http://magebase.com/magento-tutorials/creating-custom-layout-handles/
This uses following event: controller_action_layout_load_before
For this I set up in config.xml following
<events>
<controller_action_layout_load_before>
<observers>
<mymodule>
<class>mymodule/observer</class>
<method>addAttributeSetHandle</method>
</mymodule>
</observers>
</controller_action_layout_load_before>
</events>
And in Observer.php I will have
public function addAttributeSetHandle(Varien_Event_Observer $observer)
{
$product = Mage::registry('current_product');
/**
* Return if it is not product page
*/
if (!$this->isBookProduct($product)) {
return;
}
$niceName = 'book';
/* #var $update Mage_Core_Model_Layout_Update */
$update = $observer
->getEvent()
->getLayout()
->getUpdate();
$handles = $update->getHandles(); // Store all handles in a variable
$update->resetHandles(); // Remove all handles
/**
* Rearrange layout handles to ensure PRODUCT_<product_id>
* handle is added last
*/
foreach ($handles as $handle) {
$update->addHandle($handle);
if ($handle == 'PRODUCT_TYPE_' . $product->getTypeId()) {
$update->addHandle('PRODUCT_ATTRIBUTE_SET_' . $niceName);
}
}
}
protected function isBookProduct($product)
{
if (null === $product || !($product instanceof Mage_Catalog_Model_Product)) {
return false;
}
// TODO instead of hardcoded value we could use here something neat to get by name thru eav/entity_attribute_set model, some config value which hold that ID or use some other approach...
$book_set_id = 9;
if ($product->getAttributeSetId() != $book_set_id) {
return false;
}
return true;
}
This makes possibility to use in layout xml following:
<?xml version="1.0"?>
<layout version="0.1.0">
<PRODUCT_ATTRIBUTE_SET_book>
<reference name="product.info">
<action method="setTemplate">
<template>mymodule/book/product/view.phtml</template>
</action>
</reference>
</PRODUCT_ATTRIBUTE_SET_book>
</layout>