找出要實作的應用程式內功能和內建意圖 (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> |
|
<parameter> |
<action> |
name |
<entity-set-reference> |
<parameter> |
|
<fulfillment> |
<action> |
|
<parameter-mapping> |
<fulfillment> |
|
<entity-set> |
<actions> |
entitySetId |
<entity> |
<entity-set> |
|
標記說明
本章節會說明 actions.xml
的各種結構定義標記。
<action>
該應用程式支援的應用程式動作。您必須為 actions.xml
檔案中所有 <action>
標記提供至少一項 <fulfillment>
。
屬性:
intentName
:該應用程式動作的內建意圖 (例如actions.intent.CREATE_TAXI_RESERVATION
)。支援的內建意圖清單請見內建意圖參考資料。queryPatterns
:您預期使用者會對此意圖執行的一組查詢。此屬性僅適用於自訂意圖,因為 BII 內已包含數個常見方式模型,使用者表示會根據這些方式嘗試執行任務或尋找資訊。
<parameter>
擁有名稱及關聯實體清單的應用程式動作的參數。
屬性:
name
:和此參數關聯的名稱 (例如「目的地」)。此名稱是參數的分葉層級欄位 (例如tradeOrder.assetOrdered.assetIssuedBy.name
)。如果參數是基本類型 (例如字串),則名稱會直接使用參數的名稱。
<entity-set-reference>
開發人員提供的 schema.org 動態饋給參考資料。動態饋給必須在 actions.xml
檔案裡直接使用 <entity-set>
標記提供。
屬性:
entitySetId
:特定實體系列的參考資料。這個屬性必須對應<entity-set>
內的entitySetId
。urlFilter
:提供網站清查給執行要求時使用的網址路徑。本屬性支援兩種萬用字元:*
:一個星號,符合緊接前方且零個以上的字元序列。.*
:半形句號後面加上星號,符合零個以上字元的任何序列。僅有常值的
*
和\
才需要逸出字元,各自可以逸出為\\*
和\\\\
。
<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{?someValue,anotherValue} |
"someValue": "123"
|
https://example.com/test?someValue=123&anotherValue=456 |
https://example.com/test?utm_campaign=appactions{&someValue,anotherValue} |
"someValue": "123"
|
https://example.com/test?utm_campaign=appactions&someValue=123&anotherValue=456 |
https://example.com/test?utm_campaign=appactions{#someValue} |
"someValue": "123" |
https://example.com/test?utm_campaign=appactions#someValue=123 |
myapp://example/{someValue} |
"someValue": "123" |
myapp://example/123 |
intent://example#Intent;scheme=my-scheme{;S.extra1,S.extra2};end |
"S.extra1": "123"
|
intent://example#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>
裡必須有參數lat
和long
的鍵。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
內的內嵌實體集。
屬性:
entitySetId
:actions.xml
內的<entity-set>
的必要專用 ID (例如"myInlineEntitySet1"
)。這個值也必須對應<entity-set-reference>
標記內的<entitySetId>
值。entitySetId
的值必須有至少 30 個英數字元 (不可使用-
或_
等特殊字元),並須以英文字母開頭。
<entity>
actions.xml
內嵌實體集內的元素。包括 schema.org/Thing
欄位的子集。
url
、identifier
和 sameAs
欄位的字串值可採用硬式編碼,或透過 APK 的字串資源進行參照。提供同義詞時,請為參照 APK 字串陣列資源的 alternateName
欄位使用字串值。
屬性:
name
:實體必要名稱,除非您要指定sameAs
欄位。必須是專用值,不得和指定<entity-set>
(例如「牙膏」) 的實體name
及alternateName
欄位相同。alternateName
:(非必要) 該實體的替代名稱。您必須先指定name
欄位,然後才能指定alternateName
欄位。對於指定的<entity-set>
來說,實體name
和alternateName
欄位的值不得相同。當使用者查詢內容符合此處任一字串,便會選取此實體。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
)。
必須提供 identifier
或 url
兩者之一。指定實體集裡的所有實體都必須使用相同的屬性 (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
:
在您要使用網站目錄的
<action>
標記內,新增<fulfillment>
標記,並將其urlTemplate
屬性設為{@url}
。在同一個
<action>
標記中新增<parameter>
標記,並將其name
屬性設為與網頁描述的實體最相符的內建意圖參數。舉例來說,為ORDER_MENU_ITEM
提供網站目錄時,您可以將選單頁面連結到menuItem.name
,並將餐廳位置頁面連結到menuItem.inMenuSection.inMenu.forRestaurant.name
。在新的
<parameter>
標記中新增<entity-set-reference>
標記,並將其urlFilter
屬性設為您希望網站目錄使用的網址路徑。
執行以上步驟後,Google 助理即可使用您在 urlFilter
屬性提供的網址路徑進行網頁搜尋,然後使用結果將 {@url}
值提供給您的執行要求。接著,您的深層連結處理常式即可根據 Google 助理回傳的深層連結轉送使用者,以便處理該執行要求。
舉例來說,您的網站內有路徑開頭為 https://www.example.com/items/
的產品清單。您使用的是 urlFilter
值 https://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
內必須有該預留位置值,左右須用大括號 ({}
) 包住。
應用程式連結網址
如果您使用應用程式連結網址,urlTemplate
會指向可觸發 Activity
的標準 HTTP 網址。參數會以網址參數的形式傳遞到應用程式連結網址內。urlTemplate
內的參數前後必須用大括號 ({}
) 包住,並在前端加上半形問號 (?
)。如未設定參數,則結果會省略參數 (包括大括號)。
舉例來說,如果使用者要求搭乘預定的計程車前往舊金山,並觸發了應用程式動作,那麼最終觸發的 URI (替換參數之後) 會像這樣:
https://mydomain.com/order?action=com.example.myapp.MY_ACTION&dropoff=San+Francisco
意圖網址
如果您使用意圖網址,那麼 urlTemplate
值便會包含套件名稱、意圖動作,以及一個稱為「下車地點」的額外意圖。這個額外意圖前方會加上「S.」來表示 String
額外意圖 (按照 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{&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 會挑選
name
或alternateName
值與使用者查詢內容相符的實體。
範例
本節將舉例說明如何在 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>