ملاحظة: تشير هذه الصفحة إلى حزمة Camera2. ننصحك باستخدام CameraX، ما لم يتطلّب تطبيقك ميزات محدّدة منخفضة المستوى من Camera2. تتوافق كل من CameraX وCamera2 مع الإصدار 5.0 من نظام التشغيل Android (المستوى 21 من واجهة برمجة التطبيقات) والإصدارات الأحدث.
لا تكون الكاميرات ومعاينات الكاميرا دائمًا في الاتجاه نفسه على أجهزة Android.
تكون الكاميرا في موضع ثابت على الجهاز، بغض النظر عما إذا كان الجهاز هاتفًا أو جهازًا لوحيًا أو كمبيوتر. عندما يتغير اتجاه الجهاز، يتغير اتجاه الكاميرا.
نتيجةً لذلك، تفترض تطبيقات الكاميرا بشكل عام وجود علاقة ثابتة بين اتجاه الجهاز ونسبة العرض إلى الارتفاع لمعاينة الكاميرا. عندما يكون الهاتف في الوضع العمودي، من المفترض أن تكون معاينة الكاميرا أطول من عرضها. عند تدوير الهاتف (والكاميرا) إلى الوضع الأفقي، من المتوقّع أن تكون معاينة الكاميرا أعرض من طولها.
ولكن هذه الافتراضات تواجه تحديات بسبب أشكال الأجهزة الجديدة، مثل الأجهزة القابلة للطي، وأوضاع العرض مثل النوافذ المتعددة والشاشات المتعددة. تغير الأجهزة القابلة للطي حجم العرض ونسبة العرض إلى الارتفاع دون تغيير الاتجاه. يؤدي وضع النوافذ المتعددة إلى حصر تطبيقات الكاميرا في جزء من الشاشة، ما يؤدي إلى تغيير حجم معاينة الكاميرا بغض النظر عن اتجاه الجهاز. يتيح وضع "الشاشات المتعددة" استخدام شاشات ثانوية قد لا تكون في الاتجاه نفسه للشاشة الأساسية.
اتجاه الكاميرا
يحدّد مستند تعريف التوافق مع Android أنّه "يجب توجيه وحدة استشعار الصور في الكاميرا بحيث يتوافق البُعد الطويل للكاميرا مع البُعد الطويل للشاشة. أي أنّه عند حمل الجهاز في الوضع الأفقي، يجب أن تلتقط الكاميرات الصور في الوضع الأفقي. ينطبق ذلك بغض النظر عن الاتجاه الطبيعي للجهاز، أي أنّه ينطبق على الأجهزة التي يكون اتجاهها الأساسي أفقيًا وكذلك الأجهزة التي يكون اتجاهها الأساسي عموديًا".
يؤدي ترتيب الكاميرا على الشاشة إلى زيادة مساحة عرض عدسة الكاميرا في تطبيق الكاميرا إلى أقصى حد. بالإضافة إلى ذلك، عادةً ما تُخرج وحدات استشعار الصور بياناتها بنِسب عرض إلى ارتفاع أفقية، وتكون النسبة 4:3 هي الأكثر شيوعًا.
الاتجاه الطبيعي لمستشعر الكاميرا هو الاتجاه الأفقي. في الشكل 1، يتم تدوير أداة استشعار الكاميرا الأمامية (الكاميرا التي تشير إلى الاتجاه نفسه الذي تشير إليه الشاشة) بمقدار 270 درجة بالنسبة إلى الهاتف للامتثال لمستند تعريف التوافق مع Android.
لإتاحة تدوير أداة الاستشعار للتطبيقات، تتضمّن واجهة برمجة التطبيقات camera2 الثابت SENSOR_ORIENTATION. في معظم الهواتف والأجهزة اللوحية، يبلغ الجهاز عن اتجاه أداة استشعار يبلغ 270 درجة للكاميرات الأمامية و90 درجة (وجهة النظر من الجزء الخلفي للجهاز) للكاميرات الخلفية، مما يحاذي الحافة الطويلة لأداة الاستشعار مع الحافة الطويلة للجهاز. تُبلغ كاميرات أجهزة الكمبيوتر المحمول بشكل عام عن اتجاه أداة استشعار يبلغ 0 أو 180 درجة.
بما أنّ وحدات استشعار الصور في الكاميرا تُخرج بياناتها (مخزن مؤقت للصور) في الاتجاه الطبيعي لوحدة الاستشعار (الأفقي)، يجب تدوير المخزن المؤقت للصور بعدد الدرجات المحدّد في SENSOR_ORIENTATION لكي تظهر معاينة الكاميرا في الاتجاه الطبيعي للجهاز. بالنسبة إلى الكاميرات الأمامية، يكون التدوير عكس اتجاه عقارب الساعة، وبالنسبة إلى الكاميرات الخلفية، يكون في اتجاه عقارب الساعة.
على سبيل المثال، بالنسبة إلى الكاميرا الأمامية في الشكل 1، يبدو المخزن المؤقت للصور الذي ينتجه مستشعر الكاميرا على النحو التالي:
يجب تدوير الصورة بمقدار 270 درجة عكس اتجاه عقارب الساعة لكي يتطابق اتجاه المعاينة مع اتجاه الجهاز:
ستنتج الكاميرا الخلفية مخزنًا مؤقتًا للصور بالاتجاه نفسه
للمخزن المؤقت السابق، ولكن SENSOR_ORIENTATION تبلغ 90 درجة. ونتيجة لذلك، يتم تدوير المخزن المؤقت
بمقدار 90 درجة في اتجاه عقارب الساعة.
تدوير الجهاز
تدوير الجهاز هو عدد درجات تدوير الجهاز من اتجاهه الطبيعي. على سبيل المثال، الهاتف في الوضع الأفقي يكون تدوير الجهاز فيه بمقدار 90 أو 270 درجة، حسب اتجاه التدوير.
يجب تدوير مخزن الصور المؤقت في أداة استشعار الكاميرا بنفس عدد درجات تدوير الجهاز (بالإضافة إلى درجات اتجاه أداة الاستشعار) لكي تظهر معاينة الكاميرا في وضع عمودي.
احتساب الاتجاه
يأخذ الاتجاه الصحيح لمعاينة الكاميرا في الاعتبار اتجاه أداة الاستشعار وتدوير الجهاز.
يمكن احتساب التدوير الإجمالي لذاكرة التخزين المؤقت لصورة أداة الاستشعار باستخدام الصيغة التالية:
rotation = (sensorOrientationDegrees - deviceOrientationDegrees * sign + 360) % 360
حيث يمثّل sign القيمة 1 للكاميرات الأمامية، والقيمة -1 للكاميرات الخلفية.
بالنسبة إلى الكاميرات الأمامية، يتم تدوير مخزن الصور المؤقت عكس عقارب الساعة (من الاتجاه الطبيعي لأداة الاستشعار). بالنسبة إلى الكاميرات الخلفية، يتم تدوير مخزن الصور المؤقت الخاص بأداة الاستشعار في اتجاه عقارب الساعة.
يحوّل التعبير deviceOrientationDegrees * sign + 360 تدوير الجهاز
من عكس عقارب الساعة إلى اتجاه عقارب الساعة للكاميرات الخلفية (على سبيل المثال،
تحويل 270 درجة عكس عقارب الساعة إلى 90 درجة في اتجاه عقارب الساعة). تعمل عملية حساب باقي القسمة على تغيير حجم النتيجة إلى أقل من 360 درجة (على سبيل المثال، تغيير حجم 540 درجة من الدوران إلى 180).
تُبلغ واجهات برمجة التطبيقات المختلفة عن تدوير الجهاز بشكل مختلف:
- يوفّر
Display#getRotation()دوران الجهاز عكس عقارب الساعة (من وجهة نظر المستخدم). يتم إدخال هذه القيمة في المعادلة السابقة كما هي. OrientationEventListener#onOrientationChanged()تعرض هذه الدالة دوران الجهاز في اتجاه عقارب الساعة (من وجهة نظر المستخدم). اعكس القيمة لاستخدامها في الصيغة السابقة.
الكاميرات الأمامية
في ما يلي مخزن الصور المؤقت الذي ينتجه مستشعر الكاميرا في الشكل 4:
يجب تدوير المخزن المؤقت بمقدار 270 درجة عكس عقارب الساعة لضبط اتجاه أداة الاستشعار (يُرجى الاطّلاع على قسم اتجاه الكاميرا أعلاه):
بعد ذلك، يتم تدوير المخزن المؤقت بزاوية 90 درجة إضافية عكس عقارب الساعة لمراعاة تدوير الجهاز، ما يؤدي إلى الاتجاه الصحيح لمعاينة الكاميرا في الشكل 4:
في ما يلي الكاميرا التي تم تدويرها إلى اليمين إلى الوضع الأفقي:
إليك مخزن الصور المؤقت:
يجب تدوير المخزن المؤقت بمقدار 270 درجة عكس عقارب الساعة لضبط اتجاه أداة الاستشعار:
بعد ذلك، يتم تدوير المخزن المؤقت بمقدار 270 درجة أخرى عكس اتجاه عقارب الساعة لمراعاة تدوير الجهاز:
الكاميرات الخلفية
عادةً ما يكون اتجاه أداة الاستشعار في الكاميرات الخلفية 90 درجة (كما يظهر من الجزء الخلفي للجهاز). عند توجيه معاينة الكاميرا، يتم تدوير مخزن الصور المؤقت لأداة الاستشعار في اتجاه عقارب الساعة بمقدار دوران أداة الاستشعار (بدلاً من عكس اتجاه عقارب الساعة مثل الكاميرات الأمامية)، ثم يتم تدوير مخزن الصور المؤقت عكس اتجاه عقارب الساعة بمقدار دوران الجهاز.
في ما يلي مخزن الصور المؤقت من أداة الاستشعار في الكاميرا في الشكل 12:
The buffer must be rotated 90 degrees clockwise to adjust for sensor orientation:
بعد ذلك، يتم تدوير المخزن المؤقت بمقدار 270 درجة عكس عقارب الساعة لمراعاة تدوير الجهاز:
نسبة العرض إلى الارتفاع
تتغيّر نسبة العرض إلى الارتفاع للشاشة عند تغيير اتجاه الجهاز، وكذلك عند طي الأجهزة القابلة للطي وفتحها، وعند تغيير حجم النوافذ في بيئات النوافذ المتعددة، وعند فتح التطبيقات على الشاشات الثانوية.
يجب توجيه مخزن الصور المؤقت لمستشعر الكاميرا وتغيير حجمه ليتطابق مع اتجاه عنصر واجهة المستخدم في عدسة الكاميرا ونسبة العرض إلى الارتفاع فيه، حيث يتغير اتجاه واجهة المستخدم ديناميكيًا، سواء تغيّر اتجاه الجهاز أم لا.
على أشكال الأجهزة الجديدة أو في بيئات النوافذ المتعددة أو الشاشات المتعددة، إذا كان تطبيقك يفترض أنّ معاينة الكاميرا لها نفس اتجاه الجهاز (عمودي أو أفقي)، قد يتم توجيه المعاينة بشكل غير صحيح أو تغيير حجمها بشكل غير صحيح أو كليهما.
في الشكل 16، افترض التطبيق خطأً أنّ الجهاز تم تدويره بمقدار 90 درجة عكس عقارب الساعة، وبالتالي تم تدوير المعاينة بالمقدار نفسه.
في الشكل 17، لم يضبط التطبيق نسبة العرض إلى الارتفاع لمخزن الصور المؤقت ليتمكّن من تغيير حجمه بشكل صحيح ليلائم الأبعاد الجديدة لعنصر واجهة المستخدم الخاص بمعاينة الكاميرا.
عادةً ما تواجه تطبيقات الكاميرا ذات الاتجاه الثابت مشاكل على الأجهزة القابلة للطي والأجهزة الأخرى ذات الشاشات الكبيرة، مثل أجهزة الكمبيوتر المحمول:
في الشكل 18، تظهر واجهة مستخدم تطبيق الكاميرا بشكل جانبي لأنّ اتجاه التطبيق يقتصر على الوضع العمودي فقط. يتم توجيه صورة عدسة الكاميرا بشكل صحيح بالنسبة إلى أداة استشعار الكاميرا.
وضع "بورتريه" مضمَّن
يمكن وضع تطبيقات الكاميرا التي لا تتيح وضع النوافذ المتعددة
(resizeableActivity="false") وتفرض قيودًا على
اتجاه الشاشة
(screenOrientation="portrait" أو
screenOrientation="landscape") في
وضع "بورتريه" على الأجهزة ذات الشاشات الكبيرة لتوجيه معاينة
الكاميرا بشكل صحيح.
يؤدي وضع "بورتريه" المضمّن إلى عرض التطبيقات التي تعمل في الوضع العمودي فقط في الاتجاه العمودي، حتى إذا كانت نسبة العرض إلى الارتفاع للشاشة هي الوضع الأفقي. يتم عرض التطبيقات التي تعمل في الوضع الأفقي فقط في وضع العرض الأفقي مع إضافة أشرطة سوداء على الجانبين، على الرغم من أنّ نسبة العرض إلى الارتفاع للشاشة هي الوضع العمودي. يتم تدوير صورة الكاميرا لتتلاءم مع واجهة مستخدم التطبيق، ثم يتم اقتصاصها لتتطابق مع نسبة العرض إلى الارتفاع لمعاينة الكاميرا، ثم يتم تغيير حجمها لملء المعاينة.
يتم تفعيل وضع "بورتريه" الداخلي عندما لا تتطابق نسبة العرض إلى الارتفاع لوحدة استشعار الصور في الكاميرا مع نسبة العرض إلى الارتفاع للنشاط الأساسي للتطبيق.
في الشكل 19، تم تدوير تطبيق الكاميرا الذي يعمل في الوضع العمودي فقط لعرض واجهة المستخدم بشكل عمودي على شاشة الكمبيوتر المحمول. يتم عرض التطبيق في وضع شاشة عريضة بسبب الاختلاف في نسبة العرض إلى الارتفاع بين التطبيق في الوضع العمودي والشاشة في الوضع الأفقي. تم تدوير صورة معاينة الكاميرا للتعويض عن تدوير واجهة مستخدم التطبيق (بسبب وضع "بورتريه" المضمّن)، وتم اقتصاص الصورة وتغيير حجمها لتناسب الاتجاه العمودي، ما يقلّل من مجال الرؤية.
التدوير والاقتصاص وتغيير الحجم
يتم تفعيل وضع "بورتريه" المضمّن لتطبيق كاميرا يعمل في الوضع العمودي فقط على شاشة ذات نسبة عرض إلى ارتفاع أفقية:
يتم عرض التطبيق في وضع "صندوق الرسائل" في الاتجاه العمودي:
يتم تدوير صورة الكاميرا بمقدار 90 درجة لضبط إعادة توجيه التطبيق:
يتم اقتصاص الصورة وفقًا لنسبة العرض إلى الارتفاع لمعاينة الكاميرا، ثم يتم تغيير حجمها لملء المعاينة (يتم تقليل مجال الرؤية):
على الأجهزة القابلة للطي، يمكن أن يكون اتجاه أداة استشعار الكاميرا عموديًا بينما تكون نسبة العرض إلى الارتفاع للشاشة أفقية:
بما أنّه يتم تدوير معاينة الكاميرا لضبط اتجاه أداة الاستشعار، يتم توجيه الصورة بشكل صحيح في عدسة الكاميرا، ولكن التطبيق الذي يعمل في الوضع العمودي فقط يظهر بشكل جانبي.
لا يحتاج وضع "بورتريه" المضمّن إلا إلى إضافة شريط أسود إلى التطبيق في الاتجاه العمودي لتوجيه التطبيق ومعاينة الكاميرا بشكل صحيح:
واجهة برمجة التطبيقات
اعتبارًا من الإصدار 12 من نظام التشغيل Android (المستوى 31 لواجهة برمجة التطبيقات)، يمكن للتطبيقات أيضًا التحكّم بشكل صريح في وضع "بورتريه" المضمّن من خلال السمة SCALER_ROTATE_AND_CROP للفئة CaptureRequest.
القيمة التلقائية هي SCALER_ROTATE_AND_CROP_AUTO، ما يتيح للنظام تفعيل وضع "بورتريه" المضمَّن.
SCALER_ROTATE_AND_CROP_90 هو سلوك وضع "بورتريه" المضمّن كما هو موضّح سابقًا.
لا تتوافق بعض الأجهزة مع بعض قيم SCALER_ROTATE_AND_CROP. للحصول على قائمة بالقيم المسموح بها، يُرجى الرجوع إلى CameraCharacteristics#SCALER_AVAILABLE_ROTATE_AND_CROP_MODES.
CameraX
تسهّل مكتبة Jetpack CameraX إنشاء عدسة كاميرا تتوافق مع اتجاه أداة الاستشعار وتدوير الجهاز.
يُنشئ عنصر التنسيق PreviewView معاينة للكاميرا،
ويتم تعديله تلقائيًا حسب اتجاه أداة الاستشعار وتدوير الجهاز وتغيير الحجم.
يحافظ PreviewView على نسبة العرض إلى الارتفاع لصورة الكاميرا من خلال تطبيق نوع المقياس FILL_CENTER الذي يضع الصورة في الوسط ولكن قد يقتصّها لتتطابق مع أبعاد PreviewView. لإضافة شريط أسود إلى صورة الكاميرا، اضبط نوع المقياس على FIT_CENTER.
للتعرّف على أساسيات إنشاء معاينة للكاميرا باستخدام PreviewView، يُرجى الاطّلاع على
تنفيذ معاينة.
للاطّلاع على نموذج كامل للتنفيذ، يُرجى مراجعة مستودع CameraXBasic على GitHub.
CameraViewfinder
على غرار حالة استخدام المعاينة، توفّر مكتبة CameraViewfinder مجموعة من الأدوات لتبسيط إنشاء معاينة الكاميرا. ولا تعتمد على CameraX Core، لذا يمكنك دمجها بسلاسة في قاعدة رموز Camera2 الحالية.
بدلاً من استخدام Surface مباشرةً، يمكنك استخدام التطبيق المصغّر CameraViewfinder لعرض خلاصة الكاميرا في Camera2.
يستخدم CameraViewfinder داخليًا إما TextureView أو SurfaceView لعرض خلاصة الكاميرا، ويطبّق عمليات التحويل المطلوبة عليها لعرض عدسة الكاميرا بشكل صحيح. يتضمن ذلك تصحيح نسبة العرض إلى الارتفاع
والحجم والتدوير.
لطلب السطح من الكائن CameraViewfinder، عليك إنشاء
ViewfinderSurfaceRequest.
يتضمّن هذا الطلب متطلبات دقة السطح ومعلومات جهاز الكاميرا من CameraCharacteristics.
يؤدي استدعاء requestSurfaceAsync() إلى إرسال الطلب إلى
موفّر السطح، وهو إما TextureView أو SurfaceView، ويحصل على
ListenableFuture من Surface.
يؤدي استدعاء markSurfaceSafeToRelease() إلى إشعار
موفّر السطح بأنّ السطح غير مطلوب ويمكن
إصدار الموارد ذات الصلة.
fun startCamera() {
val previewResolution = Size(width, height)
val viewfinderSurfaceRequest =
ViewfinderSurfaceRequest(previewResolution, characteristics)
val surfaceListenableFuture =
cameraViewfinder.requestSurfaceAsync(viewfinderSurfaceRequest)
Futures.addCallback(surfaceListenableFuture, object : FutureCallback<Surface> {
override fun onSuccess(surface: Surface) {
/* create a CaptureSession using this surface as usual */
}
override fun onFailure(t: Throwable) { /* something went wrong */ }
}, ContextCompat.getMainExecutor(context))
}
SurfaceView
SurfaceView هو نهج مباشر لإنشاء معاينة للكاميرا إذا كانت المعاينة لا تتطلب معالجة وليست متحركة.
يُجري SurfaceView تدويرًا تلقائيًا لذاكرة التخزين المؤقت لصور أداة استشعار الكاميرا لتتطابق مع
اتجاه العرض، مع مراعاة اتجاه أداة الاستشعار وتدوير الجهاز.
ومع ذلك، يتم تغيير حجم مخزن الصورة المؤقت ليتناسب مع أبعاد SurfaceView بدون
أي اعتبار لنسبة العرض إلى الارتفاع.
يجب التأكّد من أنّ نسبة العرض إلى الارتفاع لمخزن الصورة المؤقت تتطابق مع نسبة العرض إلى الارتفاع لـ SurfaceView، ويمكنك تحقيق ذلك من خلال تغيير حجم محتوى SurfaceView في طريقة onMeasure() للمكوّن:
(يتوفّر الرمز المصدر لـ computeRelativeRotation() في قسم التدوير النسبي أدناه).
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { val width = MeasureSpec.getSize(widthMeasureSpec) val height = MeasureSpec.getSize(heightMeasureSpec) val relativeRotation = computeRelativeRotation(characteristics, surfaceRotationDegrees) if (previewWidth > 0f && previewHeight > 0f) { /* Scale factor required to scale the preview to its original size on the x-axis. */ val scaleX = if (relativeRotation % 180 == 0) { width.toFloat() / previewWidth } else { width.toFloat() / previewHeight } /* Scale factor required to scale the preview to its original size on the y-axis. */ val scaleY = if (relativeRotation % 180 == 0) { height.toFloat() / previewHeight } else { height.toFloat() / previewWidth } /* Scale factor required to fit the preview to the SurfaceView size. */ val finalScale = min(scaleX, scaleY) setScaleX(1 / scaleX * finalScale) setScaleY(1 / scaleY * finalScale) } setMeasuredDimension(width, height) }
لمزيد من التفاصيل حول تنفيذ SurfaceView كمعاينة للكاميرا، يُرجى الاطّلاع على
اتجاهات الكاميرا.
TextureView
TextureView أقل أداءً من SurfaceView، ويتطلب
مزيدًا من العمل، ولكن TextureView يمنحك أقصى قدر من التحكم في معاينة
الكاميرا.
تعمل TextureView على تدوير مخزن الصور المؤقت لأداة الاستشعار استنادًا إلى اتجاه أداة الاستشعار، ولكنها لا تتعامل مع تدوير الجهاز أو تغيير حجم المعاينة.
يمكن ترميز تغيير الحجم والتدوير في تحويل مصفوفة.
لمعرفة كيفية تغيير حجم TextureView وتدويره بشكل صحيح، يُرجى الاطّلاع على مقالة إتاحة
الأسطح القابلة لتغيير الحجم في تطبيق الكاميرا.
التدوير النسبي
يشير الدوران النسبي لمستشعر الكاميرا إلى مقدار الدوران المطلوب لمحاذاة مخرجات مستشعر الكاميرا مع اتجاه الجهاز.
يتم استخدام التدوير النسبي من خلال مكوّنات مثل SurfaceView وTextureView
لتحديد عاملي قياس x وy لصورة المعاينة. ويُستخدم أيضًا لتحديد دوران مخزن الصور المؤقت لأداة الاستشعار.
تتيح الفئتان CameraCharacteristics وSurface احتساب الدوران النسبي لميزة الاستشعار في الكاميرا:
/** * Computes rotation required to transform the camera sensor output orientation to the * device's current orientation in degrees. * * @param characteristics The CameraCharacteristics to query for the sensor orientation. * @param surfaceRotationDegrees The current device orientation as a Surface constant. * @return Relative rotation of the camera sensor output. */ public fun computeRelativeRotation( characteristics: CameraCharacteristics, surfaceRotationDegrees: Int ): Int { val sensorOrientationDegrees = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION) ?: 0 // Reverse device orientation for back-facing cameras. val sign = if (characteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT ) 1 else -1 // Calculate desired orientation relative to camera orientation to make // the image upright relative to the device orientation. return (sensorOrientationDegrees - surfaceRotationDegrees * sign + 360) % 360 }
مقاييس النافذة
يجب عدم استخدام حجم الشاشة لتحديد أبعاد عدسة الكاميرا، فقد يكون تطبيق الكاميرا قيد التشغيل في جزء من الشاشة، إما في وضع النوافذ المتعددة على الأجهزة الجوّالة أو في وضع النوافذ العائمة على ChromeOS.
WindowManager#getCurrentWindowMetrics()
(تمت إضافتها في مستوى واجهة برمجة التطبيقات 30) تعرض حجم نافذة التطبيق بدلاً من
حجم الشاشة. توفّر طرق مكتبة Jetpack WindowManager
WindowMetricsCalculator#computeCurrentWindowMetrics()
وWindowInfoTracker#currentWindowMetrics()
دعمًا مشابهًا مع التوافق مع الأنظمة القديمة حتى مستوى واجهة برمجة التطبيقات 14.
التدوير بمقدار 180 درجة
إنّ تدوير الجهاز بزاوية 180 درجة (على سبيل المثال، من الوضع الطبيعي إلى الوضع الطبيعي المقلوب) لا يؤدي إلى تشغيل دالة الاستدعاء onConfigurationChanged(). نتيجةً لذلك، قد تظهر معاينة الكاميرا رأسًا على عقب.
لرصد دوران بزاوية 180 درجة، يمكنك تنفيذ
DisplayListener والتحقّق من دوران الجهاز من خلال استدعاء
Display#getRotation() في دالة الاستدعاء
onDisplayChanged().
مراجع حصرية
قبل الإصدار Android 10، كان النشاط المرئي في أعلى الشاشة فقط في بيئة نوافذ متعددة في الحالة RESUMED. كان هذا مربكًا للمستخدمين لأن
النظام لم يقدم أي إشارة إلى النشاط الذي تم استئنافه.
قدّم نظام التشغيل Android 10 (المستوى 29 لواجهة برمجة التطبيقات) ميزة الاستئناف المتعدّد التي تكون فيها جميع الأنشطة المرئية
في الحالة RESUMED. Visible activities can still enter the PAUSED
state if, for example, a transparent activity is on top of the activity or
the activity is not focusable, such as in picture-in-picture mode (see
Picture-in-picture support).
يجب أن يتيح التطبيق الذي يستخدم الكاميرا أو الميكروفون أو أي مورد حصري أو أحادي في المستوى 29 من واجهة برمجة التطبيقات أو المستويات الأعلى ميزة الاستئناف المتعدّد. على سبيل المثال، إذا أرادت ثلاثة أنشطة مستأنفة استخدام الكاميرا، فسيتمكن نشاط واحد فقط من الوصول إلى هذا المورد الحصري. يجب أن ينفّذ كل نشاط دالة الاستدعاء onDisconnected() ليبقى على عِلم بالوصول الاستباقي إلى الكاميرا من خلال نشاط ذي أولوية أعلى.
لمزيد من المعلومات، يُرجى الاطّلاع على الاستئناف المتعدّد.
مراجع إضافية
- للحصول على نموذج Camera2، يمكنك الاطّلاع على تطبيق Camera2Basic على GitHub.
- للتعرّف على حالة استخدام معاينة CameraX، يُرجى الاطّلاع على تنفيذ معاينة في CameraX.
- للاطّلاع على نموذج تنفيذ معاينة الكاميرا في CameraX، يُرجى مراجعة مستودع CameraXBasic على GitHub.
- للحصول على معلومات حول معاينة الكاميرا على ChromeOS، يُرجى الاطّلاع على اتجاهات الكاميرا.
- لمزيد من المعلومات حول تطوير التطبيقات للأجهزة القابلة للطي، يُرجى الاطّلاع على التعرّف على الأجهزة القابلة للطي.