DFX 作業負責人
隨著 Android 生態系統擴展到手錶、客廳、車輛和 XR,開發人員有更多機會透過新螢幕觸及使用者。不過,在 Wear OS、Android TV、Android Auto、Android Automotive OS 或 Android XR 上發布應用程式時,測試、商店資訊和應用程式審查等方面的考量會有所不同。
本課程將探討如何有效運用 Google Play 管理中心,針對非行動裝置板型規格,簡化可預測的支援多種裝置推出流程。我們將說明重要的發布決策,包括如何規劃測試群組策略和套件名稱、設定指定測試群組,以及量身打造商店資訊。您將實際瞭解各種板型規格的應用程式品質指南,避免常見的審查問題,並更有信心地在 Google Play 發布應用程式。
轉錄稿
大家好,歡迎各位的加入。
感謝各位參加這場講座,瞭解如何提升支援多種裝置的應用程式品質,以及在 Google Play 發布非行動裝置適用的應用程式。
我是 Jan Kleinert,車輛專用 Android 團隊的開發人員關係工程師。
我是 Faustine Liao,Play 信任與安全團隊的作業負責人。
很高興今天能與各位齊聚一堂。
因此,多年來,當我們提到 Android 開發時,大多數人其實只會想到行動裝置,但 Android 生態系統已擴展到智慧型手機以外的領域。
因此,使用者現在可以在客廳透過 Android TV 與應用程式互動,也可以在共乘或充電時透過 Android Auto 或 Automotive OS 使用應用程式,或是在手腕上透過 Wear OS 使用應用程式,甚至可以透過 Android XR 在沉浸式 3D 空間中使用應用程式。
這對成長來說是絕佳機會,但擴展到這些板型規格,代表發布策略需要考量一些邊際因素。
從建構應用程式到在 Google Play 發布並上架,整體流程與您熟悉的行動裝置版本發布流程大致相同。
建構及準備應用程式,然後在 Play 管理中心建立商店資訊、測試應用程式、上傳及提交正式版,最後等待審查和核准。
不過,在發布非行動裝置板型規格的應用程式時,有一些獨特的考量。
今天,我們將提供明確的架構,協助您做好準備,讓支援多種裝置的發布程序更順暢、更可預測。
首先,我們來談談基礎:如何架構及封裝應用程式。
因此,在您使用 Google Play 管理中心之前,必須先做出重要的架構決策。
您會建構單一、統一的應用程式套件,其中包含支援的所有板型規格,還是將應用程式拆分為特定板型規格的模組,並為每個模組產生 Android App Bundle (AAB)?
因此,當我說模組或模組化時,指的是一種建構程式碼集的方式,能提升可維護性。
模組化的方法有很多,但一般來說,您需要將程式碼集整理成鬆耦合和獨立的部分,其中每個部分都是一個模組。
因此,雖然統一的 Android App Bundle 做法可能更容易管理,但我們實際上建議採用模組化做法。
以下舉例說明我們為何建議採用這種模組化方法。
假設您有一個同時支援行動裝置和 Android TV 的應用程式。
如果您在標準行動裝置發布群組中提交單一 Android 應用程式套件,而 Android TV 應用程式未通過審查,整個版本就會停止發布。
因此,Android TV 應用程式和行動應用程式的發布都會受到影響。
因此,即使您的行動應用程式本身沒有問題,您仍須解決導致 Android TV 審查失敗的問題,並重新提交應用程式送審,才能向使用者發布版本。
另一方面,為每個板型規格建立模組化 Android App Bundle,可讓您更精細地控管,並將這些板型規格版本與行動裝置版本區隔開來。
因此,如果您有行動應用程式和 TV 應用程式的個別應用程式模組,可以為每個模組產生個別的 Android 應用程式套件。
如果電視應用程式的審查結果有問題,只有該應用程式的版本會遭到封鎖,直到您解決問題為止。
行動應用程式版本會照常發布。
如前所述,模組化有許多方法。
以下舉例說明如何將有聲書應用程式模組化,提供行動裝置和 Android Automotive OS 體驗。
在頂端綠色部分,我們為每個板型規格提供一個應用程式模組,這有助於區隔平台專用的依附元件。
黃色部分是功能模組,對應應用程式功能的獨立部分。
資料模組為藍色,底部則是核心或通用模組,通常用於包含其他模組經常使用的程式碼。
接著,您可以在專案的 Gradle 設定檔中,加入並設定這個多模組 Gradle 設定,以支援這類模組化。
...
rootProject.name = "MultiFormFactorApp"
// Define modules for each form factor
include(":app:automotive")
include(":app:mobile")
include(":core:network")
include(":data:books")
include(":data:reviews")
include(":feature:home")
include(":feature:player")
include(":feature:reviews")因此,每個應用程式模組和捆綁包都將使用相同的包名或應用程式 ID。
這種模組化做法與 Play 管理中心的測試群組策略直接相關。
發布時,您可以使用標準行動裝置測試群組,但我們也提供專屬板型規格測試群組。
如果是 Android TV、Android XR 和 Android Automotive OS,您可以選擇。
您可以與行動裝置版本同時發布,或使用專屬板型規格測試群組。
不過,有兩種例外狀況。
如果是 Wear OS,則必須使用專屬的 Wear OS 測試群組。
至於 Android Auto,由於它基本上是投射到車輛螢幕上的行動應用程式擴充功能,因此只能選擇標準行動測試群組。
如果您管理多個測試群組,版本管理就非常重要。
其中一種做法是將版本代碼的前幾位數指派給板型規格。
例如,01 代表行動裝置、02 代表 Wear OS、03 代表 Android Automotive OS 等。
一般建議版本代碼長度至少為七位數,這樣剩餘的位數就能用於應用程式版本。
這有助於避免 Play 管理中心發生版本代碼衝突。
應用程式封裝完成後,就可以開始測試。
板型規格開發需要經過徹底測試,Google Play 提供三種不同的管道,讓您在發布正式版前進行測試:內部測試、封閉測試和公開測試。
如果您使用專屬板型規格測試群組,也可以將這些測試群組與板型規格結合,進一步精細控管程序。
舉例來說,您可以透過標準測試群組,為行動應用程式推出封閉測試版本,並透過專屬的 Android TV 版型測試群組,為 Android TV 應用程式推出獨立的封閉測試版本,並視需要設定不同的測試人員群組。
因此,內部測試是很好的起點。
您可以快速將應用程式發布給最多 100 位測試人員,而且最重要的是,這不會觸發 Play 審查。
也就是說,您和測試人員可以快速在裝置上安裝應用程式,並在模擬器或實際的電視、手錶或其他裝置上驗證體驗。
進行內部測試時,您會取得專屬網址,可以分享給測試人員。
如果對內部測試結果感到滿意,就可以進行封閉測試和公開測試。
除了內部測試,您也可以執行封閉測試,邀請更多測試人員測試預先發布版應用程式,收集更精確的意見回饋。
您可以透過電子郵件地址清單或 Google 群組,管理封閉測試群組。
公開測試則可讓您在 Google Play 上對更多使用者進行測試。
您的應用程式會顯示在 Google Play,任何人都能加入公開測試計畫。
他們不需收到邀請,就能與您分享對應用程式的意見和私人意見。
這些公開和封閉測試群組會觸發審查。
這其實是一大優勢。
您可以測試審查程序,並在備受期待的發布日前排除任何障礙。
接下來,我們來談談審查程序包含哪些內容,以及為什麼這項程序很重要。
這些政策和規範的核心,就是應用程式品質。
因此,優質應用程式和遊戲可為使用者帶來價值、提供愉悅的使用體驗、充分發揮高階裝置效能,並採用融入安全考量的設計。
接下來,我們將說明如何做好準備,讓應用程式輕鬆通過審查。
我認為最好的起點是查看應用程式品質指南,瞭解優質使用者體驗的樣貌。
我們發布了適用於所有應用程式的核心應用程式品質指南,定義所有應用程式應符合的最低品質,以及自動調整應用程式品質指南,協助您確保應用程式在任何裝置板型規格、螢幕大小或顯示模式下,都能提供優質體驗。
這兩套指南是很好的起點。
不過,我們也針對每種板型規格制定了專屬的應用程式品質指南。
我們的審查人員會根據這些指南,在實體裝置和模擬器上測試您的應用程式。
因此,請務必確保應用程式遵守這些政策。
接下來,我們將快速說明應用程式在各板型規格中遭拒的最常見原因。
但請注意,這些並未涵蓋所有應用程式品質指南。
因此,請務必詳閱各板型規格的品質指南,瞭解更完整的條件。
首先,我們來看看 Android TV。
因此,在這些章節投影片的底部,您會看到一個短連結,可前往該板型規格的完整應用程式品質指南清單。
Android TV 應用程式遭拒的常見原因之一,是未針對應用程式支援的每種語言提供主畫面橫幅圖片。
因此,您應該提供 320 x 180 像素的圖片,並在圖片中加入本地化文字,以便識別您的應用程式。
這張投影片中的圖片,是符合上述條件的主畫面橫幅範例。
第二,在大多數電視上,使用者會使用 D-pad 遙控器與裝置互動。
因此,請務必妥善支援 D-pad 導覽和焦點。
請務必至少支援最低限度的 D-pad 控制項,以免因不符合這些條件而遭拒。
第三個常見的 Android TV 應用程式遭拒原因,是 Android 資訊清單檔案中缺少 CATEGORY_LEANBACK_LAUNCHER 意圖篩選器。
<application ...>
...
<activity
android:name="com.example.TvActivity"
android:label="@string/app_name"
android:theme="@style/Theme.Leanback">
<intent-filter>
<action android:name=
"android.intent.action.MAIN" />
<category android:name=
"Android.intent.category.
LEANBACK_LAUNCHER" />
</intent-filter>
</activity>
</application>這個篩選器會將您的應用程式識別為已啟用電視功能,並讓 Google Play 也將其識別為電視應用程式。
當使用者在電視主畫面上選取您的應用程式時,系統會根據這個意圖判斷要啟動哪個活動。
因此請務必在資訊清單中加入這項權限。
Android XR 則是下一個。
建構 Android XR 支援的 XR 頭戴式裝置或 XR 眼鏡時,請特別注意應用程式的效能、算繪和穩定性。
您可以使用 Perfetto 分析 Jetpack XR SDK 建構的應用程式效能,確保符合最低影格率規定。
如果您使用 Unity 等即時引擎建構內容,可以使用引擎內建的分析工具,確保符合轉譯規定。
接下來是車輛,包括 Android Auto 和 Android Automotive OS。
Android Auto 和 Android Automotive OS 有類別的概念,這對這個特定板型規格來說有點獨特。
只有特定類別的應用程式可以發布到車輛。
因此,如果您提交的應用程式類別不屬於我們支援的類別,或是您將應用程式提交至公開測試或正式版,但該類別僅處於 Beta 版階段,就會遭到拒絕。
接下來,我會更詳細地說明。
您可以在這裡查看各平台支援的車用應用程式類別總覽,以及其可用性。
無論是 Beta 版、公開版 (即正式發布),或尚未支援 (此處標示為「即將推出」)。
因此,導航或搜尋點等類別的應用程式已正式發布,這表示任何人都可以將這些類別的應用程式發布到車輛的正式版。
但其他類別 (例如 Android Auto 的通訊通話應用程式) 仍處於 Beta 版階段。
因此,您可以將這類應用程式發布至內部測試或封閉測試群組,但除非您已獲准加入該類別的搶先體驗計畫,否則無法發布至正式版群組。
如要進一步瞭解這項功能和其他資訊,請參閱車輛專用 Android 開發人員指南。
您可以在該頁面找到連結,申請加入這些搶先體驗計畫。
另一個常見的拒絕原因,是 Android Automotive OS 螢幕截圖規格不符或有誤。
因此,提供 Android Automotive OS 螢幕截圖時,請務必附上至少兩張直向螢幕截圖,以及至少兩張橫向螢幕截圖,尺寸須符合這裡列出的規格。
您可以使用 Android Automotive OS 模擬器擷取這些資訊。
這項設定可擷取所需大小的螢幕截圖。
最後,車用應用程式最重視安全性。
因此,如果應用程式不符合駕駛人分心等級指南,就會遭到拒絕。
舉例來說,影片應用程式必須暫停播放,且在車輛行進時不得顯示。
最後,但同樣重要的一點是 Wear OS。
因此,如果 Wear OS 應用程式未針對小型圓形螢幕進行最佳化和格式化,可能會遭到拒絕。
因此,我們建議使用最新穩定版 Compose for Wear OS,確保內容不會在不同尺寸的裝置上遭到邊緣裁剪,或確保捲動式內容出現時會顯示捲軸。
@Composable
fun MyText() {
Text(
text = stringResource(R.string.compose_for_wear_os),
modifier = Modifier.fillMaxWidth(),
textAlign = TextAlign.Center,
style = MaterialTheme.typography.titleLarge
)
}與 Android Automotive OS 類似,如果 Wear OS 應用程式缺少 Wear OS 螢幕截圖或螢幕截圖不正確,也可能遭到拒絕。
以下是 Androidify 範例應用程式在 Google Play 商店資訊中的螢幕截圖,這張截圖符合規定。
因此,請務必提交至少一張螢幕截圖,展示應用程式在 Wear OS 裝置上執行的情形。
...
rootProject.name = "MultiFormFactorApp"
// Define modules for each form factor
include(":app:automotive")
include(":app:mobile")
include(":core:network")
include(":data:books")
include(":data:reviews")
include(":feature:home")
include(":feature:player")
include(":feature:reviews")<application ...>
...
<activity
android:name="com.example.TvActivity"
android:label="@string/app_name"
android:theme="@style/Theme.Leanback">
<intent-filter>
<action android:name=
"android.intent.action.MAIN" />
<category android:name=
"Android.intent.category.
LEANBACK_LAUNCHER" />
</intent-filter>
</activity>
</application>@Composable
fun MyText() {
Text(
text = stringResource(R.string.compose_for_wear_os),
modifier = Modifier.fillMaxWidth(),
textAlign = TextAlign.Center,
style = MaterialTheme.typography.titleLarge
)
}