يمكّنك الإجراء التالي من تحويل تطبيق إرسال Android من Cast SDK v2 باستخدام CCL إلى CAF. تم تنفيذ جميع وظائف CCL في CAF، لذلك بعد الترحيل، لن تحتاج إلى استخدام CCL.
تستخدم حزمة تطوير البرامج (SDK) لمُرسِل CAF في Cast CastCast لإدارة GoogleAPIClient نيابةً عنك. يُدير CastContext دورات الحياة والأخطاء ومعاودة الاتصال، ما يسهِّل إلى حد كبير تطوير تطبيق Cast.
المقدمة
- نظرًا لتأثر تصميم مرسل CAF بمكتبة Cast Companion Library، فإن الترحيل من CCL إلى مرسل CAF يتضمن في الغالب تعيينات فردية للفئات وأساليبها.
- لا يزال مُرسل CAF موزعًا كجزء من خدمات Google Play باستخدام مدير Android SDK.
- وتكون الحزم الجديدة (
com.google.android.gms.cast.framework.*
) التي تمت إضافتها إلى مرسِل CAF، ذات وظائف مشابهة لوظيفة CCL، مسؤولة عن الالتزام بقائمة التحقّق من تصميم Google Cast. - يوفر CAF Sender أدوات تتوافق مع متطلبات Cast UX، وتشبه هذه الأدوات الأدوات التي تقدمها CCL.
- يوفر CAF Sender استدعاءات غير متزامنة تشبه حالات CCL، لتتبع الحالات والحصول على البيانات. بخلاف CCL، لا يوفر CAF Sender أي عمليات تنفيذ مستقلة لطرق الواجهة المتنوعة.
في الأقسام التالية، سنركز بشكل أساسي على التطبيقات التي تركز على الفيديو استنادًا إلى VideoCastManager في CCL، ولكن في كثير من الحالات، تنطبق المفاهيم نفسها على DataCastManager أيضًا.
العناصر التابعة
لدى CCL وCAF التبعيات نفسها في مكتبة دعم AppCompat ومكتبة دعم MediaRouter v7 وخدمات Google Play. ومع ذلك، فإن الفرق هو أن CAF يعتمد على إطار عمل الإرسال الجديد المتاح في خدمات Google Play الإصدار 9.2.0 أو إصدار أحدث.
في ملف build.gradle، أزل التبعيات على
com.google.android.gms:play-services-cast
و
com.google.android.libraries.cast.companionlibrary:ccl
،
ثم أضف إطار عمل الإرسال الجديد:
dependencies {
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:mediarouter-v7:23.4.0'
compile 'com.google.android.gms:play-services-cast-framework:9.4.0'
}
يمكنك أيضًا إزالة البيانات الوصفية لخدمة Google Play:
<meta‐data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version"/>
يتم تلقائيًا دمج أي خدمات وأنشطة وموارد تشكّل جزءًا من CAF في ملف بيان التطبيق وموارده.
الحد الأدنى لإصدار Android SDK الذي يدعمه CAF هو 9 (Gingerbread)؛ الحد الأدنى لإصدار SDK لنظام Android CCL هو 10.
يوفّر CCL طريقة سهلة،
BaseCastManager.checkGooglePlayServices(activity)
، للتحقق من توفر إصدار متوافق من خدمات Google Play على الجهاز. ولا يوفر CAF هذا
كجزء من تطبيق Cast SDK. اتَّبِع الإجراء
التأكُّد من أنّ الأجهزة تتضمّن حِزمة APK لخدمات Google Play
للتأكُّد من تثبيت حِزمة APK الصحيحة لخدمات Google Play على جهاز المستخدم لأنّ التحديثات قد لا تصل فورًا إلى جميع المستخدمين.
لا يزال يتعين عليك استخدام متغير من Theme.AppCompat لمظهر التطبيق.
الإعداد
بالنسبة إلى CCL، كان مطلوب استدعاء VideoCastManager.initialize()
في طريقة onCreate()
من مثيلات التطبيقات. يجب إزالة هذا المنطق من رمز فئة التطبيق.
في CAF، يجب أيضًا إجراء خطوة تهيئة صريحة لإطار الإرسال. ويتضمن هذا إعداد CastContext
سينغلتون، باستخدام OptionsProvider
المناسب لتحديد معرّف تطبيق المستلم وأي خيارات عامة أخرى. يلعب CastContext
دورًا مشابهًا لدور CCL
VideoCastManager
من خلال توفير أغنية فردية يتفاعل معها العملاء.
إنّ OptionsProvider
مشابه لـ CastConfiguration
الخاصّ بـ CCL
ليتيح لك ضبط ميزات إطار عمل Cast.
إذا كانت قيمة CCL CastConfiguration.Builder
الحالية تبدو كما يلي:
VideoCastManager.initialize(
getApplicationContext(),
new CastConfiguration.Builder(context.getString(R.string.app_id))
.enableWifiReconnection()
.enableAutoReconnect()
.build());
ثم في CAF، سيبدو CastOptionsProvider
التالي باستخدام CastOptions.Builder
مشابهًا:
public class CastOptionsProvider implements OptionsProvider {
@Override
public CastOptions getCastOptions(Context context) {
return new CastOptions.Builder()
.setReceiverApplicationId(context.getString(R.string.app_id))
.build();
}
@Override
public List<SessionProvider> getAdditionalSessionProviders(
Context context) {
return null;
}
}
ألق نظرة على نموذج تطبيق للحصول على التنفيذ الكامل لخيارات الخيارات.
أعلن عن OptionsProvider ضمن العنصر "application" ضمن ملف AndroidManifest.xml:
<application>
...
<meta-data
android:name=
"com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
android:value="com.google.sample.cast.refplayer.CastOptionsProvider"
/>
</application>
إعداد CastContext
ببطء في كل طريقة onCreate
Activity
(وليس مثيل Application
):
private CastContext mCastContext;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.video_browser);
setupActionBar();
mCastContext = CastContext.getSharedInstance(this);
}
للدخول إلى CastContext
Singleton، استخدم:
mCastContext = CastContext.getSharedInstance(this);
رصد الأجهزة
يجب إزالة VideoCastManager
incrementUiCounter
وdecrementUiCounter
من CCL
من طريقتي onResume
وonPause
من Activities
.
في CAF، تبدأ عملية الاكتشاف وتوقفها تلقائيًا إطار الصورة عندما يظهر التطبيق في المقدّمة وينتقل إلى الخلفية على التوالي.
زر الإرسال ومربع حوار الإرسال
وكما هو الحال مع CCL، يتم توفير هذه المكونات من خلال مكتبة دعم MediaRouter v7.
لا يزال زر الإرسال قيد التنفيذ بواسطة MediaRouteButton
ويمكن إضافته إلى نشاطك (باستخدام ActionBar
أو Toolbar
)، كعنصر في القائمة.
إعلان MediaRouteActionProvider
في قائمة XML هو نفسه
مع CCL:
<item
android:id="@+id/media_route_menu_item"
android:title="@string/media_route_menu_title"
app:actionProviderClass="android.support.v7.app.MediaRouteActionProvider"
app:showAsAction="always"/>
كما هو الحال مع CCL، يمكنك إلغاء طريقة onCreateOptionMenu() لكل نشاط، ولكن بدلاً من استخدام CastManager.addMediaRouterButton، يمكنك استخدام CastButtonfactory التابع لـ CAF لتوصيل إطار عمل MediaRouteButton بإطار عمل Cast:
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.browse, menu);
CastButtonFactory.setUpMediaRouteButton(getApplicationContext(),
menu,
R.id.media_route_menu_item);
return true;
}
التحكّم في الجهاز
وكما هو الحال مع CCL، يتم التعامل مع التحكم في الأجهزة إلى حد كبير بواسطة إطار العمل في CAF.
لا يحتاج تطبيق المُرسِل إلى الاتصال (وعدم محاولة المعالجة) الاتصال بالجهاز وإطلاق تطبيق المُستلِم باستخدام GoogleApiClient
.
يتم الآن تمثيل التفاعل بين المُرسِل والمُستلِم على أنه "جلسة". يعالج الصف SessionManager
دورة الحياة ويبدأ الجلسات ويوقفها تلقائيًا بناءً على إيماءات المستخدم: تبدأ الجلسة عندما يحدد المستخدم جهاز البث في مربع حوار البث، وتنتهي عندما ينقر المستخدم على الزر "إيقاف الإرسال" في مربّع الحوار "إرسال" أو عندما يُنهي تطبيق المُرسِل نفسه.
في CCL، يجب تمديد الفئة VideoCastConsumerImpl
لتتبع حالة جلسة الإرسال.
private final VideoCastConsumer mCastConsumer = new VideoCastConsumerImpl() {
public void onApplicationConnected(ApplicationMetadata appMetadata,
String sessionId,
boolean wasLaunched) {}
public void onDisconnectionReason(int reason) {}
public void onDisconnected() {}
}
في CAF، يمكن إشعار تطبيق المُرسِل بأحداث دورة الحياة من خلال تسجيل SessionManagerListener
في SessionManager
. تحدد استدعاءات
SessionManagerListener طرق معاودة الاتصال لجميع أحداث مراحل النشاط في الجلسة.
يتم تعيين الطرق SessionManagerListener
التالية من واجهة VideoCastConsumer
CCL:
VideoCastConsumer.onApplicationConnected
->SessionManagerListener.onSessionStarted
VideoCastConsumer.onDisconnected
->SessionManagerListener.onSessionEnded
حدِّد فئة تستخدم واجهة SessionManagerListener
وانقل المنطق VideoCastConsumerImpl
إلى طرق المطابقة:
private class CastSessionManagerListener implements SessionManagerListener<CastSession> {
public void onSessionEnded(CastSession session, int error) {}
public void onSessionStarted(CastSession session, String sessionId) {}
public void onSessionEnding(CastSession session) {}
...
}
يمثل الصف CastSession
جلسة مع جهاز بث. تتوفر في الصف طرق
للتحكّم في مستوى صوت الجهاز وكتم الصوت، وهو ما يحدث في CCL في
BaseCastManager
.
بدلاً من استخدام CCL VideoCastManager
لإضافة مستهلك:
VideoCastManager.getInstance().addVideoCastConsumer(mCastConsumer);
سجِّل الآن SessionManagerListener
:
mCastSessionManager =
CastContext.getSharedInstance(this).getSessionManager();
mCastSessionManagerListener = new CastSessionManagerListener();
mCastSessionManager.addSessionManagerListener(mCastSessionManagerListener,
CastSession.class);
لإيقاف الاستماع إلى الأحداث في CCL:
VideoCastManager.getInstance().removeVideoCastConsumer(mCastConsumer);
يمكنك الآن استخدام SessionManager
لإيقاف الاستماع إلى أحداث الجلسات:
mCastSessionManager.removeSessionManagerListener(mCastSessionManagerListener,
CastSession.class);
لقطع الاتصال بجهاز البث بشكل صريح، استعانت CCL بما يلي:
VideoCastManager.disconnectDevice(boolean stopAppOnExit,
boolean clearPersistedConnectionData,
boolean setDefaultRoute)
بالنسبة إلى CAF، استخدم SessionManager
:
CastContext.getSharedInstance(this).getSessionManager()
.endCurrentSession(true);
لتحديد ما إذا كان المُرسِل متصلاً بالمستلِم، يقدّم CCL
VideoCastManager.getInstance().isConnected()
، ولكن في CAF استخدم
SessionManager
:
public boolean isConnected() {
CastSession castSession = CastContext.getSharedInstance(mAppContext)
.getSessionManager()
.getCurrentCastSession();
return (castSession != null && castSession.isConnected());
}
في CAF، يستمر إرسال إشعارات تغيير مستوى الصوت/كتم الصوت عبر طرق
معاودة الاتصال في Cast.Listener
، ويتم تسجيل هؤلاء المستمعين باستخدام
CastSession
. يتم تسليم جميع إشعارات حالة الجهاز المتبقية عن طريق
CastStateListener
معاودة الاتصال، ويتم تسجيل هؤلاء المستمعين باستخدام
CastSession
. تأكد من أنك لا تزال تلغي تسجيل المستمعين عند انتقال الأجزاء أو الأنشطة أو التطبيقات المرتبطة إلى الخلفية.
منطق إعادة الاتصال
يحاول CAF إعادة إنشاء اتصالات الشبكة المفقودة بسبب فقدان إشارة WiFi المؤقتة أو أخطاء الشبكة الأخرى. ويتم ذلك الآن على مستوى الجلسة، ويمكن أن تُدخل الجلسة حالة "معلّقة" عند فقد الاتصال، وتنتقل مرة أخرى إلى الحالة "مرتبط" عند استعادة الاتصال. ويتولى إطار العمل هذا إعادة الاتصال بتطبيق جهاز الاستقبال وإعادة ربط أي من قنوات الإرسال كجزء من هذه العملية.
يوفر CAF خدمة إعادة الاتصال الخاصة به، حتى تتمكن من إزالة CCL ReconnectionService
من البيان:
<service android:name="com.google.android.libraries.cast.companionlibrary.cast.reconnection.ReconnectionService"/>
لا تحتاج أيضًا إلى الأذونات التالية في البيان لمنطق إعادة الاتصال:
<uses‐permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses‐permission android:name="android.permission.ACCESS_WIFI_STATE"/>
يتم تفعيل خدمة إعادة الاتصال في CAF تلقائيًا، ولكن يمكن إيقافها باستخدام
CastOptions
.
إضافة إلى ذلك، يضيف CAF أيضًا استئنافًا تلقائيًا للجلسة يتم تمكينه تلقائيًا (ويمكن إلغاء تنشيطه عبر CastOptions
). إذا تم إرسال تطبيق المرسل إلى الخلفية أو تم إنهاؤه (عن طريق التمرير السريع بعيدًا أو بسبب حدوث عطل)
أثناء كون جلسة الإرسال قيد التقدم، فسيحاول إطار العمل استئناف هذه الجلسة عندما يعود تطبيق المرسل إلى المقدمة أو يتم إعادة تشغيله،
وسيتم التعامل مع هذا تلقائيًا من خلال رسالة SessionManager
التي سيتم فيها تسجيل أي رد مناسب على SessionManagerListener
.
تسجيل قناة مخصّصة
يوفر CCL طريقتين لإنشاء قناة رسالة مخصصة إلى المستلم:
- يتيح لك
CastConfiguration
تحديد مساحات أسماء متعددة، وسينشئ برنامج CCL القناة بالنيابة عنك. - إنّ
DataCastManager
مشابه لـ VideoCastManager، ولكنّه يركّز على حالات الاستخدام غير الوسائط.
لا يدعم أي من هاتين الطريقتين لإنشاء قناة مخصصة بواسطة CAF -- يجب عليك بدلاً من ذلك اتباع الإجراء إضافة قناة مخصصة لتطبيق المرسل.
وكما هو الحال مع CCL، ليس من الضروري في تطبيقات الوسائط تسجيل قناة التحكم في الوسائط بشكل صريح.
التحكم في الوسائط
في CAF، تُعادل الفئة RemoteMediaClient
طرق الوسائط VideoCastManager
. تُعادل RemoteMediaClient.Listener
طريقة
VideoCastConsumer
. على وجه التحديد، تعيّن طريقتا
onRemoteMediaPlayerMetadataUpdated
وonRemoteMediaPlayerStatusUpdated
في VideoCastConsumer
طريقتَي onMetadataUpdated
وonStatusUpdated
لـ RemoteMediaClient.Listener
على التوالي:
private class CastMediaClientListener implements RemoteMediaClient.Listener {
@Override
public void onMetadataUpdated() {
setMetadataFromRemote();
}
@Override
public void onStatusUpdated() {
updatePlaybackState();
}
@Override
public void onSendingRemoteMediaRequest() {
}
@Override
public void onQueueStatusUpdated() {
}
@Override
public void onPreloadStatusUpdated() {
}
}
ليس من الضروري إعداد كائن RemoteMediaClient
أو تسجيله بشكل صريح، حيث سينشئ إطار العمل صورة للكائنات تلقائيًا ويسجِّل قناة الوسائط الأساسية في وقت بدء الجلسة إذا كان تطبيق المستقبِل الذي يتم الاتصال به يتوافق مع مساحة اسم الوسائط.
ويمكن الوصول إلى RemoteMediaClient
كطريقة getRemoteMediaClient
لكائن CastSession
.
CastSession castSession = CastContext.getSharedInstance(mAppContext)
.getSessionManager()
.getCurrentCastSession();
mRemoteMediaClient = castSession.getRemoteMediaClient();
mRemoteMediaClientListener = new CastMediaClientListener();
بدلاً من CCL:
VideoCastManager.getInstance().addVideoCastConsumer(mCastConsumer);
يمكنك الآن استخدام CAF:
mRemoteMediaClient.addListener(mRemoteMediaClientListener);
يمكن تسجيل أي عدد من المستمعين مع RemoteMediaClient
، ما يسمح للعديد من مكوّنات المُرسِل بمشاركة المثيل الوحيد لـ RemoteMediaClient
المرتبط بالجلسة.
يوفر VideoCastManager
في CCL طرقًا للتعامل مع تشغيل الوسائط:
VideoCastManager manager = VideoCastManager.getInstance();
if (manager.isRemoteMediaLoaded()) {
manager.pause();
mCurrentPosition = (int) manager.getCurrentMediaPosition();
}
يتم تنفيذ هذه الآن بواسطة RemoteMediaClient في CAF:
if (mRemoteMediaClient.hasMediaSession()) {
mRemoteMediaClient.pause();
mCurrentPosition =
(int)mRemoteMediaClient.getApproximateStreamPosition();
}
في CAF، تعرض جميع طلبات الوسائط التي تم إصدارها في RemoteMediaClient
RemoteMediaClient.MediaChannelResult
عبر معاودة الاتصال PendingResult
والتي يمكن استخدامها لتتبع مدى تقدم الطلب والنتائج النهائية.
يستخدم كل من CCL وCAF فئتي MediaInfo
وMediaMetadata
لتمثيل عناصر الوسائط وتحميل الوسائط.
لتحميل الوسائط في CCL، يتم استخدام VideoCastManager
:
VideoCastManager.getInstance().loadMedia(media, autoPlay, mCurrentPosition, customData);
في CAF، يتم استخدام RemoteMediaClient
لتحميل الوسائط:
mRemoteMediaClient.load(media, autoPlay, mCurrentPosition, customData);
للحصول على معلومات Media
وحالة جلسة الوسائط الحالية على جهاز الاستقبال، تستخدم ميزة CCL VideoCastManager
:
MediaInfo mediaInfo = VideoCastManager.getInstance()
.getRemoteMediaInformation();
int status = VideoCastManager.getInstance().getPlaybackStatus();
int idleReason = VideoCastManager.getInstance().getIdleReason();
في CAF، استخدم RemoteMediaClient
للحصول على المعلومات نفسها:
MediaInfo mediaInfo = mRemoteMediaClient.getMediaInfo();
int status = mRemoteMediaClient.getPlayerState();
int idleReason = mRemoteMediaClient.getIdleReason();
تراكب تمهيدي
على غرار CCL، يوفر CAF عرضًا مخصصًا IntroductoryOverlay
لإبراز زر الإرسال عند عرضه للمرة الأولى للمستخدمين.
بدلاً من استخدام طريقة VideoCastConsumer
onCastAvailabilityChanged
لـ CCL لمعرفة وقت عرض التراكب، أعلن عن CastStateListener
لتحديد متى يصبح زر الإرسال مرئيًا بعد أن يكتشف MediaRouter
أجهزة الإرسال على الشبكة المحلية:
private IntroductoryOverlay mIntroductoryOverlay;
private MenuItem mMediaRouteMenuItem;
protected void onCreate(Bundle savedInstanceState) {
...
mCastStateListener = new CastStateListener() {
@Override
public void onCastStateChanged(int newState) {
if (newState != CastState.NO_DEVICES_AVAILABLE) {
showIntroductoryOverlay();
}
}
};
mCastContext = CastContext.getSharedInstance(this);
mCastContext.registerLifecycleCallbacksBeforeIceCreamSandwich(this,
savedInstanceState);
}
protected void onResume() {
mCastContext.addCastStateListener(mCastStateListener);
...
}
protected void onPause() {
mCastContext.removeCastStateListener(mCastStateListener);
...
}
تتبُّع مثيل MediaRouteMenuItem
:
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.browse, menu);
mMediaRouteMenuItem = CastButtonFactory.setUpMediaRouteButton(
getApplicationContext(), menu,
R.id.media_route_menu_item);
showIntroductoryOverlay();
return true;
}
تحقق مما إذا كان MediaRouteButton
مرئيًا بحيث يمكن عرض التراكب التمهيدي:
private void showIntroductoryOverlay() {
if (mIntroductoryOverlay != null) {
mIntroductoryOverlay.remove();
}
if ((mMediaRouteMenuItem != null) && mMediaRouteMenuItem.isVisible()) {
new Handler().post(new Runnable() {
@Override
public void run() {
mIntroductoryOverlay = new IntroductoryOverlay.Builder(
VideoBrowserActivity.this, mMediaRouteMenuItem)
.setTitleText(getString(R.string.introducing_cast))
.setOverlayColor(R.color.primary)
.setSingleTime()
.setOnOverlayDismissedListener(
new IntroductoryOverlay
.OnOverlayDismissedListener() {
@Override
public void onOverlayDismissed() {
mIntroductoryOverlay = null;
}
})
.build();
mIntroductoryOverlay.show();
}
});
}
}
ألق نظرة على نموذج التطبيق للحصول على شفرة العمل الكاملة لعرض التراكب التمهيدي.
لتخصيص نمط التراكب التمهيدي، اتبع الإجراء تخصيص التراكب التمهيدي.
وحدة تحكم صغيرة
بدلاً من استخدام CCL MiniController
، استخدم MiniControllerFragment
CAF في ملف تخطيط التطبيق للأنشطة التي تريد عرض وحدة التحكم المصغّرة فيها:
<fragment
android:id="@+id/cast_mini_controller"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:castShowImageThumbnail="true"
android:visibility="gone"
class="com.google.android.gms.cast.framework.media.widget.MiniControllerFragment" />
لا يدعم CAF الضبط اليدوي الذي يدعمه MiniController
CCL ولا يدعم ميزة Autoplay
أيضًا.
لتخصيص النمط وأزرار وحدة التحكم المصغرة، اتبع إجراء تخصيص وحدة تحكم صغيرة.
الإشعار وشاشة القفل
على غرار VideoCastNotificationService
في CCL، يوفر CAF
MediaNotificationService
لإدارة عرض إشعارات الوسائط
عند الإرسال.
يجب إزالة ما يلي من البيان:
VideoIntentReceiver
VideoCastNotificationService
يتيح CCL توفير خدمة إشعارات مخصّصة مع
CastConfiguration.Builder
، وهو غير متوافق مع CAF.
يجب إعداد CastManager
التالية باستخدام CCL:
VideoCastManager.initialize(
getApplicationContext(),
new CastConfiguration.Builder(
context.getString(R.string.app_id))
.addNotificationAction(
CastConfiguration.NOTIFICATION_ACTION_PLAY_PAUSE,true)
.addNotificationAction(
CastConfiguration.NOTIFICATION_ACTION_DISCONNECT,true)
.build());
بالنسبة إلى الإعدادات المكافئة في CAF، توفّر حزمة تطوير البرامج (SDK)
NotificationsOptions.Builder
لمساعدتك على إنشاء عناصر التحكّم في الوسائط
للإشعار وشاشة القفل في تطبيق المُرسِل. ويمكن تفعيل الإشعارات وعناصر التحكّم في
شاشة القفل باستخدام CastOptions
عند إعداد
CastContext
.
public CastOptions getCastOptions(Context context) {
NotificationOptions notificationOptions =
new NotificationOptions.Builder()
.setActions(Arrays.asList(
MediaIntentReceiver.ACTION_TOGGLE_PLAYBACK,
MediaIntentReceiver.ACTION_STOP_CASTING), new int[]{0, 1})
.build();
CastMediaOptions mediaOptions = new CastMediaOptions.Builder()
.setNotificationOptions(notificationOptions)
.build();
return new CastOptions.Builder()
.setReceiverApplicationId(context.getString(R.string.app_id))
.setCastMediaOptions(mediaOptions)
.build();
}
تكون الإشعارات وعناصر التحكم في شاشة القفل مفعّلة دائمًا في CAF. لاحظ أيضًا أنه يتم توفير أزرار التشغيل/الإيقاف المؤقت وإيقاف الإرسال بشكل افتراضي. سيتتبع CAF مستوى رؤية الأنشطة تلقائيًا لتحديد وقت عرض إشعار الوسائط، باستثناء Gingerbread.
(بالنسبة إلى Gingerbread، راجع الملاحظة السابقة حول
استخدام registerLifecycleCallbacksBeforeIceCreamSandwich()
، ومكالمات CCL
VideoCastManager
incrementUiCounter
، وdecrementUiCounter
يجب إزالتها.)
لتخصيص الأزرار التي يتم عرضها في الإشعارات، اتبع الإجراء إضافة عناصر تحكم في الوسائط إلى الإشعارات وشاشة القفل.
وحدة تحكم موسعة
توفّر CCL VideoCastControllerActivity
وVideoCastControllerFragment
لعرض وحدة تحكم موسّعة عند إرسال الوسائط.
يمكنك إزالة تعريف VideoCastControllerActivity
في البيان.
في CAF، يجب توسيع قائمة التشغيل الموسّعة وإضافة زر الإرسال.
لتخصيص الأنماط والأزرار التي يتم عرضها في وحدة التحكم الموسَّعة، اتبع الإجراء تخصيص وحدة التحكم الموسعة.
التركيز على الصوت
كما هو الحال مع CCL، تتم إدارة تركيز الصوت تلقائيًا.
التحكم في مستوى الصوت
بالنسبة إلى Gingerbread، يجب توفير dispatchKeyEvent
كما هو الحال مع CCL. في ICS والإصدارات الأحدث
بالنسبة إلى التحكم في مستوى صوت CCL وCAF، يتم التعامل معهما تلقائيًا.
يتيح CAF التحكم في مستوى صوت الإرسال من خلال زر مستوى الصوت الثابت على الهاتف داخل أنشطة التطبيقات، كما يعرض شريط مستوى الصوت المرئي عند الإرسال إلى الإصدارات المتوافقة. يتعامل CAF أيضًا مع تغيير مستوى الصوت من خلال مستوى الصوت الثابت حتى إذا لم يكن تطبيقك في المقدمة، أو كان مغلقًا، أو حتى عندما تكون الشاشة مغلقة.
الترجمة والشرح
في نظام التشغيل Android KitKat وأحدث، يمكن تخصيص التسميات التوضيحية من خلال إعدادات التسميات التوضيحية، الموجودة ضمن إعدادات > إمكانية الوصول. إلا أن الإصدارات السابقة من Android لا تتضمن هذه الإمكانية. يتعامل CCL مع هذا من خلال توفير إعدادات مخصصة للإصدارات السابقة وتفويض إعدادات النظام على KitKat والإصدارات الأحدث.
لا يوفر CAF إعدادات مخصصة لتغيير تفضيلات التسميات التوضيحية. عليك إزالة المراجع CaptionsPreferenceActivity
في ملف البيان
وتفضيلات XML.
لم تعد قناة TracksChooserDialog
التابعة لـ CCL مطلوبة لأن تغيير واجهة
مقاطع الترجمة والشرح تتم معالجته بواسطة واجهة مستخدم وحدة التحكم الموسّعة.
إنّ واجهة برمجة التطبيقات للتسميات التوضيحية المغلقة في CAF مماثلة للإصدار 2.
تسجيل تصحيح الأخطاء
لا يوفر CAF إعدادات تسجيل تصحيح الأخطاء.
ميزات متنوّعة
لا تتوفّر ميزات CCL التالية في CAF:
- جارٍ الحصول على تفويض قبل التشغيل من خلال تقديم
MediaAuthService
- رسائل واجهة المستخدم القابلة للتهيئة
نماذج تطبيقات
يمكنك الاطّلاع على الفارق في نقل نموذج التطبيق Universal Music Player لـ Android (Uamp) من CCL إلى CAF.
لدينا أيضًا برامج تعليمية حول الترميز ونماذج من التطبيقات التي تستخدم CAF.