2

My question is relatively simple considering the options shown in the official documentation and code labs but i've been struggling to make it work.

I want to trigger a widget to be shown in Google Assistant via a dynamic shortcut. Seems pretty straightforward but when implementing a capability and dynamic shortcut like this:

<capability
    android:name="actions.intent.GET_RESERVATION">
    <app-widget
        android:identifier="GET_MY_RESERVATION"
        android:targetClass="com.myapp.widget.MyWidget">
        <parameter
            android:name="reservation.reservationFor.name"
            android:key="shortcutId"
            android:required="true"
            app:shortcutMatchRequired="true" />
        <extra android:name="hasTts" android:value="true"/>
    </app-widget>
    <intent
        android:identifier="GET_MY_RESERVATION_FALLBACK"
        android:action="android.intent.action.VIEW"
        android:targetClass="com.myapp.widget.MyWidget">
    </intent>
</capability>
val shortcut = ShortcutInfoCompat.Builder(context, "shortcut_id")
        .setShortLabel("shortcut label"))
        .setExcludedFromSurfaces(ShortcutInfoCompat.SURFACE_LAUNCHER)
        .setLongLived(false)
        .addCapabilityBinding(
            "actions.intent.GET_RESERVATION",
            "reservation.reservationFor.name",
            context.resources.getStringArray(R.array.synonyms).toList()
        )
        .setIntent(Intent(context, MyWidget::class.java).apply {
            action = Intent.ACTION_VIEW
        })
        .setRank(2)
        .build()
ShortcutManagerCompat.pushDynamicShortcut(context, shortcut)

The intent defined for the shortcut is the one triggered rather then the widget defined for the capability. Moreover, the shortcut definition above is crashing the app since it expects its intent to be something that could be invoked via startActivity() (and a widget is not).

If i define the same shortcut statically:

<shortcut
    android:shortcutId="shortcut_id"
    android:shortcutShortLabel="shortcut label">
    <capability-binding
        android:key="actions.intent.GET_RESERVATION">
        <parameter-binding
            android:key="reservation.reservationFor.name"
            android:value="@array/synonyms" />
    </capability-binding>
</shortcut>

I can omit the intent and triggering this action will delegate the logic to the capability's widget as expected. Unfortunately I couldnt find a way to create a dynamic shortcut without an intent.

Anything im missing here? Help is appreciated.

AsafK
  • 2,425
  • 3
  • 32
  • 38

2 Answers2

0

When you add the addCapabilityBinding call on the ShortcutInfoCompat builder, you're telling the Google Assistant that this Android shortcut can be listed as a Google Assistant shortcut. After triggering the code that pushes the shortcut, your shortcut should appear in two places: after long pressing the app icon, and at the Google Assistant's settings (you can type "my shortcuts" on Google Assistant to see a list of available shortcuts). I tried to add a shortcut on an emulator but unfortunately I couldn't see it on Google Assistant. More info in the official documentation.

This, though, doesn't seem like what you're trying to accomplish: trigger a widget from an Android shortcut. The Intent that you have to define here has to be an Android intent. In most cases, we declare an Android intent with an Activity from the host app but you can deeplink into other apps if you have the info. It turns out that I've already made some apps that deeplink from my Android app into the Google Assistant. You can try something like this:

.setIntent(Intent(Intent.ACTION_VIEW, Uri.parse("https://assistant.google.com/services/invoke/uid/YOUR_UDID?intent=actions.intent.GET_TAXI_RESERVATION")))

Where YOUR_UDID is the one listed on the App Actions Plugin. I guess that once your app is in production, the UDID will be different. I could get this working with this instruction :) Hope this helps.

  • Thank you so much for the answer and sorry about my delayed response. – AsafK Apr 24 '23 at 09:20
  • Regarding your first paragraph, in addition to the benefits of shortcuts you mentioned they can also serve as an instance of a capability. Meaning, for cases we want to narrow down our BII triggering filter to a list of predefined synonyms. This, together with the `shortcutMatchRequired` label suppose to make sure the capability is used only when one of the synonyms was recognized in the user's voice command. This combination is the main feature im interested in using. – AsafK Apr 24 '23 at 09:27
  • And it works pretty well when using static shortcuts. The problem is when im using dynamic shortcuts. I've tried the solution you've suggested but unfortunately it doesnt work also. Setting the shortcut's intent with a deeplink to google assistant always redirects to the capability fallback intent and not the appwidget. This whole thing is becoming pretty frustrating tbh. – AsafK Apr 24 '23 at 09:32
  • Update: Managed to call the widget from a dynamic shortcut with your suggested solution. The thing that prevented it from working was the `android:required="true"` tag in the capability. Now the issue is with passing the shortcutId (or any other) parameter using the suggested intent. It doesnt work. – AsafK Apr 24 '23 at 14:06
0

When you add the addCapabilityBinding call on the ShortcutInfoCompat builder, you're telling the Google Assistant that this Android shortcut can be listed as a Google Assistant shortcut. After triggering the code that pushes the shortcut, your shortcut should appear in two places: after long pressing the app icon, and at the Google Assistant's settings (you can type "my shortcuts" on Google Assistant to see a list of available shortcuts). I tried to add a shortcut on an emulator but unfortunately I couldn't see it on Google Assistant. More info in the official documentation.

haxxorman
  • 11
  • 2