أجهزة استقبال البث للمبتدئين

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

خلفية

أجهزة استقبال البث هي مكونات في تطبيق Android الخاص بك تستمع إلى رسائل البث (أو الأحداث) من منافذ مختلفة:

  • من التطبيقات الأخرى
  • من النظام نفسه
  • من التطبيق الخاص بك

بمعنى ، يتم استدعاءهم عند حدوث إجراء معين تمت برمجتهم للاستماع إليه (IE ، بث).

البث هو مجرد رسالة ملفوفة داخل كائن Intent. يمكن أن يكون البث إما ضمنيًا أو صريحًا.

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

هناك طريقتان للإعلان عن جهاز استقبال:

  1. من خلال إعلان واحد في ملف AndroidManifest.xml الخاص بك مع العلامة (تسمى أيضًا ثابتة)

ستلاحظ أن جهاز استقبال البث المعلن أعلاه له خاصية تم تصديرها = ”true” . تخبر هذه السمة جهاز الاستقبال بأنه يمكنه استقبال البث من خارج نطاق التطبيق.

2. أو بشكل ديناميكي عن طريق تسجيل مثيل مع registerReceiver (ما يعرف بالسياق المسجل)

public abstract Intent registerReceiver (BroadcastReceiver receiver, IntentFilter filter);

التنفيذ

لإنشاء جهاز استقبال البث الخاص بك ، يجب عليك أولاً تمديد الفئة الرئيسية لـ BroadcastReceiver وتجاوز الطريقة الإلزامية ، onReceive:

public void onReceive(Context context, Intent intent) { //Implement your logic here }

جمع كل ذلك معًا ينتج عنه:

public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { StringBuilder sb = new StringBuilder(); sb.append("Action: " + intent.getAction() + "\n"); sb.append("URI: " + intent.toUri(Intent.URI_INTENT_SCHEME).toString() + "\n"); String log = sb.toString(); Toast.makeText(context, log, Toast.LENGTH_LONG).show(); } }
تعمل طريقة onReceive على الخيط الرئيسي ، ولهذا يجب أن يكون تنفيذها موجزًا.

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

مثال التسجيل الديناميكي

لتسجيل جهاز استقبال بسياق ، تحتاج أولاً إلى إنشاء مثيل لجهاز استقبال البث الخاص بك:

BroadcastReceiver myBroadcastReceiver = new MyBroadcastReceiver();

بعد ذلك ، يمكنك تسجيله بناءً على السياق المحدد الذي ترغب فيه:

IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED); this.registerReceiver(myBroadcastReceiver, filter);

لا تنس إلغاء تسجيل جهاز استقبال البث الخاص بك عندما لم تعد بحاجة إليه

@Override protected void onStop() { super.onStop(); unregisterReceiver(myBroadcastReceiver); }

بث حدث

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

هناك ثلاث طرق لإرسال البث:

  1. و sendOrderedBroadcastالطريقة ، تأكد من إرسال البث إلى جهاز استقبال واحد فقط في كل مرة. يمكن لكل بث بدوره أن يمرر البيانات إلى الذي يتبعه ، أو أن يوقف انتشار البث إلى أجهزة الاستقبال التالية
  2. و sendBroadcast مشابهة للطريقة المذكورة أعلاه، مع فارق واحد. تتلقى جميع أجهزة استقبال البث الرسالة ولا تعتمد على بعضها البعض
  3. و LocalBroadcastManager.sendBroadcast طريقة يرسل فقط البث لاستقبال تعريفها داخل طلبك ولا يتجاوز نطاق application.Example الخاص بإرسال بث مخصصة

//giphy.com/gifs/23gUJhHyWkXEwl7UYV/html5

مسك والأشياء التي يجب الانتباه إليها

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

تشير النقاط التالية إلى التغييرات في أجهزة استقبال البث ذات الصلة بكل إصدار من إصدارات نظام التشغيل Android (بدءًا من 7.0). لكل إصدار ، تم وضع قيود معينة وتغير السلوك أيضًا. ضع هذه القيود في الاعتبار عند التفكير في استخدام جهاز استقبال البث.

  • 7.0 وما فوق (API المستوى 24) - تم تعطيل عمليتي بث للنظام ، Action_New_Picture و Action_New_Video (ولكن تمت إعادتهما إلى Android O لأجهزة الاستقبال المسجلة)
  • 8.0 وما فوق (مستوى API 26) - يجب تسجيل معظم عمليات البث الضمنية بشكل ديناميكي وليس ثابتًا (في البيان الخاص بك). يمكنك العثور على عمليات البث التي تمت إضافتها إلى القائمة البيضاء في هذا الرابط.
  • 9.0 وما فوق (مستوى API 28) - تم تلقي معلومات أقل حول بث نظام Wi-Fi و Network_State_Changed_Action.

التغييرات في Android O هي التغييرات التي يجب أن تكون على دراية بها. كان سبب إجراء هذه التغييرات هو أنها تؤدي إلى مشكلات في الأداء ونفاد البطارية وتضر بتجربة المستخدم. حدث هذا لأن العديد من التطبيقات (حتى تلك التي لا تعمل حاليًا) كانت تستمع إلى تغيير على مستوى النظام وعندما حدث هذا التغيير ، أعقب ذلك الفوضى. تخيل أن كل تطبيق تم تسجيله في الإجراء ، جاء إلى الحياة للتحقق مما إذا كان بحاجة إلى القيام بشيء ما بسبب البث. ضع في الاعتبار شيئًا مثل حالة Wi-Fi ، والتي تتغير كثيرًا ، وستبدأ في فهم سبب حدوث هذه التغييرات.

بدائل لأجهزة استقبال البث

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

  • LocalBroadcastManager - كما ذكرت أعلاه ، هذا صالح فقط للبث داخل تطبيقك
  • جدولة وظيفة - يمكن تشغيل وظيفة بناءً على إشارة أو مشغل تم تلقيه ، لذلك قد تجد أن البث الذي كنت تستمع إليه يمكن استبداله بوظيفة. علاوة على ذلك ، فإنJobScheduler, will guarantee your job will finish, but it will take into account various system factors(time and conditions)to determine when it should run. When creating a job, you will override a method called onStartJob. This method runs on the main thread, so make sure that it finishes its work in a limited amount of time. If you need to perform complex logic, consider starting a background task. Furthermore, the return value for this method is a boolean, where true denotes that certain actions are still being performed, and false means the job is done

If you want to experience first hand the joy and wonder that are broadcast receivers, you can follow these links to repositories that I have set up:

  1. Custom Broadcast (with manifest declaration)
  2. Registering Broadcast (without declaring one in the manifest)
  3. لوكال برودكاست ماناجر

بث أكثر.