Edit: This is a bug (missing feature?) in the manifest merger. It works in Android Studio 3.5 Canary 5 and above. So what one want's to do is to add one <deepLink /> per uri. Which in my case would be
<deepLink
android:id="#+id/deepLink"
app:uri="https://www.example.com/foo?cn={cardNumber}&bd={birthDate}"/>
<deepLink
android:id="#+id/deepLink2"
app:uri="https://www.example.com/foo?cn={cardNumber}"/>
I have a deep link in the form "https://www.example.com/foo?cn=L349DA&bd=1982-03-12"
and I parse it in my navigation graph with
<deepLink
android:id="#+id/deepLink"
app:uri="https://www.example.com/foo?cn={cardNumber}&bd={birthDate}"/>
That all works well. But my parameter bd is optional, so I'm not guaranteed that it will be included in the url. How do we handle this case?
I've tried with wildcards * on the parameter with no luck. And I've tried with adding two <deepLink .../> elements, but that yields a Manifest merger failed: Multiple destinations... error.
Thanks in advance!
In "androidx.navigation:navigation-*:2.2.0-alpha02"
September 5, 2019
Deep links with query parameters now support reordered query parameters; arguments that have a default value or are nullable are now optional when matching deep links. (b/133273839)
Android Developers Jetpack AndroidX Navigation
Related
I have a fragment in a navigation graph with two parameters (ids: List<Int>? and name: String?) - these both have default values set (both set to #null).
I have created a deeplink to this fragment from the pattern mysite.com/{name} but after upgrading to navigation version 2.4.0-alpha08 I get this error when running my app:
Caused by: java.lang.IllegalArgumentException: Deep link mysite.com/{name} can't be used to open destination Destination(com.mysite:id/myFragment) class=com.mysite.MyFragment.
Following required arguments are missing: [ids]
As the exception is thrown when inflating my MainActivity.xml, it seems like the default value for ids is being ignored when validating the deeplink.
This didn't happen in version 2.4.0-alpha06.
Is this a bug in this version of the navigation component (I'll raise a bug if so), or is this just better validation in that component revealing a bug in my code - if so, what's the fix?
Horribly, here's the hack I'm using.
URL parameters are optional if their value has a default set, so my deeplinks in the navigation graph now look like this:
mysite.com/{name}?this_wont_ever_really_happen={ids}
which matches the url mysite.com/{name} because ids has a default value (of #null)
Jetpack Navigation version 2.5.0-alpha04 release note mentions a fix to solve this kind of problem:
I want to implement the android.intent.action.SEND as per the developers tutorial with the navigation component.
But when making deep links in the navigation.xml it requires a Uri with the below error message:
Navigation XML document element must contain a app:uri
attribute.
I am using Android Studio 4.1.3 and I do have the option to choose an action. But it just doesn't work without uri.
The docs are leaving some basic questions open:
How to get the intent params like Intent.EXTRA_TEXT
How to provide category and 'data'?
How to provide multiple actions/categories/datas?
I'm attempting to add a deep-link for a URL that has the following format:
<deepLink
android:id="#+id/deep_link"
android:autoVerify="true"
app:uri="my.example.com/articles/{slug}" />
This causes the slug argument passed to my destination to also include the query if it exists. For example, the URL my.example.com/articles/recent-article?utm=1 results in the slug argument being recent-article?utm=1.
I've tried using the following pattern format in an attempt to ignore the query, but URLs no longer match correctly.
<deepLink
android:id="#+id/deep_link"
android:autoVerify="true"
app:uri="my.example.com/articles/{slug}?*.*" />
Is there a way to effectively ignore the query?
Assuming you're using the latest Navigation 2.2.0-rc04 (or one of the other Navigation 2.2 releases that adds support for query parameters), it sounds like you're hitting this issue where deeplinks without query parameters don't ignore query parameters.
The workaround mentioned in the bug is to include a dummy parameter:
<deepLink
android:id="#+id/deep_link"
android:autoVerify="true"
app:uri="my.example.com/articles/{slug}?dummy={dummy} />
I am checking below google sample code for test Deep-linking with Navigation.
Navigation with Deep linking Basic Sample
It works well. But in navigation.xml file I don't want to add uri directly , I want to use strings.xml file for same.
Not this :
<deepLink app:uri="www.example.com/user/{userName}" />
but , Want to do like this ,
<deepLink app:uri="#string/profile_url" />
the reason is that, if there is any changes in URL then I just have to go in strings.xml file and replace relative things.
Let me know if you have better idea about it or any better optimized solution.
I have an android app that using com.google.android.gms.actions.SEARCH_ACTION
to search a phrase on my app using search for PHRASE on APP_NAME, but now I want use custom voice command like APP_NAME PHRASE to open my app and pass that phrase using google assistant.
So is it possible to implement this feature?
I have tried with https://github.com/actions-on-google/appactions-fitness-kotlin to get deep idea about actually how action intent works and found that it may be possible using deep linking.
Here in this example in actions.xml file one action actions.intent.GET_EXERCISE_OBSERVATION implemented as you can see below code.
<action intentName="actions.intent.GET_EXERCISE_OBSERVATION">
<fulfillment
fulfillmentMode="actions.fulfillment.SLICE"
urlTemplate="content://com.devrel.android.fitactions.FitSliceProvider/stats{?exerciseType}">
<parameter-mapping
entityMatchRequired="true"
intentParameter="exerciseObservation.aboutExercise.name"
required="true"
urlParameter="exerciseType" />
</fulfillment>
<fulfillment
fulfillmentMode="actions.fulfillment.DEEPLINK"
urlTemplate="https://fit-actions.firebaseapp.com/stats" />
<parameter name="exerciseObservation.aboutExercise.name">
<entity-set-reference entitySetId="ExerciseEntitySet" />
</parameter>
</action>
<!-- Defines an entity set with our supported entities -->
<entity-set entitySetId="ExerciseEntitySet">
<entity
name="#string/activity_running"
alternateName="#array/runningSynonyms"
identifier="RUNNING" />
<entity
name="#string/activity_walking"
alternateName="#array/walkingSynonyms"
identifier="WALKING" />
<entity
name="#string/activity_cycling"
alternateName="#array/cyclingSynonyms"
identifier="CYCLING" />
</entity-set>
But now I have some questions regarding this code.
How urlTemplate content://com.devrel.android.fitactions.FitSliceProvider/stats{?exerciseType} for actions.fulfillment.SLICE is generated?
Can exerciseObservation.aboutExercise.name have any custom value rather then defined in entity-set ?
How urlTemplate https://fit-actions.firebaseapp.com/stats for actions.fulfillment.DEEPLINK is generated?
After implementing this I think actions.intent.OPEN_APP_FEATURE will be helpful with the help of DEEPLINK fulfillment.
So is it possible to implement this using actions.intent.OPEN_APP_FEATURE"?
How urlTemplate content://com.devrel.android.fitactions.FitSliceProvider/stats{?exerciseType}
for actions.fulfillment.SLICE is generated?
The urlTemplate value (whether fulfilling via slice or deep link) is fully up to you to define. In the case of a deep link, this is the URL the system will call to open up your app. In the case of a Slice, this is the contentUri the system will call to render the Slice. The parameters inside the {} will be expanded with values at runtime. To get a better understanding of how that works, see the docs here and here or the Google I/O 2019 session.
Can exerciseObservation.aboutExercise.name have any custom value rather then defined in entity-set ?
I'm not exactly sure what you mean here but let me try and give more detail. The param name of exerciseObservation.aboutExercise.name is set for each Assistant Intent can cannot be changed. These values are listed in the documentation (example). The actual values of the parameters (that are populated by the user's query at runtime) are dynamic and will change based on the user's query and the Assistant Intent. For each Assistant Intent, you can refer to the docs to see what the possible values can be. In some cases they are from a set list of values (like for GET_EXERCISE_OBSERVATION), for others it could be a free form value based on the user's input, and for others still you can optionally extend the values using inline inventory (this is what you use <entity-set> for in your example).
How urlTemplate https://fit-actions.firebaseapp.com/stats for
actions.fulfillment.DEEPLINK is generated?
As per #1, the value of urlTemplate is totally up to you to configure. It can be any Android Intent URI. The system will call this Uri to start up your app/Activity.
After implementing this I think
actions.intent.OPEN_APP_FEATURE will be helpful with the
help of DEEPLINK fulfillment.
So is it possible to implement this using
actions.intent.OPEN_APP_FEATURE"?
OPEN_APP_FEATURE is just another Assistant Intent that allows a generic call into a feature of your app. The docs were recently updated with some example queries. Eg.
Open Youtube history
This example will open the app named "YouTube" and pass the feature name "history" to the app to handle.
Open Example App Example feature
This example will open the app named "Example App" and pass the feature name "Example feature" to the app to handle.