建立 action.xml (已淘汰)

找出要實作的應用程式內功能和內建意圖 (BII) 後,即可在 Android 應用程式中建立 actions.xml 資源,將 BII 對應至應用程式功能。在 actions.xml 中定義的應用程式動作會說明每個 BII 如何解析執行要求,以及擷取並提供給應用程式的參數。

總覽

為了將應用程式動作整合到您的 Android 應用程式內,您必須在應用程式專案的 res/xml 目錄內放置 actions.xml 檔案。

AndroidManifest.xml 檔案中,使用 <meta-data> 標記新增 actions.xml 檔案的參考資料。例如:

<application>
    <!-- ... -->
    <meta-data android:name="com.google.android.actions" android:resource="@xml/actions" />
</application>

這樣可以為在 APK 中的 xml/actions.xml 檔案宣告 XML 資源。若要進一步瞭解如何在 Android 內指定資源,請見 Android 開發人員文件的「應用程式資源總覽」。

結構定義

以下表格會說明 actions.xml 的結構定義。加入標記時,除非有標註「非必要」,否則須提供所有屬性。

標記 包含於 屬性
<actions> 頂層
<action> <actions>

intentName

queryPatterns (僅適用於自訂意圖)

<parameter> <action> name
<entity-set-reference> <parameter>

entitySetId

urlFilter

<fulfillment> <action>

urlTemplate

fulfillmentMode (非必要)

requiredForegroundActivity (非必要)

<parameter-mapping> <fulfillment>

urlParameter

intentParameter

required (非必要)

entityMatchRequired (非必要)

<entity-set> <actions> entitySetId
<entity> <entity-set>

name (以及非必要的 alternateName) 或

sameAs

identifierurl

標記說明

本章節會說明 actions.xml 的各種結構定義標記。

<action>

該應用程式支援的應用程式動作。您必須為 actions.xml 檔案中所有 <action> 標記提供至少一項 <fulfillment>

屬性:

  • intentName:該應用程式動作的內建意圖 (例如 actions.intent.CREATE_TAXI_RESERVATION)。支援的內建意圖清單請見內建意圖參考資料

  • queryPatterns:期望使用者為此意圖提出的查詢內容集。這個屬性僅適用於自訂意圖,BII 內已有為使用者想要的作業或資訊的常見表達方式建立的模型。

<parameter>

擁有名稱及關聯實體清單的應用程式動作的參數。

屬性:

  • name:和此參數關聯的名稱 (例如「目的地」)。此名稱應是 BII 參數的分葉層級欄位 (例如 tradeOrder.assetOrdered.assetIssuedBy.name)。如果參數是基本類型 (例:字串),則名稱會直接使用參數的名稱。

<entity-set-reference>

開發人員提供的 schema.org 動態饋給參考資料。動態饋給必須在 actions.xml 檔案裡直接使用 <entity-set> 標記提供。

屬性:

  • entitySetId:特定實體系列的參考資料。這個屬性必須對應 <entity-set> 內的 entitySetId

  • urlFilter:提供網站清查給執行要求時使用的網址路徑。本屬性支援兩種萬用字元:

    • *:一個星號,符合緊接前方且 0 個以上的字元序列。

    • .*:半形句號後面加上星號,符合 0 個以上字元的任何序列。

    • 僅有常值的 *\ 才需要逸出字元,各自可以逸出為 \\*\\\\

<fulfillment>

關於如何使用 Android 應用程式執行使用者意圖的資訊。開發人員可以在 actions.xml 裡提供多個 <fulfillment> 標記,並為每個意圖提供不同的必要參數集。

如果有提供所有填寫使用者查詢內容的必要參數,則 Google 會使用第一個 <fulfillment>。您必須提供一個沒有任何必要參數的 <fulfillment> 當做備用執行要求。

屬性:

  • urlTemplate:建構裝置要開啟的深層連結或 Slice URI 的範本。如果有該範本必要的所有參數,即可使用使用者意圖參數擴充此範本。HTTP 網址範本範例請看 Wikipedia 網址範本條目。範本格式需遵守 RFC 6570 URI 範本規格

  • fulfillmentMode:(非必要) 提供使用的執行要求模式。有效的值包括:

    • actions.fulfillment.DEEPLINK:使用深層連結開啟 Android 應用程式,藉此執行使用者動作。此為預設值。

    • actions.fulfillment.SLICE:內嵌由 Android 應用程式提供的 Slice,藉此執行使用者動作。

  • requiredForegroundActivity:(非必要) 限制活動必須要在前景,才能使用前景應用程式叫用觸發應用程式動作。

    • 指定沒有任何使用應用程式套件名稱的類別縮寫的活動,後面加上正斜線 (/),然後加上活動名稱:APP_PACKAGE_NAME/ACTIVITY_NAME

以下提供部分網址範本值範例:

範本 擴充值
https://example.com/test{?foo,bar} "foo": "123"

"bar": "456"

https://example.com/test?foo=123&bar=456
https://example.com/test?utm_campaign=appactions{&foo,bar} "foo": "123"

"bar": "456"

https://example.com/test?utm_campaign=appactions&foo=123&bar=456
https://example.com/test?utm_campaign=appactions{#foo} "foo": "123" https://example.com/test?utm_campaign=appactions#foo=123
myapp://example/{foo} "foo": "123" myapp://example/123
intent://foo#Intent;scheme=my-scheme{;S.extra1,S.extra2};end "S.extra1": "123"

"S.extra2": "456"

intent://foo#Intent;scheme=my-scheme;S.extra1=123;S.extra2=456;end

如果想進一步瞭解如何設定網址範本,請見執行要求內的網址範本

<parameter-mapping>

將意圖參數對應至網址範本內的變數。這項對應的鍵代表了網址範本參數,或如 RFC 6570 所稱的「變數」。

如果意圖內沒有參數,則展開網址範本時保持不定義對應的變數。未定義變數的處理方式說明請見 RFC 6570 的第 3.2.1 節

注意,required="true"entityMatchRequired="true" 不同。

屬性:

  • urlParameter:所有網址範本內提及的變數都必須在 <parameter-mapping> 有對應的 urlParameter。舉例來說,如果 uri_template 是 http://spysatellite.com/show{?lat,long},則 <parameter-mapping> 裡必須有參數 latlong 的鍵。

  • intentParameter:參照意圖參數的值。如果意圖參數是結構化類型,請用點標記法參照巢狀結構欄位。舉例來說,如果有某個參數 taxiReservation 使用類型 schema.org/TaxiReservation,則您可以使用 taxiReservation.pickupLocation.geo.latitude 參照緯度值。

    如果有為此參數提供實體集,則 intentParameter 必須完全符合對應 <parameter> 標記 (例如 taxiReservation.pickupLocation.geo.latitude) 的名稱。如果意圖參數是複雜類型,則該值應該要對應該參數 (例如 taxiReservation) 的物件參考資料。如果意圖參數是基本類型,則該值應該直接使用參數的名稱。

  • required:(非必要) 表示必須要有指定的 intentParameter,這個網址範本才會有效。如果使用者查詢內容內並無指定的 intentParameter 值,則系統會捨棄這個網址範本。

  • entityMatchRequired:(非必要) 表示必須要有指定的 intentParameter 的相符清查。預設為 false

    這項屬性設為 true 時,如果有相符的清查,則會將相符的 ID 傳遞到網址範本。否則,如果沒有相符的內容,Google 助理便會略過該執行要求。

    這項屬性設為 false 時,如果有相符的清查,則會將相符的 ID 傳遞到網址範本。否則,Google 助理會提供從使用者查詢內容中擷取的 BII 參數值。

<entity-set>

actions.xml 內的內嵌實體集。

屬性:

  • entitySetIdactions.xml 內的 <entity-set> 的必要專用 ID (例如 "myInlineEntitySet1")。這個值也必須對應 <entity-set-reference> 標記內的 <entitySetId>值。

    entitySetId 的值必須有至少 30 個英數字元 (不可使用 -_ 等特殊字元),並須以英文字母開頭。

<entity>

actions.xml 內嵌實體集內的元素。包括 schema.org/Thing 欄位的子集。

urlidentifier 以及 sameAs 欄位的字串值可以是硬式編碼,或透過 APK 的字串資源進行參照。提供同義詞時,參照 APK 字串陣列資源alternateName 欄位請用字串值。

屬性:

  • name:實體必要名稱,除非您要指定 sameAs 欄位。必須是專用值,不得和指定 <entity-set> (例如「牙膏」) 的實體 namealternateName 欄位相同。

  • alternateName:(非必要) 該實體的替代名稱。您必須先指定 name 欄位,然後才能指定 alternateName 欄位。必須是專用值,不得和指定 <entity-set> 的實體 namealternateName 欄位相同。當使用者查詢內容符合此處任一字串,便會選取此實體。

  • sameAs:可明確識別實體的參照網頁網址。只有在意圖參數類型是 schema.org/Enumeration 子類型時,才能用來識別列舉值。

    類型為 schema.org/Enumeration 子類型的參數欄位 (如 MealTypeBreakfast) 必須提供此項目。

  • identifier:實體 ID。必須為專用值,不得和指定 <entity-set> (例如 CAPPUCCINO_ID) 的實體相同。

  • url:要用 Android 裝置開啟的 RFC 3986 網址。HTTP 用戶端不一定能夠解析這個網址。舉例來說,在 Android 上,這段網址可能是應用程式連結的「http://」網址,或裝置專用的網址,例如「intent://」網址,或是使用自訂網址配置的網址。

    您可以透過以下方式,使用 url 欄位搭配 <fulfillment>urlTemplate 屬性:

    • 在內嵌清查中提供 url 值,然後在 <fulfillment> 內省略 urlTemplate

    • 在內嵌清查中提供 url 值,然後在 urlTemplate 值內使用這些值 (例如 {@url}?extra_param=ExampleValue)。

必須提供 identifierurl 兩者之一。指定實體集裡的所有實體都必須使用相同的屬性 (identifier 或是 url)。

應用程式動作內嵌清查

您可以讓部分內建意圖選擇將實體擷取內容導入 actions.xml 指定的支援實體集,這稱為內嵌清查。當有使用者叫用您的應用程式動作時,Google 助理會比對使用者查詢參數和指定為內嵌清查的實體。然後,Google 助理便可以在產生執行要求深層連結時,使用對應清查項目的 ID。

您主要會使用 <entity-set><entity> 元素定義內嵌清查。內嵌清查可以讓應用程式只需要處理應用程式動作叫用的 ID 或網址,而不需要識別字串或 Google 列舉值,藉此簡化開發過程。

舉例來說,您的應用程式提供多種可供使用者點購的飲品,而您預期使用者會使用以下要求點購相同類型的飲品:

  • Ok Google,使用範例應用程式點一份藍莓涼爽冰招牌拿鐵。

  • Ok Google,使用範例應用程式點一份藍莓冰咖啡。

在嵌入清查中,您指定「藍莓涼爽冰招牌拿鐵」做為對應 ID 12345a 的實體。您也可以指定「藍莓冰咖啡」做為對應相同 ID 的實體。現在,當有使用者用以上查詢內容觸發應用程式動作時,Google 助理就能使用 ID「12345a」產生執行要求的深層連結。

在所有實體集當中,每個應用程式最多可以指定 1,000 個實體。每個 <entity> 最多可以定義 20 個 alternateName 同義詞。

應用程式動作網站清查

部分內建意圖可以使用網站清查當做產生執行要求網址的方法。網站清查會使用您的網站偵測應用程式動作執行要求網址。如果您的網站非常知名,而應用程式內的深層連結是可公開檢視的網站內容,就非常適合使用這個功能。

若要使用網站清查,請更新 actions.xml

  1. 在您想使用網站清查的 <action> 標記內,新增 <fulfillment> 標記,並將其 urlTemplate 屬性設定為 {@url}

  2. 在同一個 <action> 標記中新增 <parameter> 標記,並將其 name 屬性設定為最接近網頁描述實體的內建意圖參數。舉例來說,為 ORDER_MENU_ITEM 提供網站清查時,您應該將選單頁面連結到 menuItem.name,並將餐廳位置頁面連結到 menuItem.inMenuSection.inMenu.forRestaurant.name

  3. 在新的 <parameter> 標記中新增 <entity-set-reference> 標記,並將其 urlFilter 屬性設定為您希望網站清查使用的網址路徑。

執行以上步驟後,Google 助理即可使用您在 urlFilter 屬性提供的網址路徑進行網頁搜尋。然後,Google 助理便可以使用結果為執行要求提供 {@url} 的值。接著,您的深層連結處理常式即可根據 Google 助理回傳的深層連結轉送使用者,以便處理該執行要求。

舉例來說,您的網站內有路徑開頭為 https://www.example.com/items/ 的產品清單。您使用的是 urlFilterhttps://www.example.com/items/.*,而 Google 助理在之後回傳執行要求網址,例如 https://www.example.com/items/item123。有關 urlFilter 屬性的資訊,請見 <entity-set-reference>

執行要求內的網址範本

您可以使用動態參數預留位置,在 <fulfillment> 標記內宣告網址範本。此範本使用應用程式連結網址、自訂配置或意圖網址對應到 Android 活動之一。

設定網址範本

應用程式連結網址範例:

<action intentName="actions.intent.CREATE_TAXI_RESERVATION">
    <fulfillment urlTemplate="http://my-taxi.com/order{?dropoffLocation}">
        <parameter-mapping
                intentParameter="taxiReservation.dropoffLocation.name"
                urlParameter="dropoffLocation"/>
    </fulfillment>
</action>

自訂配置範例:

<action intentName="actions.intent.CREATE_TAXI_RESERVATION">
    <fulfillment urlTemplate="mytaxi://reserve{?dropoffLocation}">
        <parameter-mapping
                intentParameter="taxiReservation.dropoffLocation.name"
                urlParameter="dropoffLocation"/>
    </fulfillment>
</action>

意圖網址範例:

<action intentName="actions.intent.CREATE_TAXI_RESERVATION">
    <fulfillment
            urlTemplate="intent:#Intent;package=com.example.myapp;action=com.example.myapp.MY_ACTION{;S.dropoff};end">
        <parameter-mapping
                intentParameter="taxiReservation.dropoffLocation.name"
                urlParameter="S.dropoff"/>
    </fulfillment>
</action>

為執行要求指定 <parameter-mapping> 時,intentParameter 屬性表示由使用者提供的內建意圖參數。在上述範例中,該參數為下車地點名稱 (taxiReservation.dropoffLocation.name)。您可以參閱內建意圖參考資料,瞭解任何內建意圖可以使用的參數。

如果想將內建意圖參數對應到網址內的位置,請用 <parameter-mapping> 標記的 urlParameter 屬性。此屬性對應您想取代為使用者提供資訊的網址範本內的預留位置值。您的 urlTemplate 內必須有該預留位置值,左右須用大括號 ({}) 包住。

應用程式連結網址

如果您使用應用程式連結網址,則可以用指向標準 HTTP 網址的 urlTemplate 觸發活動。參數會以網址參數的形式傳遞到應用程式連結網址內。urlTemplate 內的參數左右必須用大括號 ({}) 包住,並在前端加上半形問號 (?)。如果並未設定參數,則結果會略去參數 (包括大括號)。

舉例來說,如果有使用者要求搭乘計程車前往舊金山並觸發了應用程式動作,那麼最終觸發的 URI (替換參數之後) 會像這樣:

https://mydomain.com/order?action=com.example.myapp.MY_ACTION&dropoff=San+Francisco

意圖網址

如果您使用意圖網址,那麼 urlTemplate 的值內便有套件名稱、意圖動作,以及一個稱為「下車地點」的額外意圖。這個額外意圖前方會加上「S.」,表示字串額外意圖 (按照 Intent.toUri() 的定義),左右以大括號包住,表示會用參數替代。前方需要額外加入半形分號,以便將意圖動作和額外意圖分開 (只有在設定參數之後才會納入)。

在我們提供的範例中,urlParameter 值設為 S.dropoff,您可以在 urlTemplate 裡找尋這個值,藉此瞭解這段內容出現在網址的什麼地方。

舉例來說,如果有使用者要求搭車前往「舊金山」並觸發動作,則最終觸發的 URI (替換參數之後) 會像這樣:

intent:#Intent;package=com.example.myapp;action=com.example.myapp.MY_ACTION;S.dropoff=San+Francisco;end

如果想進一步瞭解意圖,請見「Android 意圖」文件。

使用網址範本實體的網址值

如果有 <entity> 符合使用者查詢內容,則 identifier 屬性的值預設會傳遞給網址範本。如果您想改為參照 <entity>url 屬性,請在網址範本內使用 {@url},且不要使用 <parameter-mapping> 標記。請注意,這個 ID 的值是網址逸出,但是 url 屬性值並未改變。

如果有執行要求在網址範本內使用 {@url},則該執行要求會嘗試從網站和內嵌清查等來源衍生 {@url}。如果網站和內嵌清查都是可能衍生 {@url} 的來源,則以網站清查為主。

例如:

<fulfillment urlTemplate="{@url}">
    <!-- No parameter-mapping is needed -->
</fulfillment>
<entity-set entitySetId="...">
    <entity name="..." url="https://my.url.fulfillment/1"/>
    <entity name="..." url="https://my.url.fulfillment/2"/>
</entity-set>

{@url} 參數可和其他參數混合使用。例如:

<fulfillment urlTemplate="{@url}?referrer=actions_on_google{&amp;other_param}">
    <parameter-mapping intentParameter="otherParam.name" urlParameter="other_param"/>
</fulfillment>
<entity-set entitySetId="...">
    <entity name="..." url="https://my.url.fulfillment/1"/>
    <entity name="..." url="https://my.url.fulfillment/2"/>
</entity-set>

參數比對

Google 會根據以下的參數類型,將使用者語音內的參數和您指定的實體進行比對:

  • 列舉:Google 會將使用者查詢內容 (「星期一」) 和關聯的列舉網址 (「http://schema.org/Monday」) 進行比對,然後挑選 sameAs 值與列舉網址相符的實體。
  • 字串:Google 會挑選 namealternateName 值與使用者查詢內容相符的實體。

範例

以下章節將展示如何在 actions.xml 內使用內建意圖的範例。

財經 - 帳戶與付款

以下 actions.xml 範例使用 actions.intent.CREATE_MONEY_TRANSFER 內建意圖:

<?xml version="1.0" encoding="utf-8"?>
<actions>
    <action intentName="actions.intent.CREATE_MONEY_TRANSFER">
        <fulfillment urlTemplate="mybankapp://transfer{?amount,currency,recipientBankAccountType,senderBankAccountType,mode}">
            <parameter-mapping intentParameter="moneyTransfer.amount.value" urlParameter="amount" />
            <parameter-mapping intentParameter="moneyTransfer.amount.currency" urlParameter="currency" />
            <parameter-mapping intentParameter="moneyTransfer.moneyTransferDestination.name" urlParameter="recipientBankAccountType" />
            <parameter-mapping intentParameter="moneyTransfer.moneyTransferOrigin.name" urlParameter="senderBankAccountType" />
            <parameter-mapping intentParameter="moneyTransfer.transferMode" urlParameter="mode" />
        </fulfillment>
    </action>
</actions>

健身 - 營養

以下 actions.xml 範例使用 actions.intent.RECORD_FOOD_OBSERVATION 內建意圖:

<?xml version="1.0" encoding="utf-8"?>
<actions>
    <action intentName="actions.intent.RECORD_FOOD_OBSERVATION">
        <parameter name="foodObservation.forMeal">
            <entity-set-reference entitySetId="MealEntitySet"/>
        </parameter>
        <fulfillment urlTemplate="myfoodapp://record{?food,meal}">
            <parameter-mapping intentParameter="foodObservation.forMeal" urlParameter="meal" entityMatchRequired="true" />
            <parameter-mapping intentParameter="foodObservation.aboutFood.name" urlParameter="food" />
        </fulfillment>
    </action>
    <entity-set entitySetId="MealEntitySet">
        <entity sameAs="http://schema.googleapis.com/MealTypeBreakfast" identifier="1" />
        <entity sameAs="http://schema.googleapis.com/MealTypeLunch" identifier="2" />
        <entity sameAs="http://schema.googleapis.com/MealTypeDinner" identifier="3" />

    </entity-set>
</actions>

訂購餐點

以下 actions.xml 範例使用 actions.intent.ORDER_MENU_ITEM 內建意圖:

<?xml version="1.0" encoding="utf-8"?>
<actions>
    <action intentName="actions.intent.ORDER_MENU_ITEM">
        <parameter name="menuItem.inMenuSection.inMenu.forRestaurant.servesCuisine">
            <entity-set-reference entitySetId="CuisineEntitySet"/>
        </parameter>
        <fulfillment urlTemplate="myfoodapp://order{?restaurant}">
            <parameter-mapping intentParameter="menuItem.inMenuSection.inMenu.forRestaurant.name" urlParameter="restaurant" required="true" />
        </fulfillment>
        <!-- URL values are derived from a matched entity from the CuisineEntity Set. This is not a fallback fulfillment because {@url} is a required parameter. -->
        <fulfillment urlTemplate="{@url}" />
        <!-- Fallback fulfillment with no required parameters -->
        <fulfillment urlTemplate="myfoodapp://browse{?food}">
            <parameter-mapping intentParameter="menuItem.name" urlParameter="food" />
        </fulfillment>
    </action>
    <entity-set entitySetId="CuisineEntitySet">
        <entity url="myfoodapp://browse/italian/pizza" name="@string/pizza" alternateName="@array/pizzaSynonyms" />
        <entity url="myfoodapp://browse/american/hamburger" name="@string/hamburger" alternateName="@array/hamburgerSynonyms" />
        <entity url="myfoodapp://browse/mediterranean" name="@string/mediterranean" alternateName="@array/mediterraneanSynonyms" />
    </entity-set>
</actions>

交通

以下 actions.xml 檔案使用 actions.intent.CREATE_TAXI_RESERVATION 內建意圖:

<actions>
    <action intentName="actions.intent.CREATE_TAXI_RESERVATION">
        <fulfillment urlTemplate="https://taxi-actions.firebaseapp.com/order{?dropoffAddress}">
            <!-- Dropoff location as an address -->
            <parameter-mapping
                    intentParameter="taxiReservation.dropoffLocation.name"
                    urlParameter="dropoffAddress"/>
        </fulfillment>
    </action>
</actions>

其他

以下 actions.xml 範例使用 actions.intent.OPEN_APP_FEATURE 內建意圖。

<?xml version="1.0" encoding="utf-8"?>
<actions>
    <action intentName="actions.intent.OPEN_APP_FEATURE">
        <!-- Each parameter can reference an entity set using a custom ID. -->
        <parameter name="feature">
            <entity-set-reference entitySetId="FeatureEntitySet"/>
        </parameter>

        <fulfillment urlTemplate="myexampleapp://pathto{?appFeature}">
            <parameter-mapping intentParameter="feature" urlParameter="appFeature" />
        </fulfillment>
    </action>

    <entity-set entitySetId="FeatureEntitySet">
        <entity identifier="FEATUREONE" name="first feature" />
        <entity identifier="FEATURETWO" name="second feature" />
    </entity-set>
</actions>