Engage SDK Listen:第三方技術整合操作說明

Google 正在建構的裝置端途徑會依產業別將使用者的應用程式分門別類,並提供全新沉浸式體驗,可供使用者取用及瀏覽個人化應用程式內容。開發合作夥伴可以利用這個全螢幕體驗,在應用程式以外的專屬管道展示最精彩的多媒體內容。

本指南適用於需要整合音訊內容的開發合作夥伴,並提供透過 Engage SDK 填入此新途徑區域和現有 Google 途徑的操作說明。

整合詳情

術語

這項整合包含以下三個叢集類型:推薦接續精選

  • 推薦叢集會顯示個別開發合作夥伴針對閱讀內容提供的個人化建議。

    推薦內容採用以下結構:

    • 推薦叢集:此 UI 檢視畫面包含相同開發合作夥伴提供的一組推薦內容。

      圖 1. Entertainment Space UI 顯示單一合作夥伴提供的推薦叢集。
    • 實體:代表叢集中單一項目的物件。實體可以是播放清單、有聲書和 Podcast 等等。如需支援的實體類型清單,請參閱「提供實體資料」一節。

      圖 2. Entertainment Space UI 顯示單一合作夥伴推薦叢集內的單一實體。
  • 接續叢集會在單一 UI 群組中,顯示多個開發合作夥伴所提供使用者最近互動的音訊內容。每個開發合作夥伴最多可在接續叢集中播送 10 個實體。

    圖 3. Entertainment Space UI 顯示的接續叢集,內含多個合作夥伴提供的未讀完推薦內容 (目前只能看到一則推薦內容)。
  • 精選叢集會在一個 UI 群組中展示多個開發合作夥伴提供的精選項目。這個單一精選叢集會顯示在靠近 UI 頂端的位置,並且優先放置在所有推薦叢集的上方。每個開發合作夥伴最多可在精選叢集中播送 10 個實體。

    圖 4. Entertainment Space UI 顯示的精選叢集,內含多個合作夥伴提供的推薦內容 (目前只能看到一則推薦內容)。

事前作業

最低 API 級別:19

com.google.android.play:engage 程式庫新增至應用程式:

dependencies {
    // Make sure you also include that repository in your project's build.gradle file.
    implementation 'com.google.android.engage:engage-core:1.4.0'
}

摘要

這項設計是以繫結服務的實作為基礎。

用戶端可發布的資料受到不同叢集類型的限制,如下所示:

叢集類型 叢集限制 單一叢集中的實體數量上限
推薦叢集 最多 5 個 最多 50 個
接續叢集 最多 1 個 最多 10 個
精選叢集 最多 1 個 最多 10 個

步驟 1:提供實體資料

SDK 定義了不同實體,用來代表各種項目類型。Listen 類別支援下列實體:

  1. MusicAlbumEntity
  2. MusicArtistEntity
  3. MusicTrackEntity
  4. MusicVideoEntity
  5. PlaylistEntity
  6. PodcastSeriesEntity
  7. PodcastEpisodeEntity
  8. LiveRadioStationEntity
  9. AudiobookEntity

下方圖表列出各類型的可用屬性和必要性。

MusicAlbumEntity

MusicAlbumEntity 物件代表音樂專輯 (例如 Taylor Swift 的《Midnights》)。

屬性 必要性 附註
名稱 必要 音樂專輯的名稱。
代表圖片 必要 至少須提供一張圖片。如需相關指南,請參閱「圖片規格」一節。
資訊頁面 URI 必要

供應商應用程式的深層連結,可提供音樂專輯相關詳細資訊。

注意:您可以使用深層連結追蹤歸因。請參閱這篇常見問題文章

演出者 必要 音樂專輯中的藝人名單。
播放 URI 選用

供應商應用程式中的深層連結,可開始播放專輯。

注意:您可以使用深層連結追蹤歸因。請參閱這篇常見問題文章

說明 選用 如有提供,須限制在 200 個半形字元內。
歌曲數量 選用 音樂專輯中的歌曲數量。
類型 選用 音樂專輯中的類型清單。
專輯格式 選用

專輯 (含 LP 和雙 LP)

迷你專輯

單曲

混音專輯

唱片公司 選用 專輯相關唱片公司清單。
已下載到裝置上 選用 布林值,指出音樂專輯是否已下載到裝置上。
煽情露骨內容 選用

布林值,指出內容是否為煽情露骨內容

含有煽情露骨內容或家長指導警示的項目應設為 TRUE。煽情露骨項目會以「E」標記註明。

發行日期 選用 專輯發行日期 (以 Epoch 時間計算的毫秒為單位)。
時間長度 選用 專輯的時間長度 (以毫秒為單位)。
上次互動時間 選用

建議用於接續叢集中的項目。可能會用於排名。

以 Epoch 時間計算的毫秒為單位。

完成進度百分比 選用

建議用於接續叢集中的項目。

介於 0 和 100 之間的整數

MusicArtistEntity

MusicArtistEntity 物件代表音樂藝人 (例如 Adele)。

屬性 必要性 附註
名稱 必要 音樂藝人的名稱。
代表圖片 必要 至少須提供一張圖片。如需相關指南,請參閱「圖片規格」一節。
資訊頁面 URI 必要

供應商應用程式的深層連結,可提供音樂藝人相關詳細資訊。

注意:您可以使用深層連結追蹤歸因。請參閱這篇常見問題文章

播放 URI 選用

供應商應用程式中的深層連結,可開始播放藝人的歌曲。

注意:您可以使用深層連結追蹤歸因。請參閱這篇常見問題文章

說明 選用 如有提供,須限制在 200 個半形字元內。
上次互動時間 選用

建議用於接續叢集中的項目。可能會用於排名。

以 Epoch 時間計算的毫秒為單位。

MusicTrackEntity

MusicTrackEntity 物件代表音樂曲目 (例如 Coldplay 的〈Yellow〉)。

屬性 必要性 附註
名稱 必要 音樂曲目的名稱。
代表圖片 必要 至少須提供一張圖片。如需相關指南,請參閱「圖片規格」一節。
播放 URI 必要

供應商應用程式中的深層連結,可開始播放音樂曲目。

注意:您可以使用深層連結追蹤歸因。請參閱這篇常見問題文章

資訊頁面 URI 選用

供應商應用程式的深層連結,可提供音樂曲目相關詳細資訊。

注意:您可以使用深層連結追蹤歸因。請參閱這篇常見問題文章

說明 選用 如有提供,須限制在 200 個半形字元內。
時間長度 選用 曲目的時間長度 (以毫秒為單位)。
專輯 選用 這首歌曲所屬的專輯名稱。
藝人 必要 音樂曲目的演出者名單。
已下載到裝置上 選用 布林值,指出音樂曲目是否已下載到裝置上。
煽情露骨內容 選用

布林值,指出內容是否為煽情露骨內容

含有煽情露骨內容或家長指導警示的項目應設為 TRUE。煽情露骨項目會以「E」標記註明。

上次互動時間 選用

建議用於接續叢集中的項目。可能會用於排名。

以 Epoch 時間計算的毫秒為單位。

完成進度百分比 選用

建議用於接續叢集中的項目。

介於 0 和 100 之間的整數

MusicVideoEntity

MusicVideoEntity 物件代表音樂影片 (例如「The Weeknd - Take My Breath (官方音樂影片)」)。

屬性 必要性 附註
名稱 必要 音樂影片的名稱。
代表圖片 必要 至少須提供一張圖片。如需相關指南,請參閱「圖片規格」一節。
播放 URI 必要

供應商應用程式中的深層連結,可開始播放音樂影片。

注意:您可以使用深層連結追蹤歸因。請參閱這篇常見問題文章

資訊頁面 URI 選用

供應商應用程式的深層連結,可提供音樂影片相關詳細資訊。

注意:您可以使用深層連結追蹤歸因。請參閱這篇常見問題文章

時間長度 選用 影片的時間長度 (以毫秒為單位)。
觀看次數 選用 任意文字格式的影片觀看次數。
藝人 選用 音樂影片的演出者名單。
內容分級 選用 曲目的內容分級清單。
說明 選用 如有提供,須限制在 200 個半形字元內。
已下載到裝置上 選用 布林值,指出音樂影片是否已下載到裝置上。
煽情露骨內容 選用

布林值,指出內容是否為煽情露骨內容

含有煽情露骨內容或家長指導警示的項目應設為 TRUE。煽情露骨項目會以「E」標記註明。

上次互動時間 選用

建議用於接續叢集中的項目。可能會用於排名。

以 Epoch 時間計算的毫秒為單位。

完成進度百分比 選用

建議用於接續叢集中的項目。

介於 0 和 100 之間的整數

PlaylistEntity

PlaylistEntity 物件代表音樂播放清單 (例如,美國前 10 名熱播清單)。

屬性 必要性 附註
名稱 必要 播放清單的標題。
代表圖片 必要 至少須提供一張圖片。如需相關指南,請參閱「圖片規格」一節。
播放 URI 必要

供應商應用程式中的深層連結,可開始播放音樂播放清單。

注意:您可以使用深層連結追蹤歸因。請參閱這篇常見問題文章

資訊頁面 URI 選用

供應商應用程式的深層連結,可提供音樂播放清單相關詳細資訊。

注意:您可以使用深層連結追蹤歸因。請參閱這篇常見問題文章

時間長度 選用 播放清單的時間長度 (以毫秒為單位)。
歌曲數量 選用 音樂播放清單中的歌曲數量。
說明 選用 如有提供,須限制在 200 個半形字元內。
已下載到裝置上 選用 布林值,指出播放清單是否已下載到裝置上。
煽情露骨內容 選用

布林值,指出內容是否為煽情露骨內容

含有煽情露骨內容或家長指導警示的項目應設為 TRUE。煽情露骨項目會以「E」標記註明。

上次互動時間 選用

建議用於接續叢集中的項目。可能會用於排名。

以 Epoch 時間計算的毫秒為單位。

完成進度百分比 選用

建議用於接續叢集中的項目。

介於 0 和 100 之間的整數

PodcastSeriesEntity

PodcastSeriesEntity 物件代表 Podcast 系列 (例如「This American Life」)。

屬性 必要性 附註
名稱 必要 Podcast 系列的標題。
代表圖片 必要 至少須提供一張圖片。如需相關指南,請參閱「圖片規格」一節。
資訊頁面 URI 必要

供應商應用程式的深層連結,可提供 Podcast 系列相關詳細資訊。

注意:您可以使用深層連結追蹤歸因。請參閱這篇常見問題文章

播放 URI 選用

供應商應用程式中的深層連結,可開始播放 Podcast 系列。

注意:您可以使用深層連結追蹤歸因。請參閱這篇常見問題文章

集數 選用 Podcast 系列的集數。
製作者名稱 選用 Podcast 系列的製作者名稱。
主持人 選用 Podcast 系列的主持人名單。
類型 選用 Podcast 系列類型清單。
已下載到裝置上 選用 布林值,指出該 Podcast 是否已下載到裝置上。
說明 選用 如有提供,須限制在 200 個半形字元內。
煽情露骨內容 選用

布林值,指出內容是否為煽情露骨內容

含有煽情露骨內容或家長指導警示的項目應設為 TRUE。煽情露骨項目會以「E」標記註明。

上次互動時間 選用

建議用於接續叢集中的項目。可能會用於排名。

以 Epoch 時間計算的毫秒為單位。

PodcastEpisodeEntity

PodcastEpisodeEntity 物件代表 Podcast 單集節目 (例如 Spark Bird, Episode 754: This American Life)。

屬性 必要性 附註
名稱 必要 Podcast 單集節目的標題。
代表圖片 必要 至少須提供一張圖片。如需相關指南,請參閱「圖片規格」一節。
播放 URI 必要

供應商應用程式中的深層連結,可開始播放 Podcast 單集節目。

注意:您可以使用深層連結追蹤歸因。請參閱這篇常見問題文章

製作系列標題 必要 該集節目所屬的 Podcast 系列名稱。
時間長度 必要 Podcast 單集節目的時間長度 (以毫秒為單位)。
發布日期 必要 Podcast 的發布日期 (以 Epoch 時間計算的毫秒為單位)
資訊頁面 URI 選用

供應商應用程式的深層連結,可提供 Podcast 單集節目相關詳細資訊。

注意:您可以使用深層連結追蹤歸因。請參閱這篇常見問題文章

製作者名稱 選用 Podcast 系列的製作者名稱。
單集節目索引 選用 系列中的單集節目索引 (第一個索引為 1)。
主持人 選用 Podcast 單集節目的主持人名單。
類型 選用 Podcast 單集節目類型清單。
已下載到裝置上 選用 布林值,指出該 Podcast 單集節目是否已下載到裝置上。
說明 選用 如有提供,須限制在 200 個半形字元內。
視訊網播節目 選用 布林值,指出該 Podcast 單集節目是否包含影片內容
煽情露骨內容 選用

布林值,指出內容是否為煽情露骨內容

含有煽情露骨內容或家長指導警示的項目應設為 TRUE。煽情露骨項目會以「E」標記註明。

下一個收聽內容的類型 選用

建議用於接續叢集中的項目

TYPE_CONTINUE - 繼續播放未結束的音訊。

TYPE_NEXT - 繼續收聽系列新作。

TYPE_NEW - 新發行。

上次互動時間 選用

建議用於接續叢集中的項目。可能會用於排名。

以 Epoch 時間計算的毫秒為單位。

完成進度百分比 選用

建議用於接續叢集中的項目。

介於 0 和 100 之間的整數

LiveRadioStationEntity

LiveRadioStationEntity 物件代表直播廣播電台 (例如 98.1 The Breeze)。

屬性 必要性 附註
名稱 必要 直播廣播電台的名稱。
代表圖片 必要 至少須提供一張圖片。如需相關指南,請參閱「圖片規格」一節。
播放 URI 必要

供應商應用程式中的深層連結,可開始播放廣播節目。

注意:您可以使用深層連結追蹤歸因。請參閱這篇常見問題文章

資訊頁面 URI 選用

供應商應用程式的深層連結,可提供廣播電台相關詳細資訊。

注意:您可以使用深層連結追蹤歸因。請參閱這篇常見問題文章

頻率 選用 廣播電台的廣播頻率 (例如「98.1 FM」)。
節目名稱 選用 廣播電台目前播放的節目。
主持人 選用 廣播電台的主持人名單。
說明 選用 如有提供,須限制在 200 個半形字元內。
上次互動時間 選用

建議用於接續叢集中的項目。可能會用於排名。

以 Epoch 時間計算的毫秒為單位。

AudiobookEntity

AudiobookEntity 物件代表有聲書 (例如 Michelle Obama 的《Becoming》有聲書)。

屬性 必要性 附註
名稱 必要
代表圖片 必要 至少須提供一張圖片。如需相關指南,請參閱「圖片規格」一節。
作者 必要 至少須提供一個作者名稱。
講述者 必要 至少須提供一個講述者名稱。
動作連結 URI 必要

有聲書的供應商應用程式深層連結。

注意:您可以使用深層連結追蹤歸因。請參閱這篇常見問題文章

發布日期 選用 以 Epoch 時間計算的毫秒為單位 (如有提供)。
說明 選用 如有提供,須限制在 200 個半形字元內。
價格 選用 任意文字
時間長度 選用 如有提供,必須是正值。
類型 選用 書籍相關類型清單。
系列叢書名稱 選用 有聲書所屬系列叢書的名稱 (例如《哈利波特》)。
系列叢書單書索引 選用 系列叢書中的有聲書索引,其中 1 是系列中第一本有聲書。舉例來說,如果《哈利波特 ③ 阿茲卡班的逃犯》是該系列叢書的第三本書,這項屬性應設為 3。
繼續閱讀書籍類型 選用

TYPE_CONTINUE - 繼續閱讀未讀完的書籍。

TYPE_NEXT - 繼續閱讀系列叢書中的新作。

TYPE_NEW - 新發行。

上次互動時間 在特定情況下為必要

當項目屬於接續叢集時必須提供。

以 Epoch 時間計算的毫秒為單位。

完成進度百分比 在特定情況下為必要

當項目屬於接續叢集時必須提供。

*新*購有聲書可以屬於接續收聽叢集。

值必須介於 0 至 100 之間。

DisplayTimeWindow - 設定內容在途徑上顯示的時間長度
開始時間戳記 選用

Epoch 時間戳記,內容應會在此時間過後顯示在途徑上。

如未設定,表示內容一律會顯示在途徑上。

以 Epoch 時間計算的毫秒為單位。

結束時間戳記 選用

Epoch 時間戳記,內容在此時間後將不會顯示在途徑上。

如未設定,表示內容一律會顯示在途徑上。

以 Epoch 時間計算的毫秒為單位。

圖片規格

圖片素材資源的規格規定如下:

顯示比例 必要性 最低像素 建議的像素
正方形 (1x1) 必要 300x300 1200x1200
橫向 (1.91x1) 選用 600x314 1200x628
直向 (4x5) 選用 480x600 960x1200

檔案格式

PNG、JPG、靜態 GIF、WebP

檔案大小上限

5120 KB

其他建議

  • 圖片安全區域:將重要內容放在圖片中央 80% 的範圍內。

範例

MusicAlbumEntity musicAlbumEntity =
        new MusicAlbumEntity.Builder()
            .setName(NAME)
             .addPosterImage(new Image.Builder()
                  .setImageUri(Uri.parse("http://www.x.com/image.png"))
                  .setImageHeightInPixel(960)
                  .setImageWidthInPixel(408)
                  .build())
            .setPlayBackUri("https://play.google/album/play")
            .setInfoPageUri("https://play.google/album/info")
            .setDescription("A description of this album.")
            .addArtist("Artist")
            .addGenre("Genre")
            .addMusicLabel("Label")
            .addContentRating("Rating")
            .setSongsCount(960)
            .setReleaseDateEpochMillis(1633032895L)
            .setDurationMillis(1633L)
            .build();
AudiobookEntity audiobookEntity =
        new AudiobookEntity.Builder()
            .setName("Becoming")
            .addPosterImage(new Image.Builder()
                 .setImageUri(Uri.parse("http://www.x.com/image.png"))
                 .setImageHeightInPixel(960)
                 .setImageWidthInPixel(408)
                  .build())
            .addAuthor("Michelle Obama")
            .addNarrator("Michelle Obama")
            .setActionLinkUri(
               Uri.parse("https://play.google/audiobooks/1"))
            .setDurationMillis(16335L)
            .setPublishDateEpochMillis(1633032895L)
            .setDescription("An intimate, powerful, and inspiring memoir")
            .setPrice("$16.95")
            .addGenre("biography")
            .build();

步驟 2:提供叢集資料

建議您在背景執行內容發布工作 (例如使用 WorkManager),並安排定期執行或根據事件排程 (例如使用者每次開啟應用程式,或剛將商品加入購物車時)。

AppEngagePublishClient 負責發布叢集。以下 API 可在用戶端中使用:

  • isServiceAvailable
  • publishRecommendationClusters
  • publishFeaturedCluster
  • publishContinuationCluster
  • publishUserAccountManagementRequest
  • updatePublishStatus
  • deleteRecommendationsClusters
  • deleteFeaturedCluster
  • deleteContinuationCluster
  • deleteUserManagementCluster
  • deleteClusters

isServiceAvailable

這個 API 可用於檢查服務是否可供整合,以及內容是否能在裝置上顯示。

Kotlin


client.isServiceAvailable.addOnCompleteListener { task ->
    if (task.isSuccessful) {
        // Handle IPC call success
        if(task.result) {
          // Service is available on the device, proceed with content
          // publish calls.
        } else {
          // Service is not available, no further action is needed.
        }
    } else {
      // The IPC call itself fails, proceed with error handling logic here,
      // such as retry.
    }
}

Java


client.isServiceAvailable().addOnCompleteListener(task - > {
    if (task.isSuccessful()) {
        // Handle success
        if(task.getResult()) {
          // Service is available on the device, proceed with content publish
          // calls.
        } else {
          // Service is not available, no further action is needed.
        }
    } else {
      // The IPC call itself fails, proceed with error handling logic here,
      // such as retry.
    }
});

publishRecommendationClusters

這個 API 可用於發布 RecommendationCluster 物件清單。

Kotlin


client.publishRecommendationClusters(
            PublishRecommendationClustersRequest.Builder()
                .addRecommendationCluster(
                    RecommendationCluster.Builder()
                        .addEntity(entity1)
                        .addEntity(entity2)
                        .setTitle("Trending music")
                        .build())
                .build())

Java


client.publishRecommendationClusters(
            new PublishRecommendationClustersRequest.Builder()
                .addRecommendationCluster(
                    new RecommendationCluster.Builder()
                        .addEntity(entity1)
                        .addEntity(entity2)
                        .setTitle("Trending music")
                        .build())
                .build());

服務收到要求後,系統會在單一交易中執行以下動作:

  • 移除開發合作夥伴提供的現有 RecommendationCluster 資料。
  • 剖析要求所提供的資料並儲存在更新後的推薦叢集中。

如果發生錯誤,整個要求都會遭到拒絕,現有狀態則維持不變。

publishFeaturedCluster

這個 API 可用於發布 FeaturedCluster 物件清單。

Kotlin


client.publishFeaturedCluster(
            PublishFeaturedClusterRequest.Builder()
                .setFeaturedCluster(
                    FeaturedCluster.Builder()
                        ...
                        .build())
                .build())

Java


client.publishFeaturedCluster(
            new PublishFeaturedClusterRequest.Builder()
                .setFeaturedCluster(
                    new FeaturedCluster.Builder()
                        ...
                        .build())
                .build());

服務收到要求後,系統會在單一交易中執行以下動作:

  • 移除開發合作夥伴提供的現有 FeaturedCluster 資料。
  • 剖析要求所提供的資料並儲存在更新後的精選叢集中。

如果發生錯誤,整個要求都會遭到拒絕,現有狀態則維持不變。

publishContinuationCluster

這個 API 可用來發布 ContinuationCluster 物件。

Kotlin


client.publishContinuationCluster(
            PublishContinuationClusterRequest.Builder()
                .setContinuationCluster(
                    ContinuationCluster.Builder()
                        .addEntity(entity1)
                        .addEntity(entity2)
                        .build())
                .build())

Java


client.publishContinuationCluster(
            PublishContinuationClusterRequest.Builder()
                .setContinuationCluster(
                    ContinuationCluster.Builder()
                        .addEntity(entity1)
                        .addEntity(entity2)
                        .build())
                .build())

服務收到要求後,系統會在單一交易中執行以下動作:

  • 移除開發合作夥伴提供的現有 ContinuationCluster 資料。
  • 剖析要求所提供的資料並儲存在更新後的接續叢集中。

如果發生錯誤,整個要求都會遭到拒絕,現有狀態則維持不變。

publishUserAccountManagementRequest

這個 API 是用來發布「登入」資訊卡。登入動作會將使用者導向應用程式的登入頁面,方便應用程式發布內容 (或提供更個人化的內容)

登入資訊卡包含下列中繼資料:

屬性 必要性 說明
動作 URI 必要 導向動作的深層連結,也就是前往應用程式登入頁面
圖片 選用 - 如未提供,則必須提供標題

資訊卡上顯示的圖片

解析度 1264x712、顯示比例 16x9 的圖片

標題 選用 - 如未提供,則必須提供圖片 資訊卡上的標題
動作文字 選用 行動號召中顯示的文字,也就是「登入」
副標題 選用 資訊卡上的選用副標題

Kotlin


var SIGN_IN_CARD_ENTITY =
      SignInCardEntity.Builder()
          .addPosterImage(
              Image.Builder()
                  .setImageUri(Uri.parse("http://www.x.com/image.png"))
                  .setImageHeightInPixel(500)
                  .setImageWidthInPixel(500)
                  .build())
          .setActionText("Sign In")
          .setActionUri(Uri.parse("http://xx.com/signin"))
          .build()

client.publishUserAccountManagementRequest(
            PublishUserAccountManagementRequest.Builder()
                .setSignInCardEntity(SIGN_IN_CARD_ENTITY)
                .build());

Java


SignInCardEntity SIGN_IN_CARD_ENTITY =
      new SignInCardEntity.Builder()
          .addPosterImage(
              new Image.Builder()
                  .setImageUri(Uri.parse("http://www.x.com/image.png"))
                  .setImageHeightInPixel(500)
                  .setImageWidthInPixel(500)
                  .build())
          .setActionText("Sign In")
          .setActionUri(Uri.parse("http://xx.com/signin"))
          .build();

client.publishUserAccountManagementRequest(
            new PublishUserAccountManagementRequest.Builder()
                .setSignInCardEntity(SIGN_IN_CARD_ENTITY)
                .build());

服務收到要求後,系統會在單一交易中執行以下動作:

  • 移除開發合作夥伴提供的現有 UserAccountManagementCluster 資料。
  • 剖析要求所提供的資料並儲存在更新後的 UserAccountManagementCluster 叢集中。

如果發生錯誤,整個要求都會遭到拒絕,現有狀態則維持不變。

updatePublishStatus

如因內部業務原因,導致無法發布任何叢集,我們強烈建議使用 updatePublishStatus API 更新發布狀態。這麼做很重要,因為:

  • 在所有情況下,提供狀態都至關重要,即使內容已發布 (STATUS == PUBLISHED) 也一樣。如此一來,才能為資訊主頁填入資料,並以明確的狀態表示整合項目的健康度和其他指標。
  • 如未發布內容,但整合狀態未遭中斷 (STATUS == NOT_PUBLISHED),Google 便可避免在應用程式健康資訊主頁中觸發快訊。這可從提供者的角度確認內容是因預期的情況而未發布。
  • 這有助開發人員深入瞭解資料何時已發布或未發布。
  • Google 可能會使用狀態碼,提醒使用者在應用程式中執行特定動作,以便查看或解決應用程式內容。

以下為符合資格的發布狀態碼清單:

// Content is published
AppEngagePublishStatusCode.PUBLISHED,

// Content is not published as user is not signed in
AppEngagePublishStatusCode.NOT_PUBLISHED_REQUIRES_SIGN_IN,

// Content is not published as user is not subscribed
AppEngagePublishStatusCode.NOT_PUBLISHED_REQUIRES_SUBSCRIPTION,

// Content is not published as user location is ineligible
AppEngagePublishStatusCode.NOT_PUBLISHED_INELIGIBLE_LOCATION,

// Content is not published as there is no eligible content
AppEngagePublishStatusCode.NOT_PUBLISHED_NO_ELIGIBLE_CONTENT,

// Content is not published as the feature is disabled by the client
// Available in v1.3.1
AppEngagePublishStatusCode.NOT_PUBLISHED_FEATURE_DISABLED_BY_CLIENT,

// Content is not published as the feature due to a client error
// Available in v1.3.1
AppEngagePublishStatusCode.NOT_PUBLISHED_CLIENT_ERROR,

// Content is not published as the feature due to a service error
// Available in v1.3.1
AppEngagePublishStatusCode.NOT_PUBLISHED_SERVICE_ERROR,

// Content is not published due to some other reason
// Reach out to engage-developers@ before using this enum.
AppEngagePublishStatusCode.NOT_PUBLISHED_OTHER

如果內容因使用者未登入而未發布,建議您發布登入資訊卡。如因任何原因導致提供者無法發布登入資訊卡,建議您呼叫 updatePublishStatus API,並使用狀態碼 NOT_PUBLISHED_REQUIRES_SIGN_IN

Kotlin


client.updatePublishStatus(
   PublishStatusRequest.Builder()
     .setStatusCode(AppEngagePublishStatusCode.NOT_PUBLISHED_REQUIRES_SIGN_IN)
     .build())

Java


client.updatePublishStatus(
    new PublishStatusRequest.Builder()
        .setStatusCode(AppEngagePublishStatusCode.NOT_PUBLISHED_REQUIRES_SIGN_IN)
        .build());

deleteRecommendationClusters

這個 API 可用來刪除推薦叢集的內容。

Kotlin


client.deleteRecommendationClusters()

Java


client.deleteRecommendationClusters();

服務收到要求後,會從推薦叢集中移除現有資料。如果發生錯誤,整個要求都會遭到拒絕,現有狀態則維持不變。

deleteFeaturedCluster

這個 API 可用來刪除精選叢集的內容。

Kotlin


client.deleteFeaturedCluster()

Java


client.deleteFeaturedCluster();

服務收到要求後,會從精選叢集中移除現有資料。如果發生錯誤,整個要求都會遭到拒絕,現有狀態則維持不變。

deleteContinuationCluster

這個 API 可用來刪除接續叢集的內容。

Kotlin


client.deleteContinuationCluster()

Java


client.deleteContinuationCluster();

服務收到要求後,會從接續叢集中移除現有資料。如果發生錯誤,整個要求都會遭到拒絕,現有狀態則維持不變。

deleteUserManagementCluster

這個 API 可用來刪除 UserAccountManagement 叢集的內容。

Kotlin


client.deleteUserManagementCluster()

Java


client.deleteUserManagementCluster();

服務收到要求後,會從 UserAccountManagement 叢集中移除現有資料。如果發生錯誤,整個要求都會遭到拒絕,現有狀態則維持不變。

deleteClusters

這個 API 可用於刪除指定叢集類型的內容。

Kotlin


client.deleteClusters(
    DeleteClustersRequest.Builder()
      .addClusterType(ClusterType.TYPE_FEATURED)
      .addClusterType(ClusterType.TYPE_RECOMMENDATION)
      ...
      .build())

Java


client.deleteClusters(
            new DeleteClustersRequest.Builder()
                .addClusterType(ClusterType.TYPE_FEATURED)
                .addClusterType(ClusterType.TYPE_RECOMMENDATION)
                ...
                .build());

服務收到要求後,會從符合指定叢集類型的所有叢集中移除現有資料。用戶端可以選擇傳遞一或多個叢集類型。如果發生錯誤,整個要求都會遭到拒絕,現有狀態則維持不變。

處理錯誤

強烈建議您監聽來自發布 API 的工作結果,據以採取後續動作來復原及重新提交能順利執行的工作。

client.publishRecommendationClusters(
              new PublishRecommendationClustersRequest.Builder()
                  .addRecommendationCluster(...)
                  .build())
          .addOnCompleteListener(
              task -> {
                if (task.isSuccessful()) {
                  // do something
                } else {
                  Exception exception = task.getException();
                  if (exception instanceof AppEngageException) {
                    @AppEngageErrorCode
                    int errorCode = ((AppEngageException) exception).getErrorCode();
                    if (errorCode == AppEngageErrorCode.SERVICE_NOT_FOUND) {
                      // do something
                    }
                  }
                }
              });

發生錯誤時會傳回 AppEngageException,並提供原因的錯誤代碼。

錯誤代碼 附註
SERVICE_NOT_FOUND 這項服務不適用於指定裝置。
SERVICE_NOT_AVAILABLE 這項服務適用於指定裝置,但無法於呼叫期間使用 (例如服務已明確停用)。
SERVICE_CALL_EXECUTION_FAILURE 執行緒發生問題,因此工作執行失敗。在這種情況下,您可以重試。
SERVICE_CALL_PERMISSION_DENIED 呼叫端未獲准發出服務呼叫。
SERVICE_CALL_INVALID_ARGUMENT 要求包含無效的資料 (例如,超過允許的叢集數量上限)。
SERVICE_CALL_INTERNAL 服務端發生錯誤。
SERVICE_CALL_RESOURCE_EXHAUSTED 服務呼叫過於頻繁。

步驟 3:處理廣播意圖

除了透過工作發出發布內容 API 呼叫,您還需要設定 BroadcastReceiver 來接收內容發布要求。

廣播意圖的目標主要用於應用程式重新啟動及強制同步處理資料。廣播意圖的傳送頻率通常不高。觸發廣播意圖的唯一時機,就是 Engage Service 判定內容可能過時 (例如已滿一週)。這樣一來,即使應用程式已有長時間未執行,使用者也能獲得最新的內容體驗。

BroadcastReceiver 必須透過下列兩種方式進行設定:

  • 使用 Context.registerReceiver() 以動態方式註冊 BroadcastReceiver 類別的例項。這樣就能接收仍在記憶體中的應用程式訊息。
class AppEngageBroadcastReceiver extends BroadcastReceiver {
// Trigger recommendation cluster publish when PUBLISH_RECOMMENDATION broadcast
// is received

// Trigger featured cluster publish when PUBLISH_FEATURED broadcast is received

// Trigger continuation cluster publish when PUBLISH_CONTINUATION broadcast is
// received
}

public static void registerBroadcastReceivers(Context context) {

context = context.getApplicationContext();

// Register Recommendation Cluster Publish Intent
context.registerReceiver(new AppEngageBroadcastReceiver(),
new IntentFilter(com.google.android.engage.service.Intents.ACTION_PUBLISH_RECOMMENDATION));

// Register Featured Cluster Publish Intent
context.registerReceiver(new AppEngageBroadcastReceiver(),
new IntentFilter(com.google.android.engage.service.Intents.ACTION_PUBLISH_FEATURED));


// Register Continuation Cluster Publish Intent
context.registerReceiver(new AppEngageBroadcastReceiver(),
new IntentFilter(com.google.android.engage.service.Intents.ACTION_PUBLISH_CONTINUATION));

}
  • AndroidManifest.xml 檔案中使用 <receiver> 標記,以靜態方式宣告實作項目。這可讓未執行的應用程式接收廣播意圖,也能讓應用程式發布內容。
<application>
   <receiver
      android:name=".AppEngageBroadcastReceiver"
      android:exported="true"
      android:enabled="true">
      <intent-filter>
         <action android:name="com.google.android.engage.action.PUBLISH_RECOMMENDATION" />
      </intent-filter>
      <intent-filter>
         <action android:name="com.google.android.engage.action.PUBLISH_FEATURED" />
      </intent-filter>
      <intent-filter>
         <action android:name="com.google.android.engage.action.PUBLISH_CONTINUATION" />
      </intent-filter>
   </receiver>
</application>

服務會傳送下列意圖

  • com.google.android.engage.action.PUBLISH_RECOMMENDATION 建議在收到此意圖時啟動 publishRecommendationClusters 呼叫。
  • com.google.android.engage.action.PUBLISH_FEATURED 建議在收到此意圖時啟動 publishFeaturedCluster 呼叫。
  • com.google.android.engage.action.PUBLISH_CONTINUATION 建議在收到此意圖時啟動 publishContinuationCluster 呼叫。

整合工作流程

如需整合完成後驗證作業的逐步指南,請參閱「Engage 開發人員整合工作流程」一文。

常見問題

請參閱「Engage SDK 常見問題」。

聯絡資訊

如果在整合過程中有任何問題,請來信至 engage-developers@google.com 與我們聯絡。我們的團隊會盡快回覆。

後續步驟

完成這項整合後,後續步驟如下:

  • 傳送電子郵件至 engage-developers@google.com,並附上整合完成可供 Google 測試的 APK。
  • Google 會在內部執行驗證及審查,確認整合能夠正常運作。如果需要進行變更,Google 會與您聯絡並提供所有必要詳細資料。
  • 測試完成後,如果不需要進行任何變更,Google 會與您聯絡,通知您可以開始將完成整合的更新版 APK 發布至 Play 商店。
  • Google 確認您已將更新版 APK 發布至 Play 商店後,就會發布您的推薦精選接續叢集供使用者瀏覽。