android.media.projection
تمكّنك واجهات برمجة التطبيقات التي تم تقديمها في Android 5 (المستوى 21 من واجهة برمجة التطبيقات) من تسجيل المحتوى
شاشة الجهاز كبث وسائط يمكنك تشغيله أو تسجيله أو إرساله إليه
على الأجهزة الأخرى، مثل أجهزة التلفزيون
يقدّم Android 14 (المستوى 34 من واجهة برمجة التطبيقات) ميزة مشاركة شاشة التطبيقات، ما يتيح للمستخدمين مشاركة نافذة تطبيق واحدة بدلاً من شاشة الجهاز بأكملها بغض النظر عن وضع النافذة. تستبعد مشاركة شاشة التطبيق شريط الحالة وشريط التنقل والإشعارات وعناصر واجهة مستخدم النظام الأخرى من الشاشة المشتركة، بما في ذلك عند استخدام ميزة "مشاركة شاشة التطبيق" لالتقاط صورة تطبيق في وضع ملء الشاشة تتم مشاركة محتوى التطبيق المحدَّد فقط.
تضمن مشاركة شاشة التطبيق خصوصية المستخدم وتزيد إنتاجية المستخدم تحسين تعدد المهام من خلال تمكين المستخدمين من تشغيل تطبيقات متعددة مع تقييد مشاركة المحتوى مع تطبيق واحد فقط.
ثلاثة تمثيلات للعرض
يلتقط عرض الوسائط محتويات شاشة الجهاز أو نافذة التطبيق
ثم عرض الصورة التي تم التقاطها على شاشة افتراضية تعرض الصورة على
Surface
![يتم عرض شاشة الجهاز الحقيقية على شاشة افتراضية. محتويات
شاشة عرض افتراضية تمت كتابتها على مستوى "سطح" الذي يوفّره التطبيق.](https://developer.android.com/static/media/images/grow/media-projection.png?authuser=5&hl=ar)
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 من واجهة برمجة التطبيقات)، عند عرض المحتوى الذي تم التقاطه على يعمل النظام على قياس المحتوى بشكل موحد، مع الحفاظ على نسبة العرض إلى الارتفاع بحيث يكون كلا بُعدي المحتوى (العرض والارتفاع) متساويين أو أقل من الأبعاد المقابلة للسطح. ثم يتم تجميع المحتوى الذي تم التقاطه في منتصف السطح.
يعمل نهج توسيع نطاق الإصدار 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()
.
من مكتبة Jetpack WindowManager
.
يمكنك استدعاء طريقة WindowMetrics
getBounds()
لمعرفة عرض شاشة الجهاز وارتفاعها.
تغييرات الحجم
يمكن أن يتغير حجم عرض الوسائط عند تدوير الجهاز أو اختيار المستخدم نافذة تطبيق كمنطقة للالتقاط في مشاركة شاشة التطبيق. قد يتم عرض الوسائط مُعدّة للعرض على شاشة عريضة أفقيًا إذا كان المحتوى الذي تم التقاطه حجم مختلف عن الحد الأقصى لمقاييس النافذة التي تم الحصول عليها عند تشغيل الوسائط تم إعداد الإسقاط.
لضمان توافق عرض الوسائط بدقة مع حجم اللقطة
المحتوى لأي منطقة يتم التقاطها وعبر عمليات تدوير الأجهزة، استخدم
استدعاء "onCapturedContentResize()
" لتغيير حجم الالتقاط. (للمزيد من
يمكنك الاطّلاع على قسم التخصيص الذي يليه).
التخصيص
يمكن لتطبيقك تخصيص تجربة عرض الوسائط للمستخدم من خلال ما يلي:
MediaProjection.Callback
واجهات برمجة التطبيقات:
onCapturedContentVisibilityChanged()
: لتمكين التطبيق المضيف (التطبيق الذي بدأ عرض الوسائط) من عرض أو إخفاء المحتوى المشترك.يمكنك استخدام رد الاتصال هذا لتخصيص واجهة المستخدم لتطبيقك استنادًا إلى ما إذا كان قد تم الحصول على تكون المنطقة مرئية للمستخدم. على سبيل المثال، إذا كان تطبيقك مرئيًا لخدمة المستخدم ويعرض المحتوى الذي تم تصويره ضمن واجهة مستخدم التطبيق التطبيق الذي تم التقاطه مرئي أيضًا للمستخدم (كما هو موضح من خلال هذا رد الاتصال)، فإن المستخدم يرى نفس المحتوى مرتين. استخدام رد الاتصال للتحديث واجهة المستخدم في تطبيقك لإخفاء المحتوى الذي تم التقاطه وإخلاء مساحة تصميم في محتوى آخر.
onCapturedContentResize()
: لتمكين التطبيق المضيف من تغيير حجم عرض الوسائط على الجهاز الافتراضي العرض والوسائطSurface
استنادًا إلى حجم اللقطة ومنطقة العرض.يتم تشغيله عند تسجيل المحتوى، سواء كان نافذة تطبيق واحد أو ممتلئ شاشة الجهاز — يتغير الحجم (بسبب تدوير الجهاز أو التقاط الصورة تطبيقك في وضع نافذة مختلف). استخدم واجهة برمجة التطبيقات هذه لتغيير حجم مساحة العرض والشاشة الافتراضية لضمان تطابق نسبة العرض إلى الارتفاع التي تم التقاطها المحتوى ولا يكون الالتقاط غير مُعدّ للعرض على شاشة عريضة أفقيًا.
استرداد الموارد
يجب أن يسجّل تطبيقك MediaProjection
.
onStop()
لمعاودة الاتصال ليتم إبلاغك عندما تتوقف جلسة عرض الوسائط وتصبح
غير صالح. عند إيقاف الجلسة، يجب أن يصدر تطبيقك الموارد التي
التي تحملها، مثل الشاشة الافتراضية وسطح العرض. توقف
لا يمكن لجلسة عرض الوسائط إنشاء شاشة افتراضية جديدة، حتى إذا
لم يسبق أن أنشأ تطبيقك شاشة افتراضية لعرض الوسائط هذا.
ويتم استدعاء هذه الاستدعاءات عند انتهاء عرض الوسائط، إما بسبب إيقاف المستخدم الجلسة يدويًا، أو لأن النظام يوقف الجلسة لسبب ما.
إذا لم يسجّل تطبيقك معاودة الاتصال، أي مكالمة إلى createVirtualDisplay()
الرميات
IllegalStateException
.
إيقاف
يتيح الإصدار 14 من نظام التشغيل Android أو الإصدارات الأحدث مشاركة شاشة التطبيقات تلقائيًا. كل الوسائط للمستخدمين خيار مشاركة نافذة التطبيق أو الشاشة بأكملها.
يمكن لتطبيقك إيقاف مشاركة شاشة التطبيق من خلال الاتصال على
طريقة واحدة (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();
مصادر إضافية
لمزيد من المعلومات حول عرض الوسائط، راجع التقاط تشغيل الفيديو والصوت: