現代相機應用程式的特色在於功能強大且重疊。使用者希望錄製 HDR 影片、以 60 FPS 捕捉流暢動作,並透過預覽穩定功能取得流暢的影片,而且通常希望同時達成這些目標。
身為開發人員,我們知道實際情況更加複雜。如何確保特定裝置實際支援特定組合?啟用多項功能往往是碰運氣,你可以檢查個別功能是否支援,但如果將這些功能合併使用,可能會導致未定義的行為,或更糟的情況,就是攝影機工作階段失敗。這種不確定性會迫使開發人員採取保守做法,導致使用者無法在效能充足的裝置上獲得最佳體驗。
舉例來說,只有極少數高階裝置能同時穩定支援 HDR 和 60 FPS 影片。因此,大多數應用程式都會避免同時啟用這兩項功能,以免在大多數手機上造成不良的使用者體驗。
為解決這個問題,我們推出了 CameraX 中的功能群組,這項新 API 的設計宗旨是消除這類猜測。現在您可以在設定相機前,查詢是否支援特定功能組合,也可以直接告知 CameraX 您的優先順序,讓 CameraX 為您啟用最適合的組合。
CameraX 新手
在深入瞭解新的 Feature Group API 之前,我們先快速回顧 CameraX。CameraX 是 Jetpack 支援資料庫,可協助您輕鬆開發相機應用程式。並提供一致且易於使用的 API 介面,適用於大多數 Android 裝置,具備 Android 6.0 (API 級別 23) 的回溯相容性。如果您是 CameraX 新手,建議先查看官方說明文件,並嘗試程式碼研究室。
您可以使用特徵群組 API 建構的項目
您不必再冒險組合功能,可以放心地提供最佳的相機體驗,例如在支援的硬體 (例如 Pixel 10 Pro) 上同時使用 HDR 和 60 FPS 影片,並在無法支援組合的裝置上順利避免錯誤。
Pixel 10 Pro 同時啟用 HDR 和 60 FPS
如果裝置較舊,無法同時執行 HDR 和 60 FPS,系統只會啟用 HDR,並停用 60 FPS 選項。
透過 Feature Group API,您可以:
- 建構更智慧的動態 UI:根據即時硬體支援情況,在 UI 中智慧地啟用或停用設定。舉例來說,如果使用者啟用 HDR,但裝置不支援 HDR 和 60 FPS 的組合,您可以立即將 60 FPS 選項設為灰色並停用。
- 提供可靠的「高畫質」模式: 設定攝影機時,請優先列出所需功能。CameraX 會自動找出並啟用任何裝置最支援的組合,確保產生優質結果,不必使用複雜的裝置專屬邏輯。
- 避免相機工作階段失敗:預先驗證支援情形,可防止相機嘗試設定不支援的組合,消除常見的當機原因,提供流暢的使用者體驗。
運作方式:核心元件
新版 API 的核心是 SessionConfig 和 CameraInfo 的重要新增項目。
- GroupableFeature:這項 API 導入一組預先定義的可分組功能,例如 HDR_HLG10、FPS_60、PREVIEW_STABILIZATION 和 IMAGE_ULTRA_HDR。由於運算限制,只有特定功能組合才能以這個 API 提供的高可靠度分組。我們正積極擴充這份清單,並會在日後推出的版本中支援更多功能。
- 新SessionConfig 參數:這個類別用於啟動攝影機工作階段,現在接受兩個新參數:
requiredFeatureGroup:用於必須支援的功能,才能成功設定,非常適合使用者明確啟用的功能,例如切換「HDR」開關。為確保體驗具有決定性且一致,如果系統不支援所要求的組合,bindToLifecycle呼叫會擲回IllegalArgumentException,而不是默默忽略功能要求。請先使用CameraInfo#isFeatureGroupSupportedAPI (詳情請見下文) 查詢這項結果。preferredFeatureGroup:用於可有可無但很實用的功能,例如您想實作預設的「高畫質」模式。您提供依優先順序排序的所需功能清單,CameraX 會自動啟用裝置支援的最高優先順序組合。
- CameraInfo#isFeatureGroupSupported():這是用於明確檢查是否支援功能群組的核心查詢方法,非常適合在應用程式 UI 中僅向使用者提供支援的功能選項。您會將
SessionConfig傳遞給這個函式,而函式會傳回布林值,指出是否支援該組合。如果您打算繫結具有必要功能的SessionConfig,請先使用這個 API 確保該功能受到支援。
實際導入
讓我們看看如何使用這些元件,打造更優質的相機體驗。
情境 1:「盡量」高畫質模式
如要預設啟用最佳功能,可以向 preferredFeatureGroup 提供優先順序清單。在本範例中,我們告知 CameraX 優先處理 HDR,然後是 60 FPS,最後是預覽穩定功能。CameraX 會處理檢查所有可能組合的複雜作業,並選擇裝置支援的最佳組合。
舉例來說,如果裝置可以同時處理 HDR 和 60 FPS,但無法處理預覽畫面穩定功能,CameraX 就會啟用前兩者,並捨棄第三者。這樣一來,您就能獲得最佳體驗,不必編寫複雜的裝置專用檢查。
cameraProvider.bindToLifecycle(
lifecycleOwner,
cameraSelector,
SessionConfig(
useCases = listOf(preview, videoCapture),
// The order of features in this list determines their priority.
// CameraX will enable the best-supported combination based on these
// priorities: HDR_HLG10 > FPS_60 > Preview Stabilization.
preferredFeatureGroup =
listOf(HDR_HLG10, FPS_60, PREVIEW_STABILIZATION),
).apply {
// (Optional) Get a callback with the enabled features
// to update your UI.
setFeatureSelectionListener { selectedFeatures ->
updateUiIndicators(selectedFeatures)
}
}
)
對於這個程式碼片段,CameraX 會嘗試依下列優先順序啟用功能組合,並選取裝置完全支援的第一個組合:
- HDR + 60 FPS + 預覽防震功能
- HDR + 60 FPS
- HDR + 預覽防震功能
- 高動態範圍
- 60 FPS + 預覽防震功能
- 每秒 60 個影格
- 預覽防震功能
- 以上皆非
情境 2:建構反應式 UI
如要建立可回應使用者選取內容的 UI,並防止使用者選取不支援的功能組合,您可以直接查詢支援項目。以下函式會檢查哪些功能與使用者的目前選項不相容,方便您停用對應的 UI 元素。
/**
* Returns a list of features that are NOT supported in combination
* with the currently selected features.
*/
fun getUnsupportedFeatures(
currentFeatures: Set<GroupableFeature>
): Set<GroupableFeature> {
val unsupportedFeatures = mutableSetOf<GroupableFeature>()
val appFeatureOptions = setOf(HDR_HLG10, FPS_60, PREVIEW_STABILIZATION)
// Iterate over every available feature option in your app.
appFeatureOptions.forEach { featureOption ->
// Skip features the user has already selected.
if (currentFeatures.contains(featureOption)) return@forEach
// Check if adding this new feature is supported.
val isSupported = cameraInfo.isFeatureGroupSupported(
SessionConfig(
useCases = useCases,
// Check the new feature on top of existing ones.
requiredFeatureGroup = currentFeatures + featureOption
)
)
if (!isSupported) {
unsupportedFeatures.add(featureOption)
}
}
return unsupportedFeatures
}
接著,您可以將這項邏輯連線至 ViewModel 或 UI 控制器,以便對使用者輸入內容做出反應,並使用保證可運作的設定重新繫結攝影機。
// Invoked when user turns some feature on/off.
fun onFeatureChange(currentFeatures: Set<GroupableFeature>) {
// Identify features that are unsupported with the current selection.
val unsupportedFeatures = getUnsupportedFeatures(currentFeatures)
// Update app UI so that users can't enable them.
updateDisabledFeatures(unsupportedFeatures)
// Since the UI now only allows selecting supported feature combinations,
// `currentFeatures` is always valid. This allows setting
// `requiredFeatureGroup` directly, without needing to re-check for
// support or set a feature selection listener.
cameraProvider.bindToLifecycle(
lifecycleOwner,
cameraSelector,
SessionConfig(
useCases = listOf(preview, videoCapture),
requiredFeatureGroup = currentFeatures,
)
)
}
如要在實際運作的應用程式中查看這些概念,可以探索我們的內部測試應用程式。這個應用程式完整實作了上述「盡力而為」和「反應式 UI」情境。
請注意:這是測試應用程式,並非官方支援的範例。雖然這份文件是 Feature Group API 的絕佳參考資料,但尚未經過潤飾,不適合用於正式環境。
立即開始使用
Feature Group API 可消除使用進階相機功能時的模糊地帶。透過提供查詢功能支援的確定性方式,您可以放心地建構更強大且可靠的相機應用程式。
這項 API 在 CameraX 1.5 中為實驗功能,預計在 1.6 版中全面穩定推出,並持續提供更多支援和改善項目。
詳情請參閱官方說明文件。我們很期待看到你的作品,也歡迎提供意見回饋。歡迎透過以下管道分享你的想法或回報任何問題:
繼續閱讀
-
產品新訊
盡可能確保 Google Play 提供最安全可靠的服務體驗。今天,我們宣布推出一系列新政策和帳戶轉移功能,進一步保障使用者隱私,並防範詐欺行為。
Bennet Manuel • 3 分鐘可讀完
-
產品新訊
現在使用 Android Emulator,就能輕鬆測試支援多種裝置的互動。
Steven Jenkins • 閱讀時間:2 分鐘
-
產品新訊
每位開發人員的 AI 工作流程和需求都不盡相同,因此選擇 AI 輔助開發的方式非常重要。我們在 1 月推出這項功能,讓您選擇任何本機或遠端 AI 模型,為 Android Studio 中的 AI 功能提供支援
Matthew Warner • 閱讀時間:2 分鐘
隨時掌握最新消息
每週透過電子郵件接收最新的 Android 開發洞察資料。