how can I deeplink an app from Google Assistant? - google-cloud-platform

I'm creating a dialogflow agent integrated with Google Assistant.
What I'd like to do is to open an app (my app) when a proper intent is matched. I've seen that actions like Youtube, Spotify etc. are able to do that, for example I can tell the Youtube action "search for cats video" and the Youtube app will open with a list of cats videos.
I tried to use the DeepLink class but I then noticed it's deprecated.
DeepLink class
Is there any way you can suggest me to do this?
Thanks in advance

I think you are looking for App Actions. Here are the steps you need to follow:
Find the right built-in intent. actions.intent.OPEN_APP_FEATURE should be the right one for you.
Create and update actions.xml. It should look like
<?xml version="1.0" encoding="UTF-8"?>
<!-- This is a sample actions.xml -->
<actions>
<action intentName="actions.intent.OPEN_APP_FEATURE">
<!-- Use url from inventory match for deep link fulfillment -->
<fulfillment urlTemplate="{#url}" />
<!-- Define parameters with inventories here -->
<parameter name="feature">
<entity-set-reference entitySetId="featureParamEntitySet" />
</parameter>
</action>
<entity-set entitySetId="featureParamEntitySet">
<!-- Provide a URL per entity -->
<entity url="myapp://deeplink/one" name="featureParam_one" alternateName="#array/featureParam_one_synonyms" />
<entity url="myapp://deeplink/two" name="featureParam_two" alternateName="#array/featureParam_two_synonyms" />
</entity-set>
</actions>

Related

Sitecore.Context.User.IsAuthenticated returns true for extranet\Anonymous user

I have Sitecore 6.6 installed. I wanted to add a new domain to Sitecore; Since my Sitecore instance is deployed in two servers with two Sitecore sites in each pointing to different web databases but same core, master and analytics databases, I couldn't do it using Sitecore Domain manager.So I thought of doing it manually by editting the App_Config\Security\domains.config in the server. The following was the domains.config that I had.
<?xml version="1.0" encoding="utf-8"?>
<domains xmlns:sc="Sitecore">
<domain name="sitecore" ensureAnonymousUser="false" />
<domain name="extranet" defaultProfileItemId="{AE4C4969-5B7E-4B4E-9042-B2D8701CE214}" />
<domain name="default" isDefault="true" />
<sc:templates>
<domain type="Sitecore.Security.Domains.Domain, Sitecore.Kernel">
<ensureAnonymousUser>true</ensureAnonymousUser>
<locallyManaged>false</locallyManaged>
</domain>
</sc:templates>
<domain name="Station" defaultProfileItemId="{F181ED3D-F342-46E6-B6F6-2A6A6173B513}" />
<domain name="Emailcampaign" />
</domains>
I added one more domain(MyDomain) at the end like below.
<?xml version="1.0" encoding="utf-8"?>
<domains xmlns:sc="Sitecore">
<domain name="sitecore" ensureAnonymousUser="false" />
<domain name="extranet" defaultProfileItemId="{AE4C4969-5B7E-4B4E-9042-B2D8701CE214}" />
<domain name="default" isDefault="true" />
<sc:templates>
<domain type="Sitecore.Security.Domains.Domain, Sitecore.Kernel">
<ensureAnonymousUser>true</ensureAnonymousUser>
<locallyManaged>false</locallyManaged>
</domain>
</sc:templates>
<domain name="Station" defaultProfileItemId="{F181ED3D-F342-46E6-B6F6-2A6A6173B513}" />
<domain name="Emailcampaign" />
<domain name="MyDomain" />
</domains>
As soon as I did that, Sitecore.Context.User.IsAuthenticated started returning true for extranet\Anonymous user(Non-logged in user) in the code.
Has anyone faced this issue before?
Please let me know where am I going wrong.
I also encounted this issue back when I was working with Sitecore 6.6, I'm not certain if its an issue in later versions. Essentially when you modified your domains.config with the param ensureAnonymousUser set to true the Anonymous User for that domain, in this case Extranet, was created in the database - it may not have been until you changed that setting.
In Sitecore all non-logged in users view the site as the user *domain*/anonymous. As Sitecore's membership is based on .NET Membership it determines that the User is logged in as its using that account.
Therefore I recommend completing an additional check with your Sitecore.Context.User.IsAuthenticated to check if the username of User's account is *domain of site*/anonymous, Sitecore.Context.User.Name, if it is return false.
EDIT
I have confirmed Sitecore.Context.User.IsAuthenticated returning true for *domain*\Anonymous user has been fixed in Sitecore 8. Therefore you can use it to determine if the User is logged in and not using the *domain*\anonymous account.
We finally resolved this issue! This was caused by a fix we added to solve an issue we had with Sitecore ECM. The issue was that Sitecore used to log out as soon as we clicked on the message preview. So we followed the steps given in the below thread to fix the issue.
https://stackoverflow.com/a/30836600/4165670
But we were not testing for Anonymous user like it is done in the thread. We never pushed this code into Content Delivery site and when
we created the new domain, This code got pushed into the Content Delivery site with some other code.
Since we are setting the current user as the Active user in the code, it started showing that extranet\Anonymous user as the current user.

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);

keeping data during orientation changes by using fragments

I am trying to understand fragments. All the examples I read is about having a main activity and then two sub fragments.
The issue is that my program has only 1 activity. Can I make it a fragment?
Current ui main class
public class MainActivity extends Activity {}
Can I make it
public class MainActivity extends Fragment {}
The program I am trying to create will constantly monitor phone variables and display logs in a textView. I don't want to lose the logs when the user changes the orientation or some other change when the os destroys the ui.
The UI is basically 1 textView that gets filled by a runnable that updates the textView every 5 seconds with the content of a linked list. I don't want to lose the content of the linked list basically.
I checked getLastNonConfigurationInstance() but it seems it's depreciated so I don't want to use that
Any help would be highly appreciated.
Amish
Found answer here:
http://blog.webagesolutions.com/archives/458
So after a lot of searching I found that if you add the following:
android:configChanges="orientation|screenSize"
in the androidManifest.xml, the os will not destroy the activity when switching from portrait mode to landscape mode.
My xml file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.axr0284.phonecontrol"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="15" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.axr0284.phonecontrol.MainActivity"
android:label="#string/app_name"
android:configChanges="orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Hope this helps somebody,
Amish

Download specific version of a file from SharePoint using web services

Can someone provide a sample for downloading a specific version of a file from SharePoint using web services? Normally I would get the file with the Copy Web Service (.../_vti_bin/copy.asmx). But I don't really know how to specify a version.
Regards
Anton Kalcik
You can use the Versions web service to get which versions exist for a File
The GetVersions method will give you an xml like this:
<results xmlns="http://schemas.microsoft.com/sharepoint/soap/">
<list id="{26E516B0-8241-4B97-984D-000000000000}" />
<versioning enabled="1" />
<settings url="http://Server_Name/Site_Name/_layouts/
1033/LstSetng.aspx?
List={26E516B0-8241-4B97-984D-000000000000}" />
<result version="#4" url="http://Server_Name/Site_Name/
Shared Documents/File_Name.doc"
created="6/7/2003 5:55 PM" createdBy="DOMAIN\User" size="19968"
comments="" />
<result version="1" url="http://Server_Name/Site_Name/
_vti_history/1/Shared Documents/File_Name.doc"
created="6/7/2003 5:49 PM" createdBy="DOMAIN\User" size="19968"
comments="" />
.
.
.
</results>
You can then just use a HTTP GET request for the content of the "url" attribute of the "result" node for the right version
Here's the exact thing you want to do, with code:
Article

How do I rename a file using the SharePoint web services?

I have a custom definition for a document library and I am trying to rename documents within the library using only the out of the box web services. Having defined a view with the "Name" field supplied and trying the "LinkFilename", my calls to rename a file are respectively returning a failure or ignoring the new value.
How do I rename a file using the SharePoint web services?
Use the Lists.UpdateListItems web method. The XML request should look like:
<Batch OnError="Continue" PreCalc="TRUE" ListVersion="0">
<Method ID="1" Cmd="Update">
<!-- List item ID of document -->
<Field Name="ID">2</Field>
<!-- Full URL to document -->
<Field Name="FileRef">http://Server/FullUrl/File.doc</Field>
<!-- New filename -->
<Field Name="BaseName">NewName</Field>
</Method>
</Batch>
You should be able to use UpdateListItems. Here's an example.
Per comment: So the actual question is "how do I call a web service?" Take a look a this example. Some more good walkthroughs here.