ما وراء الميزات الفردية: ضمان توافق مجموعات الميزات مع CameraX 1.5
مدّة القراءة: 6 دقائق
تتميّز تطبيقات الكاميرا الحديثة بميزات قوية ومتداخلة. يتوقّع المستخدمون تسجيل فيديو بنطاق عالي الديناميكية مذهل، والتقاط حركة سلسة بسرعة 60 لقطة في الثانية، والحصول على لقطات سلسة للغاية باستخدام ميزة "تثبيت المعاينة"، وغالبًا ما يتم كل ذلك في الوقت نفسه.
بصفتنا مطوّرين، ندرك أنّ الواقع أكثر تعقيدًا. كيف يمكنك ضمان أنّ جهازًا معيّنًا يتوافق فعلاً مع مجموعة معيّنة؟ حتى الآن، كان تفعيل ميزات متعددة غالبًا ما يكون أمرًا محفوفًا بالمخاطر. يمكنك التحقّق من توافق كل ميزة على حدة، ولكن قد يؤدي الجمع بينها إلى سلوك غير محدّد أو، الأسوأ من ذلك، إلى تعذُّر بدء جلسة الكاميرا. ويجبر هذا الغموض المطوّرين على توخّي الحذر، ما يمنع المستخدمين على الأجهزة المتوافقة من الحصول على أفضل تجربة ممكنة.
على سبيل المثال، لا تتيح سوى أجهزة قليلة جدًا من الفئة الممتازة إمكانية تسجيل فيديو بنطاق عالي الديناميكية و60 لقطة في الثانية في الوقت نفسه. نتيجةً لذلك، تتجنّب معظم التطبيقات تفعيل كليهما في الوقت نفسه لمنع حدوث تجربة مستخدم سيئة على معظم الهواتف.
لمعالجة هذه المشكلة، نقدّم مجموعة الميزات في CameraX، وهي واجهة برمجة تطبيقات جديدة مصمَّمة لإزالة هذه التخمينات. يمكنك الآن الاستعلام عمّا إذا كانت مجموعة معيّنة من الميزات متوافقة قبل ضبط إعدادات الكاميرا، أو يمكنك ببساطة إخبار CameraX بأولوياتك والسماح لها بتفعيل أفضل مجموعة متوافقة لك.
لمن لا يعرفون CameraX
قبل أن نتناول بالتفصيل واجهة برمجة التطبيقات الجديدة لمجموعة الميزات، دعنا نراجع سريعًا ما هي CameraX. CameraX هي مكتبة دعم Jetpack، وهي مصمَّمة لمساعدتك في تسهيل عملية تطوير تطبيقات الكاميرا. وتوفّر هذه المكتبة مساحة سطح متسقة وسهلة الاستخدام لواجهة برمجة التطبيقات تعمل على معظم أجهزة Android، مع إمكانية التوافق مع الإصدارات القديمة حتى Android 6.0 (المستوى 23 من واجهة برمجة التطبيقات). إذا كنت لا تزال مبتدئًا في استخدام CameraX، ننصحك بالاطّلاع على المستندات الرسمية وتجربة الدرس التطبيقي حول الترميز للبدء.
الإجراءات التي يمكنك تنفيذها باستخدام Feature Group API
لم يعُد عليك التخمين بشأن توافق الميزات، بل يمكنك تقديم أفضل تجارب ممكنة للكاميرا بثقة، مثل تسجيل فيديو بنطاق عالي الديناميكية (HDR) و60 لقطة في الثانية في الوقت نفسه على أجهزة متوافقة (مثل Pixel 10 Pro)، مع تجنُّب الأخطاء على الأجهزة التي لا يمكنها دعم هذه الميزات.
باستخدام Feature Group API، يمكنك إجراء ما يلي:
- إنشاء واجهات مستخدم ديناميكية وأكثر ذكاءً: يمكنك تفعيل الإعدادات أو إيقافها بذكاء في واجهة المستخدم استنادًا إلى توافق الأجهزة في الوقت الفعلي. على سبيل المثال، إذا فعّل المستخدم تقنية HDR، يمكنك إيقاف خيار 60 لقطة في الثانية على الفور إذا كان الجهاز لا يتيح استخدام هذا الخيار مع تقنية HDR.
- توفير وضع "جودة عالية" موثوق: اضبط الكاميرا باستخدام قائمة ميزات ذات أولوية. تعثر CameraX تلقائيًا على أفضل مجموعة متوافقة مع أي جهاز وتفعّلها، ما يضمن الحصول على نتيجة رائعة بدون منطق معقّد خاص بالجهاز.
- منع حدوث أخطاء في جلسة الكاميرا: من خلال التحقّق من التوافق مسبقًا، يمكنك منع الكاميرا من محاولة ضبط تركيبة غير متوافقة، ما يحدّ من أحد الأسباب الشائعة لحدوث الأعطال ويوفّر تجربة سلسة للمستخدم.
طريقة العمل: المكوّنات الأساسية
تتمحور واجهة برمجة التطبيقات الجديدة حول إضافات رئيسية إلى SessionConfig وCameraInfo.
- GroupableFeature: تقدّم واجهة برمجة التطبيقات هذه مجموعة من الميزات المحدّدة مسبقًا والقابلة للتجميع، مثل HDR_HLG10 وFPS_60 وPREVIEW_STABILIZATION وIMAGE_ULTRA_HDR. بسبب القيود الحسابية، لا يمكن تجميع سوى مجموعة معيّنة من الميزات بدرجة الموثوقية العالية التي توفّرها واجهة برمجة التطبيقات هذه. نعمل حاليًا على توسيع هذه القائمة وسنوفّر المزيد من الميزات في الإصدارات المستقبلية.
- مَعلمات SessionConfig الجديدة: يقبل هذا الصف، المستخدَم لبدء جلسة كاميرا، الآن مَعلمتَين جديدتَين:
requiredFeatureGroup: استخدِم هذا الخيار للميزات التي يجب أن تكون متاحة لكي ينجح الإعداد، وهو خيار مثالي للميزات التي يفعّلها المستخدم بشكل صريح، مثل تفعيل خيار "النطاق الديناميكي العالي" (HDR). لضمان تجربة خوارزمية حتمية ومتّسقة، ستطرح الدالةbindToLifecycleالخطأIllegalArgumentExceptionإذا كان الجمع المطلوب غير متاح، بدلاً من تجاهل طلب ميزة بدون إشعار. يجب استخدام واجهة برمجة التطبيقاتCameraInfo#isFeatureGroupSupported(التفاصيل أدناه) للبحث عن هذه النتيجة مسبقًا.-
preferredFeatureGroup: استخدِم هذا الخيار للميزات المرغوب فيها ولكنها اختيارية، على سبيل المثال عندما تريد تنفيذ وضع "جودة عالية" تلقائي. يمكنك تقديم قائمة بالميزات المطلوبة مرتّبة حسب أولوياتك، وتفعّل CameraX تلقائيًا المجموعة ذات الأولوية الأعلى التي يتيحها الجهاز.
- CameraInfo#isFeatureGroupSupported(): هذه هي طريقة طلب البحث الأساسية للتحقّق بشكل صريح مما إذا كانت مجموعة ميزات متوافقة، وهي مناسبة تمامًا لتقديم خيارات الميزات المتوافقة فقط للمستخدمين في واجهة مستخدم تطبيقك. يمكنك تمرير
SessionConfigإليها، وستعرض قيمة منطقية تشير إلى ما إذا كانت المجموعة متوافقة. إذا كنت تنوي ربطSessionConfigبميزات مطلوبة، عليك استخدام واجهة برمجة التطبيقات هذه أولاً للتأكّد من أنّها متوافقة.
التنفيذ في الممارسة
لنلقِ نظرة على كيفية استخدام هذه المكوّنات لإنشاء تجربة كاميرا أفضل.
السيناريو 1: "وضع الجودة العالية" بأفضل جهد
إذا أردت تفعيل أفضل الميزات المتاحة تلقائيًا، يمكنك تقديم قائمة ذات أولوية إلى preferredFeatureGroup. في هذا المثال، نطلب من CameraX إعطاء الأولوية لتقنية HDR، ثم 60 لقطة في الثانية، وأخيرًا ميزة "تثبيت المعاينة". تتولّى CameraX مهمة التحقّق من جميع المجموعات المحتملة واختيار أفضل مجموعة يتيحها الجهاز.
على سبيل المثال، إذا كان الجهاز يمكنه التعامل مع النطاق الديناميكي العالي و60 لقطة في الثانية معًا ولكن ليس مع ميزة "تثبيت المعاينة"، ستفعّل 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 لقطة في الثانية + تثبيت المعاينة
- نطاق عالي الديناميكية (HDR) + 60 لقطة في الثانية
- تثبيت الصورة مع تقنية HDR والمعاينة
- نطاق عالي الديناميكية
- 60 لقطة في الثانية + تثبيت المعاينة
- 60 لقطة في الثانية
- معاينة التثبيت
- لا شيء من الميزات المذكورة أعلاه
السيناريو 2: إنشاء واجهة مستخدم تفاعلية
لإنشاء واجهة مستخدم تستجيب لاختيارات المستخدمين وتمنعهم من تحديد مجموعة ميزات غير متوافقة، يمكنك الاستعلام عن التوافق مباشرةً. تتحقّق الدالة أدناه من الميزات غير المتوافقة مع اختيارات المستخدم الحالية، ما يتيح لك إيقاف عناصر واجهة المستخدم ذات الصلة.
/**
* 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 أو وحدة التحكّم في واجهة المستخدم للردّ على بيانات أدخلها المستخدم وإعادة ربط الكاميرا بإعدادات مضمونة العمل.
// 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,
)
)
}للاطّلاع على هذه المفاهيم في تطبيق عملي، يمكنك استكشاف تطبيق الاختبار الداخلي الذي يوفّر تنفيذًا كاملاً لكلّ من سيناريوهات "أفضل جهد" و "واجهة المستخدم التفاعلية" الموضّحة أعلاه.
يُرجى العِلم أنّ هذا التطبيق تجريبي وليس نموذجًا متاحًا رسميًا. مع أنّها مرجع رائع لواجهة برمجة التطبيقات Feature Group API، لم يتم تحسينها للاستخدام في مرحلة الإنتاج.
ابدأ اليوم
تزيل Feature Group API الغموض المرتبط بالعمل مع إمكانات الكاميرا المتقدّمة. من خلال توفير طريقة حتمية للاستعلام عن توافق الميزات، يمكنك إنشاء تطبيقات كاميرا أكثر فعالية وموثوقية بثقة.
تتوفّر واجهة برمجة التطبيقات كتجريبية في CameraX 1.5 ومن المقرر أن تصبح ثابتة تمامًا في الإصدار 1.6، مع توفّر المزيد من الميزات والتحسينات قريبًا.
لمزيد من المعلومات، يُرجى الاطّلاع على المستندات الرسمية. نحن متحمّسون لرؤية أعمالكم الإبداعية، ونتطلّع إلى تلقّي ملاحظاتكم. يُرجى مشاركة أفكارك والإبلاغ عن أي مشاكل من خلال القنوات التالية:
-
أخبار المنتجاتعلى Google Play، نعمل باستمرار على توسيع منصة الاشتراكات لمساعدتك في تعزيز النمو والتكيّف مع نماذج الأعمال الجديدة وتلبية احتياجات المستخدمين أينما كانوا.
Sheenam Mittal • مدّة القراءة: 4 دقائق -
أخبار المنتجاتفي العام الماضي، أصبح بإمكان "استوديو Android" استخدام أي نموذج للذكاء الاصطناعي. واليوم، نتّخذ الخطوة التالية من خلال توفير إمكانية اختيار وكلاء الترميز.
Matthew Warner • مدّة القراءة: 3 دقائق -
أخبار المنتجاتتقدّم Googlebook فئة جديدة من أجهزة الكمبيوتر المحمول المستندة إلى أساس Android المشترك. تجمع أجهزة Chromebook Plus بين سهولة استخدام الأجهزة الجوّالة وقوة أجهزة الكمبيوتر المكتبي، وهي مزوّدة بأجهزة عالية الأداء من شركاء مثل HP وDell وLenovo وAcer وAsus.
Fahd Imtiaz, Loryn Hairston • مدّة القراءة: 4 دقائق
يمكنك تلقّي أحدث الإحصاءات حول تطوير تطبيقات Android في بريدك الوارد أسبوعيًا.