Students Save 30%! Learn & create with unlimited courses & creative assets Students Save 30%! Save Now
Advertisement
  1. Code
  2. Android SDK
Code

صوت الخلفية في الروبوت مع ميدياسيسيونكومبات

by
Difficulty:BeginnerLength:LongLanguages:

Arabic (العربية/عربي) translation by Muhammad Hasrullah (you can also view the original English article)

أحد الاستخدامات الأكثر شعبية للأجهزة النقالة يلعب الصوت مرة أخرى من خلال تدفق الخدمات الصوتية التي تم تنزيلها أو أي عدد من مصادر الصوت الموسيقى. بينما هذا سمة مشتركة إلى حد ما، من الصعب أن تنفذ، مع الكثير من القطع المختلفة التي بحاجة إلى أن يبني بشكل صحيح من أجل إعطاء المستخدم الخاص بك الروبوت الكامل تجربة.

ستتعرف في هذا البرنامج التعليمي على MediaSessionCompat من مكتبة دعم Android ، وكيف يمكن استخدامها لإنشاء خدمة صوت خلفية مناسبة للمستخدمين.

برنامج الإعداد

أول شيء سوف تحتاج إلى القيام به إدراج مكتبة دعم الروبوت في المشروع الخاص بك. يمكن أن يتم ذلك عن طريق إضافة السطر التالي إلى ملف build.gradle في الوحدة النمطية الخاصة بك تحت عقده التبعيات.

بعد أن كنت قد مزامن المشروع الخاص بك، قم بإنشاء فئة جافا جديدة. في هذا المثال ، سأتصل بالفئة BackgroundAudioService. ستحتاج هذه الفئة إلى توسيع MediaBrowserServiceCompat. سنقوم أيضًا بتنفيذ واجهات التالية: MediaPlayer.OnCompletionListener و AudioManager.OnAudioFocusChangeListener.

والآن بعد أن تم إنشاء تطبيق MediaBrowserServiceCompat ، فلنأخذ لحظة لتحديث AndroidManifest.xml قبل العودة إلى هذا الفصل الدراسي. في الجزء العلوي من الفئة، سوف تحتاج إلى طلب الإذن WAKE_LOCK.

المقبل ، داخل application العقدة ، أعلن عن خدمتك الجديدة بما يلي intent-filter العناصر. سيسمح ذلك لخدمتك باعتراض أزرار التحكم وأحداث سماعة الرأس وتصفح الوسائط للأجهزة ، مثل Android Auto (على الرغم من أننا لن نفعل أي شيء مع Android Auto لهذا البرنامج التعليمي ، إلا أن بعض الدعم الأساسي له ما زال مطلوبًا بواسطة MediaBrowserServiceCompat).

وأخيرًا ، ستحتاج إلى إعلان استخدام MediaButtonReceiver من مكتبة دعم Android. هذا سوف يسمح لك لاعتراض وسائل الإعلام عنصر تحكم زر التفاعلات والأحداث سماعة الرأس على أجهزة تشغيل كيتكات والإصدارات السابقة.

الآن وبعد أن الانتهاء من ملف AndroidManifest.xml الخاص بك، فيمكنك إغلاقه. سنقوم أيضًا بإنشاء فئة أخرى باسم MediaStyleHelper ، والتي كتبها Ian Lake ، Developer Advocate في Google ، لتنظيف إنشاء إعلامات على نمط الوسائط.

بمجرد أن يتم إنشاء، والمضي قدما بإغلاق الملف. وسوف نركز على خدمة الصوت في الخلفية في المقطع التالي.

بناء على خدمة الصوت في الخلفية

الآن حان الوقت لحفر في صلب إنشاء التطبيق الخاص بك في وسائل الإعلام. هناك عدد قليل من المتغيرات الخاصة بالأعضاء التي ستقوم بتعريفها أولاً لهذا التطبيق النموذجي: وهو MediaPlayer للتشغيل الفعلي ، وكائن MediaSessionCompat الذي سيدير البيانات الوصفية وعناصر التحكم / الحالات.

بالإضافة إلى ذلك ، ستحتاج إلى جهاز BroadcastReceiver يستمع إلى التغييرات في حالة سماعة الرأس. للحفاظ على بساطة الأشياء ، سيوقف جهاز الاستقبال هذا برنامج MediaPlayer ، إذا كان مشغلاً.

لمتغير العضو النهائي، سوف لإنشاء كائن MediaSessionCompat.Callback، الذي يستخدم لمعالجة حالة التشغيل عند حدوث إجراءات الدورة وسائل الإعلام.

سوف نعيد كل من الأساليب المذكورة أعلاه في وقت لاحق في هذا البرنامج التعليمي، كما أنها ستستخدم لعمليات محرك الأقراص في التطبيق وسائل الإعلام لدينا.

هناك طريقتين التي سوف نحتاج أيضا إلى أن تعلن، على الرغم من أنها لن تحتاج إلى القيام بأي شيء لأغراض هذا البرنامج التعليمي: onGetRoot() و onLoadChildren(). يمكنك استخدام التعليمات البرمجية التالية للافتراضيات الخاصة بك.

وأخيرًا ، سترغب في تجاوز أسلوب onStartCommand () ، الذي يمثل نقطة الإدخال في Service. سيأخذ هذا الأسلوب في Intent التي تم تمريرها إلى Service وإرسالها إلى فئة MediaButtonReceiver.

تهيئة جميع الأشياء

والآن بعد أن يتم إنشاء متغيرات عضو القاعدة الخاصة بك، حان الوقت لتهيئة كل شيء. سنقوم بذلك عن طريق استدعاء أساليب المساعد المختلفة في onCreate ().

الطريقة الأولى ، initMediaPlayer () ، ستقوم بتهيئة كائن MediaPlayer الذي أنشأناه في الجزء العلوي من الفصل ، وطلب قفل التنبيه الجزئي (وهذا هو السبب في أننا طلبنا هذا الإذن في AndroidManifest.xml) ، وضبط حجم المشغل.

الطريقة التالية ، initMediaSession () ، هي المكان الذي نقوم فيه بتهيئة كائن MediaSessionCompat وسلكه إلى أزرار الوسائط وطرق التحكم التي تسمح لنا بالتعامل مع التشغيل وإدخال المستخدم. يبدأ هذا الأسلوب عن طريق إنشاء كائن ComponentName الذي يشير إلى فئة MediaButtonReceiver في مكتبة دعم Android ، ويستخدم ذلك لإنشاء MediaSessionCompat جديد. ونحن ثم تمرير الكائن MediaSession.Callback أن تم إنشاؤها في وقت سابق، وتعيين العلامات اللازمة لتلقي مدخلات زر الوسائط والتحكم بإشارات. بعد ذلك ، نخلق جديدًا Intent للتعامل مع مدخلات زر الوسائط على أجهزة Pre-Lollipop ، وتعيين رمز جلسة عمل الوسائط لخدماتنا.

أخيرًا ، سنسجل BroadcastReceiver الذي أنشأناه في الجزء العلوي من الفصل الدراسي حتى نتمكن من الاستماع إلى أحداث تغيير سماعات الرأس.

التعامل مع تركيز الصوت

الآن بعد الانتهاء من تهيئة كائنات BroadcastReceiver و MediaSessionCompat و MediaPlayer ، فقد حان الوقت للنظر في التعامل مع التركيز الصوتي.

بينما قد نعتقد أن منطقتنا تطبيقات الصوت هي الأكثر أهمية في الوقت الراهن، سوف تكون المنافسة تطبيقات أخرى على الجهاز لجعل الأصوات الخاصة بهم، مثل إعلام بالبريد الإلكتروني أو لعبة الجوال. من أجل العمل مع هذه الحالات المختلفة، يستخدم نظام الروبوت تركيز الصوت لتحديد كيف ينبغي التعامل مع الصوت.

وفي الحالة الأولى أننا سوف ترغب في التعامل مع بدء التشغيل ومحاولة تلقي التركيز للجهاز. في كائن MediaSessionCompat.Callback الخاص بك، انتقل إلى الأسلوب onPlay() وإضافة شرط الاختيار التالية.

سيتم استدعاء التعليمات البرمجية أعلاه أسلوب مساعد أن محاولات لاسترداد التركيز، ولو أنه لا يمكن، فإنه سيعود ببساطة. في تطبيق حقيقي، قد ترغب في التعامل مع فشل تشغيل الصوت بأمان أكثر. سوف successfullyRetrievedAudioFocus() الحصول على مرجع إلى نظام AudioManager، ومحاولة لطلب التركيز الصوتية لدفق الموسيقى. سوف يعود بعد ذلك boolean تمثل ما إذا كان الطلب قد نجح أم لا.

ستلاحظ أننا نمرر this أيضًا إلى requestAudioFocus () ، الذي يربط OnAudioFocusChangeListener مع خدمتنا. وهناك عدد قليل من الدول المختلفة التي سوف تحتاج للاستماع لكي تكون "مواطن الصالح" في النظام الإيكولوجي في التطبيق للجهاز.

  • AudioManager.AUDIOFOCUS_LOSS: يحدث هذا عندما طلبت آخر التطبيق تركيز الصوت. عندما يحدث هذا، يجب عليك إيقاف تشغيل الصوت في التطبيق الخاص بك.
  • AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: يتم إدخال هذه الدولة عندما يريد آخر التطبيق تشغيل الصوت، ولكن أنها تتوقع فقط تحتاج إلى التركيز لفترة قصيرة. يمكنك استخدام هذه الدولة لإيقاف تشغيل الصوت الخاص بك.
  • AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: عندما تركيز الصوت ومطلوب، ولكن يلقي دولة 'يمكن بطة'، فهذا يعني أنك يمكن أن يستمر التشغيل الخاص بك، ولكن يجب إحضار وحدة التخزين إلى أسفل قليلاً. يمكن أن يحدث هذا عندما يتم لعب صوت إشعار بالجهاز.
  • AudioManager.AUDIOFOCUS_GAIN: هو الحالة النهائية وسوف نناقش AUDIOFOCUS_GAIN. هذه هي الحالة عندما انتهت قراءة صوت دوكابل، والتطبيق الخاص بك يمكن أن تستأنف في المستويات السابقة.

رد اتصال onAudioFocusChange() مبسطة قد تبدو كما يلي:

فهم في MediaSessionCompat.Callback

الآن بعد أن لديك بنية عامة معا Service الخاصة بك، حان الوقت يغوص MediaSessionCompat.Callback. في المقطع الأخير قمت بإضافتها قليلاً إلى onPlay() للتحقق إذا كان منح تركيز الصوت. أسفل العبارة الشرطية ، ستحتاج إلى تعيين كائن MediaSessionCompat ليتم تنشيطه ، وإعطائه حالة من STATE_PLAYING ، وتعيين الإجراءات المناسبة الضرورية لإنشاء أزرار الإيقاف المؤقت على عناصر التحكم في قفل الشاشة السابق ، Lollipop ، وإخطارات الهاتف وإشعارات Android Wear.

أسلوب setMediaPlaybackState () أعلاه هو أسلوب مساعد ينشئ كائن PlaybackStateCompat.Builder ويعطيها الإجراءات المناسبة وحالة ثم ثم ينشئ ثم يقترن PlaybackStateCompat مع كائن MediaSessionCompat الخاص بك.

من المهم ملاحظة أنك ستحتاج كل من ACTION_PLAY_PAUSE وإعلام ACTION_PAUSE أو ACTION_PLAY في الإجراءات الخاصة بك من أجل الحصول على ضوابط سليمة على "ارتداء الروبوت".

Media notification on Android Wear

مرة أخرى في onPlay () ، ستحتاج إلى إظهار إعلام تشغيل مقترن كائن MediaSessionCompat الخاص بك باستخدام فئة MediaStyleHelper التي تم تعريفها مسبقًا ثم إظهار ذلك الإعلام.

أخيرا ، سوف تبدأ في MediaPlayer في نهاية onPlay ().

Media control notification on an Android Nougat device

عندما يتلقى رد الاتصال أمر الإيقاف مؤقت، سيتم استدعاء onPause(). هنا سوف تقوم بإيقاف MediaPlayer مؤقتًا ، وتعيين الحالة إلى STATE_PAUSED ، وإظهار إعلام متوقف مؤقتًا.

لدينا أسلوب مساعد showPausedNotification() مشابهاً لأسلوب showPlayNotification().

الطريقة التالية في معاودة الاتصال التي سنناقشها ، onPlayFromMediaId(), يأخذ String و Bundle كمعلمات. هذا هو أسلوب رد الاتصال التي يمكنك استخدامها لتغيير المسارات/محتوى الصوت داخل التطبيق الخاص بك.

لهذا البرنامج التعليمي، سنقوم ببساطة قبول وجود معرف موارد خام ومحاولة اللعب التي ومن ثم تهيئة بيانات التعريف الدورة. كما يسمح لك لتمرير Bundle في هذه الطريقة ، يمكنك استخدامها لتخصيص الجوانب الأخرى لتشغيل الوسائط ، مثل إعداد صوت خلفية مخصص لمسار.

الآن أن لقد ناقشنا طريقتين الرئيسي في هذا رد الاتصال التي سيتم استخدامها في التطبيقات الخاصة بك، من المهم أن تعرف أن هناك أساليب أخرى الاختيارية التي يمكنك استخدامها لتخصيص الخدمة الخاصة بك. بعض الطرق تشمل onSeekTo() الذي يسمح لك بتغيير موضع التشغيل للمحتوى الخاص بك، و onCommand() والتي سوف تقبل String تدل على نوع القيادة ،  Bundle للحصول على معلومات إضافية حول الأمر ، و ResultReceiver رد الاتصال، والتي سوف تسمح لك بإرسال أوامر مخصصة إلى حسابك Service.

تمزيق

عند الانتهاء من ملف الصوت لدينا، سوف نريد أن تقرر ما سيكون عملنا المقبل. في حين قد ترغب في تشغيل المسار التالي في تطبيقك ، سنبقي الأمور بسيطة ونفرج عن MediaPlayer.

أخيراً ، سوف نرغب في القيام بأشياء قليلة في onDestroy() طريقة لدينا Service. أولاً ، احصل على مرجع إلى AudioManager الخاص بخدمة النظام ، واتصل بـ abandonAudioFocus () باستخدام AudioFocusChangeListener كمعلمة ، والتي ستقوم بإعلام التطبيقات الأخرى على الجهاز أنك تتخلى عن تركيز الصوت. بعد ذلك ، قم بإلغاء تسجيل BroadcastReceiver الذي تم إعداده للاستماع لتغيرات سماعة الرأس وتحرير كائن MediaSessionCompat. وأخيراً، سوف تحتاج إلى إلغاء الإخطار التحكم بالتشغيل.

في هذه المرحلة ، يجب أن يكون لديك خدمة صوت Service أساسية أساسية تستخدم MediaSessionCompat للتحكم في التشغيل عبر الأجهزة. في حين قد حدثت بالفعل الكثير من المشاركة في مجرد إنشاء الدائرة، يجب أن تكون قادرة على التحكم في التشغيل من التطبيق الخاص بك، إعلام، وتأمين عناصر تحكم الشاشة على أجهزة مصاصة قبل (مصاصة وأعلاه سوف تستخدم الإخطار على الشاشة قفل)، ومن الأجهزة الطرفية، مثل "ارتداء الروبوت"، بمجرد تم بدء تشغيل Service.

Media lock screen controls on Android Kit Kat

بدء تشغيل والتحكم في المحتوى من نشاط

في حين سوف تكون معظم عناصر التحكم التلقائي، سوف لا يزال لديك قليلاً من العمل بدء تشغيل والتحكم في جلسة عمل وسائل الإعلام من عناصر التحكم في التطبيق الخاص بك. على أقل تقدير ، سوف تحتاج إلى MediaBrowserCompat.ConnectionCallback ، و MediaControllerCompat.Callback ، و MediaBrowserCompat ، و MediaControllerCompat الكائنات التي تم إنشاؤها في التطبيق الخاص بك.

سيحتوي MediaControllerCompat.Callback على أسلوب يسمى onPlaybackStateChanged () يتلقى تغييرات في حالة التشغيل ، ويمكن استخدامه للحفاظ على واجهة المستخدم الخاصة بك في المزامنة.

يحتوي MediaBrowserCompat.ConnectionCallback على أسلوب onConnected () سيتم استدعاء عند إنشاء كائن MediaBrowserCompat جديد وتوصيله. يمكنك استخدام هذا لتهيئة كائن MediaControllerCompat الخاص بك ، قم بربطه بـ MediaControllerCompat.Callback ، وقم بربطه بـ MediaSessionCompat من Service الخاصة بك. وبمجرد الانتهاء من ذلك، يمكنك بدء تشغيل الصوت من هذا الأسلوب.

ستلاحظ أن أجزاء التعليمات البرمجية المتكررة أعلاه يستخدم getSupportMediaController().getTransportControls() للتواصل مع الدورة وسائل الإعلام. باستخدام نفس الأسلوب، يمكنك استدعاء onPlay() و onPause() في كائن خدمة الصوت الخاص بك MediaSessionCompat.Callback.

عند الانتهاء من تشغيل الصوت ، يمكنك إيقاف خدمة الصوت مؤقتًا وفصل كائن MediaBrowserCompat ، وهو ما سنفعله في هذا البرنامج التعليمي عند إتلاف هذا Activity.

وفي ختام

يا للعجب! كما ترون، هناك الكثير من القطع تتحرك المعنية مع إنشاء واستخدام خدمة صوت خلفية بشكل صحيح.

في هذا البرنامج التعليمي ، قمت بإنشاء خدمة تقوم بتشغيل ملف صوتي بسيط ، والاستماع إلى التغييرات في تركيز الصوت ، والارتباطات إلى MediaSessionCompat لتوفير التحكم في التشغيل العام على أجهزة Android ، بما في ذلك الهواتف المحمولة و Android Wear. إذا قمت بتشغيل إلى حواجز الطرق أثناء العمل من خلال هذا البرنامج التعليمي، أوصى بشدة بالتحقق من التعليمات البرمجية المقترنة المشروع الروبوت في Envato Tuts + في GitHub.

وتحقق بعض دورات الروبوت والدروس هنا في Envato Tuts + الأخرى!


Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.