تتيح لك واجهات برمجة التطبيقات android.media.projection
المقدَّمة في Android 5 (المستوى 21 لواجهة برمجة التطبيقات) تسجيل محتوى شاشة الجهاز
كبث وسائط يمكنك تشغيله أو تسجيله أو بثّه على
أجهزة أخرى، مثل أجهزة التلفزيون.
يوفّر Android 14 (المستوى 34 من واجهة برمجة التطبيقات) ميزة مشاركة شاشة التطبيقات التي تتيح للمستخدمين مشاركة نافذة تطبيق واحدة بدلاً من مشاركة شاشة الجهاز بأكملها بغض النظر عن وضع النوافذ. تستبعد ميزة مشاركة شاشة التطبيق شريط الحالة وشريط التنقل والإشعارات وعناصر واجهة مستخدم النظام الأخرى من الشاشة المشتركة، حتى عند استخدام مشاركة شاشة التطبيق لتسجيل تطبيق في وضع ملء الشاشة. تتم مشاركة محتوى التطبيق المحدد فقط.
تضمن ميزة "مشاركة شاشة التطبيق" خصوصية المستخدم وتزيد من إنتاجية المستخدمين وتعزّز تنفيذ مهام متعددة من خلال السماح للمستخدمين بتشغيل تطبيقات متعددة مع حصر مشاركة المحتوى بتطبيق واحد فقط.
ثلاثة تمثيلات للعرض
يلتقط عرض الوسائط محتويات شاشة جهاز أو نافذة تطبيق، ثم يعرض الصورة الملتقطة على شاشة افتراضية تعرض الصورة على Surface
.
ويوفّر التطبيق عنصر Surface
عن طريق السمتَين
MediaRecorder
أو
SurfaceTexture
أو
ImageReader
الذي تستهلك
محتوى الشاشة التي تم التقاطها ويتيح لك إدارة الصور المعروضة
على Surface
في الوقت الفعلي. يمكنك حفظ الصور كتسجيل أو إرسالها
إلى تلفزيون أو جهاز آخر.
العرض الحقيقي
ابدأ جلسة عرض الوسائط من خلال الحصول على رمز مميز يمنح تطبيقك القدرة على التقاط محتوى شاشة الجهاز أو نافذة التطبيق. يتم تمثيل الرمز المميّز بمثيل من الفئة MediaProjection
.
استخدِم طريقة getMediaProjection()
في خدمة نظام
MediaProjectionManager
لإنشاء مثيل MediaProjection
عند بدء نشاط جديد. ابدأ النشاط باستخدام هدف من طريقة createScreenCaptureIntent()
لتحديد عملية تصوير الشاشة:
Kotlin
val mediaProjectionManager = getSystemService(MediaProjectionManager::class.java) var mediaProjection : MediaProjection val startMediaProjection = registerForActivityResult( StartActivityForResult() ) { result -> if (result.resultCode == RESULT_OK) { mediaProjection = mediaProjectionManager .getMediaProjection(result.resultCode, result.data!!) } } startMediaProjection.launch(mediaProjectionManager.createScreenCaptureIntent())
Java
final MediaProjectionManager mediaProjectionManager = getSystemService(MediaProjectionManager.class); final MediaProjection[] mediaProjection = new MediaProjection[1]; ActivityResultLauncher<Intent> startMediaProjection = registerForActivityResult( new StartActivityForResult(), result -> { if (result.getResultCode() == Activity.RESULT_OK) { mediaProjection[0] = mediaProjectionManager .getMediaProjection(result.getResultCode(), result.getData()); } } ); startMediaProjection.launch(mediaProjectionManager.createScreenCaptureIntent());
الشاشة الافتراضية
يكون محور عرض الوسائط هو الشاشة الافتراضية التي تنشئها
من خلال استدعاء
createVirtualDisplay()
على مثيل MediaProjection
:
Kotlin
virtualDisplay = mediaProjection.createVirtualDisplay( "ScreenCapture", width, height, screenDensity, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, surface, null, null)
Java
virtualDisplay = mediaProjection.createVirtualDisplay( "ScreenCapture", width, height, screenDensity, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, surface, null, null);
تحدّد المعلمتان width
وheight
أبعاد العرض الافتراضي. وللحصول على قيم للعرض والارتفاع، استخدِم واجهات برمجة تطبيقات WindowMetrics
التي تم تقديمها في Android 11 (المستوى 30 من واجهة برمجة التطبيقات). (لمعرفة التفاصيل، يُرجى الاطّلاع على قسم حجم عرض الوسائط.)
مساحات العرض
اضبط حجم سطح عرض الوسائط لإنتاج مخرجات بالدقة المناسبة. جعل السطح كبيرًا (منخفض الدقة) لبث محتوى الشاشة على أجهزة التلفزيون أو شاشات الكمبيوتر وصغير (دقة عالية) لتسجيل شاشة الجهاز
بدءًا من نظام Android 12L (المستوى 32 من واجهة برمجة التطبيقات)، عند عرض المحتوى الذي تم تسجيله على السطح، يضبط النظام المحتوى بشكل موحد مع الحفاظ على نسبة العرض إلى الارتفاع بحيث يكون كلا بُعدَي المحتوى (العرض والارتفاع) مساويًا للأبعاد المقابلة للسطح أو أقل منه. بعد ذلك، يتم توسيط المحتوى الذي تم التقاطه على السطح.
يعمل أسلوب تحجيم Android 12L على تحسين بث الشاشة على أجهزة التلفزيون وشاشات العرض الكبيرة الأخرى من خلال زيادة حجم صورة السطح مع ضمان نسبة العرض إلى الارتفاع المناسبة.
إذن الخدمة التي تعمل في المقدّمة
إذا كان تطبيقك يستهدف الإصدار 14 من نظام التشغيل Android أو الإصدارات الأحدث، يجب أن يتضمّن بيان التطبيق
بيان الأذونات الخاص بنوع
خدمة mediaProjection
التي تعمل في المقدّمة:
<manifest ...>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />
<application ...>
<service
android:name=".MyMediaProjectionService"
android:foregroundServiceType="mediaProjection"
android:exported="false">
</service>
</application>
</manifest>
ابدأ خدمة عرض الوسائط بإجراء مكالمة إلى الرقم startForeground()
.
إذا لم تحدّد نوع الخدمة التي تعمل في المقدّمة في الطلب، سيتم ضبط النوع تلقائيًا على عدد صحيح بتعلّق أنواع الخدمات التي تعمل في المقدّمة المحدّدة في البيان. إذا لم يحدِّد البيان أي أنواع من الخدمات، سيطرح النظام MissingForegroundServiceTypeException
.
موافقة المستخدم
يجب أن يطلب تطبيقك موافقة المستخدم قبل كل جلسة عرض وسائط. الجلسة هي استدعاء واحد للرمز createVirtualDisplay()
. يجب استخدام رمز MediaProjection
مرة واحدة فقط لإجراء المكالمة.
في نظام التشغيل Android 14 أو الإصدارات الأحدث، تعرض طريقة createVirtualDisplay()
الخطأ
SecurityException
في حال تنفيذ
أحد الإجراءَين التاليَين في تطبيقك:
- تمرير نسخة من
Intent
تم إرجاعها منcreateScreenCaptureIntent()
إلىgetMediaProjection()
أكثر من مرة - يتم استدعاء
createVirtualDisplay()
أكثر من مرة على مثيلMediaProjection
نفسه
حجم عرض الوسائط
يمكن لعرض الوسائط التقاط عرض الجهاز بالكامل أو نافذة التطبيق بغض النظر عن وضع النافذة.
الحجم المبدئي
من خلال عرض الوسائط بملء الشاشة، يجب أن يحدد تطبيقك حجم شاشة الجهاز. في ميزة مشاركة شاشة التطبيق، لن يتمكن تطبيقك من تحديد حجم الشاشة التي تم التقاطها إلى أن يختار المستخدم منطقة الالتقاط. إذًا، يكون الحجم الأولي لأي إسقاط وسائط هو حجم شاشة الجهاز.
يمكنك استخدام طريقة النظام الأساسي WindowManager
getMaximumWindowMetrics()
لعرض عنصر
WindowMetrics
لشاشة الجهاز حتى إذا كان تطبيق مضيف عرض الوسائط في وضع النوافذ المتعددة، إذ لا يشغل سوى جزء من الشاشة.
لضمان التوافق مع المستوى 14 لواجهة برمجة التطبيقات، استخدِم الإجراء WindowMetricsCalculator
computeMaximumWindowMetrics()
من مكتبة WindowManager
Jetpack.
عليك استدعاء طريقة WindowMetrics
getBounds()
للحصول على عرض وارتفاع شاشة الجهاز.
تغييرات الحجم
وقد يتغيّر حجم عرض الوسائط عند تدوير الجهاز أو عندما يختار المستخدم نافذة تطبيق كمنطقة الالتقاط في ميزة "مشاركة شاشة التطبيق". قد يظهر عرض الوسائط مُعدّ للعرض على شاشة عريضة أفقيًا إذا كان حجم المحتوى الذي تم التقاطه مختلفًا عن الحدّ الأقصى لمقاييس النوافذ التي تم الحصول عليها عند إعداد عرض الوسائط.
لضمان أن يتماشى عرض الوسائط بدقة مع حجم المحتوى الذي تم التقاطه
لأي منطقة تم التقاطها وعلى مستوى عمليات تدوير الجهاز، يمكنك استخدام
رد الاتصال onCapturedContentResize()
لتغيير حجم الالتقاط. (لمزيد من المعلومات، راجع قسم التخصيص الذي يتبعه).
التخصيص
يمكن لتطبيقك تخصيص تجربة المستخدم لعرض الوسائط باستخدام واجهات برمجة تطبيقات
MediaProjection.Callback
التالية:
onCapturedContentVisibilityChanged()
: يفعّل التطبيق المضيف (التطبيق الذي بدأ عرض الوسائط) لإظهار المحتوى المشترَك أو إخفائه.يمكنك استخدام معاودة الاتصال هذه لتخصيص واجهة المستخدم لتطبيقك استنادًا إلى ما إذا كانت المنطقة التي تم التقاطها مرئية للمستخدم أم لا. على سبيل المثال، إذا كان تطبيقك مرئيًا للمستخدم وكان يعرض المحتوى الذي تم التقاطه في واجهة مستخدم التطبيق، وكان التطبيق الذي تم التقاطه مرئيًا أيضًا للمستخدم (كما هو موضّح من خلال معاودة الاتصال هذه)، سيرى المستخدم المحتوى نفسه مرتين. استخدِم ميزة معاودة الاتصال لتحديث واجهة المستخدم الخاصة بتطبيقك بهدف إخفاء المحتوى الذي تم التقاطه وإخلاء مساحة في التطبيق للمحتوى الآخر.
onCapturedContentResize()
: تفعيل التطبيق المضيف لتغيير حجم عرض الوسائط على شاشة العرض الافتراضية وعرض الوسائطSurface
بناءً على حجم منطقة العرض التي تم التقاطها.يتم تشغيله عندما يتغيّر حجم المحتوى الذي تم التقاطه، سواء نافذة تطبيق واحدة أو شاشة كاملة للجهاز، (بسبب تدوير الجهاز أو دخول التطبيق الذي تم التقاطه إلى وضع نافذة مختلف). استخدِم واجهة برمجة التطبيقات هذه لتغيير حجم الشاشة الافتراضية والسطح للتأكّد من تطابُق نسبة العرض إلى الارتفاع مع المحتوى الذي تم التقاطه، وأنّه لا يتم عرض اللقطة داخل إطار مُعدّ للعرض على شاشة عريضة أفقيًا.
استرداد الموارد
يجب أن يسجِّل تطبيقك معاودة الاتصال بـ MediaProjection
onStop()
لإطلاق الموارد التي يحتفظ بها التطبيق، مثل الشاشة الافتراضية
وسطح العرض.
ويتم استدعاء معاودة الاتصال عندما ينتهي عرض الوسائط أو عندما لا يمنح المستخدم موافقته على متابعة جلسة الالتقاط.
إذا لم يسجِّل تطبيقك معاودة الاتصال ولم يوافق المستخدم على
جلسة عرض الوسائط، يتم طرح طلبات createVirtualDisplay()
بحقل
IllegalStateException
.
إيقاف
يعمل نظام التشغيل Android 14 أو الإصدارات الأحدث على تفعيل ميزة مشاركة شاشة التطبيقات تلقائيًا. كل جلسة عرض وسائط تمنح المستخدمين خيار مشاركة نافذة تطبيق أو الشاشة بأكملها.
يمكن لتطبيقك إيقاف ميزة "مشاركة شاشة التطبيق" من خلال استدعاء طريقة
createScreenCaptureIntent(MediaProjectionConfig)
باستخدام وسيطة MediaProjectionConfig
التي تم عرضها من مكالمة إلى
createConfigForDefaultDisplay()
.
إنّ الاستدعاء إلى createScreenCaptureIntent(MediaProjectionConfig)
مع الوسيطة MediaProjectionConfig
التي يتم عرضها من استدعاء إلى createConfigForUserChoice()
هو نفسه
السلوك التلقائي، أي استدعاء للرمز createScreenCaptureIntent()
.
التطبيقات التي يمكن تغيير حجمها
احرِص دائمًا على تغيير حجم تطبيقات عرض الوسائط (resizeableActivity="true"
). وتتيح التطبيقات التي يمكن تغيير حجمها
التغييرات في إعدادات الجهاز ووضع النوافذ المتعددة (يُرجى الاطّلاع على
إتاحة النوافذ المتعددة).
إذا لم يكن حجم التطبيق قابلاً لتغيير الحجم، عليه الاستعلام عن حدود العرض من سياق النافذة واستخدام getMaximumWindowMetrics()
لاسترداد WindowMetrics
للحد الأقصى لمساحة العرض المتاحة للتطبيق، وذلك على النحو التالي :
Kotlin
val windowContext = context.createWindowContext(context.display!!, WindowManager.LayoutParams.TYPE_APPLICATION, null) val projectionMetrics = windowContext.getSystemService(WindowManager::class.java) .maximumWindowMetrics
Java
Context windowContext = context.createWindowContext(context.getDisplay(), WindowManager.LayoutParams.TYPE_APPLICATION, null); WindowMetrics projectionMetrics = windowContext.getSystemService(WindowManager.class) .getMaximumWindowMetrics();
مراجع إضافية
لمزيد من المعلومات حول عرض الوسائط، يُرجى الاطّلاع على التقاط الفيديو وتشغيل الصوت.