BroadCast Receiver در اندروید

ترجمه و تالیف : پوریا شریفی
تاریخ انتشار : 10 تیر 99
خواندن در 3 دقیقه
دسته بندی ها : اندروید

یک نگاه کلی به Broadcast Receiver

Broadcast Receiver یکی از مولفه‌های اساسی در اندروید است. برنامه‌های اندرویدی می‌توانند پیغام‌های Broadcast از سیستم اندروید و برنامه‌های دیگر دریافت و یا به آن‌ها ارسال کنند. برای مثال، سیستم اندروید هنگام وقوع حوادث مختلف در سیستم پیغام Broadcast می‌فرستد. مانند زمان شروع شارژ دستگاه یا در مورد بوت شدن دستگاه. برنامه‌ها همچنین می‌توانند Broadcast‌های سفارشی ارسال کنند تا به برنامه‌های دیگر اطلاع دهند که موردی وجود دارد که ممکن است مورد علاقه آن‌ها باشد.

Broadcast Receiver چیست؟

Broadcast Receiver یک جزء اصلی در اندروید است که به شما امکان می‌دهد پیغام‌های Broadcast را به سیستم اندروید و برنامه‌های دیگر ارسال و یا از آن‌ها دریافت کنید. این Broadcast‌ها وقتی ارسال می‌شوند که یک رویداد جالب رخ دهد.

BroadCast Receiver در اندروید

دریافت Broadcastها

برنامه‌های اندرویدی می‌توانند Broadcast را از دو طریق دریافت کنند، یکی از طریق تعیین receiver در manifest و یکی دیگر از طریق ثبت receiver توسط context.

1- تعیین receiver در manifest

برای تعیین receiver در manifest، مراحل زیر را مرحله به مرحله انجام دهید:

1.1. اضافه کردن <receiver> در فایل manifest برنامه خود

<receiver android:name=".PowerButtonBroadcastReceiver"
    android:exported="false">
    <intent-filter>
        <action android:name="android.intent.action.SCREEN_OFF"/>
        <action android:name="android.intent.action.SCREEN_ON"/>
    </intent-filter>
</receiver>

1.2. یک زیر کلاس از کلاس Broadcast Receiver ایجاد کنید و (onReceive(Context, Intent را مانند مثال زیر پیاده‌سازی کنید

class PowerButtonBroadcastReceiver : BroadcastReceiver() {

  private var screenOff: Boolean = false

  override fun onReceive(context: Context, intent: Intent) {
    if (intent.action == Intent.ACTION_SCREEN_OFF) {
      screenOff = true
    } else if (intent.action == Intent.ACTION_SCREEN_ON) {
      screenOff = false
    }
    val mIntent = Intent(context, PowerButtonUpdateClickService::class.java)
    mIntent.putExtra("screen_state", screenOff)
    context.startService(mIntent)
  }
}

2- ثبت receiver از طریق Context

برای ثبت receiver از طریق Context نیز مراحل زیر را دنبال کنید:

2.1. ایجاد یک نمونه از BroadcastReceiver

val mReceiver = PowerButtonBroadcastReceiver()

2.2. ایجاد یک نمونه از IntentFilter و ثبت receiver با صدا زدن متد زیر:

(registerReceiver(BroadcastReceiver, IntetFilter

// INITIALIZE RECEIVER
val filter = IntentFilter(Intent.ACTION_SCREEN_ON)
filter.addAction(Intent.ACTION_SCREEN_OFF)
mReceiver = PowerButtonBroadcastReceiver()
registerReceiver(mReceiver, filter)

در ثبت receiver‌ها از طریق Context تا زمانی که ثبت آن‌ها معتبر نباشد، پیغام‌های Broadcast دریافت نمی‌شود (context جزئی از اکتیویتی یا فرگمنت است)، اگر از context اپلیکیشن استفاده کنید، تا زمانی‌که اپلیکیشن در حال اجرا است Broadcast‌ها را دریافت می‌کنید. برای متوقف کردن دریافت (Broadcast، unregisterBroadcast(BroadcastReceiver را فراخوانی کنید، شما باید هنگام unregister کردن receiver خیلی مراقب باشید، اگر receiver را در onCreate() ثبت کرده‎‌اید، باید آن را در onDestroy()، unregister کنید تا از نشت receiver خارج از context اکتیویتی، جلوگیری شود.

ارسال Broadcastها

روش‌های زیر برای ارسال Broadcast وجود دارد:

1- (The sendOrderedBroadcast(Intent, String

این روش Broadcast را در آن واحد فقط به یک receiver می‌فرستد، OrderedBroadcast نوعی از Broadcast است که به صورت پشت سر هم(Synchronous) ارسال می‌شوند یعنی یک به یک برای هر شنونده. OrderedBroadcast در کلاس Context اندروید قرار دارد، هدف از این روش، broadcast کردن به شنونده‌های receiver به صورت سریالی است و دریافت نتیجه از اکتیویتی که آن را صدا زده است. یکی دیگر از مزیت‌های مهم sendOrderedBroadcast این است که ما می‌توانیم اولویت BroadcastReceiver را تعیین کنیم. به این ترتیب همه BroadcastReceiver‌ها که در حال گوش دادن به یک Broadcast خاص هستند، آن را به ترتیب خاصی دریافت می‌کنند.

2- Broadcast‌های عادی

این دسته از Broadcast‌ها به صورت asynchronous ارسال می‌شوند، یعنی Broadcast توسط همه receiver‌ها به صورت asynchronous دریافت می‌شود. که دو نوع دارد:

(sendBroadcast(Intent و LocalBroadcastManager.sendBroadcast، کلاس LocalBroadcastManager.sendBroadcast برای ارسال Broadcast محلی استفاده می‌شود، یعنی درون برنامه.

روش sendBroadcast(Intent) ،Broadcast را برای همه گیرنده‌ها به ترتیب نامشخص ارسال می‌کند. به این روش Broadcast عادی گفته می‌شود. این روش کارامدتر است اما به این معنی است که گیرنده‌ها نمی‌توانند نتایج حاصل از گیرنده‌های دیگر را بخوانند. داده‌ها یا از Broadcast دریافت می‌شوند یا Broadcast را قطع می‌کند.

روش LocalBroadcastManager.sendBroadcast، Broadcast را برای گیرنده‌هایی ارسال می‌کند که در همان برنامه ارسال کننده هستند. اگر نیاز ندارید که Broadcast را از طریق برنامه ارسال کنید، از Broadcast محلی استفاده کنید. این پیاده‌سازی بسیار کارامدتر است (هیچ ارتباطات بین پردازشی لازم نیست) و دیگر نیاز نیست که نگران مشکلات امنیتی برنامه‌های دیگر باشید که می‌توانستند Broadcast‌های شما را ارسال و یا دریافت کنند.

ارسال Broadcast با مجوز

هنگام ارسال Broadcast، می‌توانیم محدودیت‌هایی را از طرف گیرنده یا از طرف فرستنده اعمال کنیم. یعنی فقط برنامه‌هایی که مجوز مشخص را دارند اجازه ارسال یا دریافت Broadcast را دارند، اگر فرستنده Broadcast را با Manifest.permission.SEND_SMS ارسال کند سپس گیرنده باید آن را با مجوز SEND_SMS در فایل manifest دریافت کنند، مانند مثال پایین.

sendBroadcast(Intent("com.example.NOTIFY"), Manifest.permission.SEND_SMS)

To receive the broadcast, the receiving app must request below permission
<uses-permission android:name="android.permission.SEND_SMS"/>

دریافت Broadcast با مجوز

اگر مجوز خاصی را در فایل manifest نوشته‌اید که با فرستنده Broadcast ثبت شده است، بنابراین ما فقط می‌توانیم Broadcast را از فرستنده‌هایی مانند زیر دریافت کنیم.

مثال زیر receiver را برای اپلیکیشن دریافت کننده در فایل manifest مشخص کرده است.

<receiver android:name=".MyBroadcastReceiver"
          android:permission="android.permission.SEND_SMS">
    <intent-filter>
        <action android:name="android.intent.action.AIRPLANE_MODE"/>
    </intent-filter>
</receiver>

یا راه دیگری وجود دارد که برنامه دریافت کننده شما همانند زیر receiver ثبت شده توسط Context دارد:

var filter = IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED)
registerReceiver(receiver, filter, Manifest.permission.SEND_SMS, null)

افکار امنیتی و بهترین کارها هنگام ارسال Broadcast

BroadCast Receiver در اندروید

1- همیشه از Broadcast‌های ثبت شده توسط Context به جای Broadcast‌های ثبت شده در manifest استفاده کنید. اگر از receiver تعیین شده در manifest استفاده کنید، می‌تواند باعث شود بسیاری از برنامه‌ها توسط سیستم اجرا شوند و هم می‌تواند بر عملکرد دستگاه و هم تجربه استفاده از برنامه اثر بگذارد.

2- هرگز داده‌های حساس را با استفاده از Intent ضمنی Broadcast نکنید. در این حالت اطلاعات می‌تواند توسط هر برنامه‌ای که برای دریافت Broadcast ثبت شده است، خوانده شود. روش‌های زیر برای کنترل آن وجود دارد:

  • می‌توانید هنگام ارسال Broadcast مجوز تعیین کنید
  • در اندروید نسخه 4.0 و بالاتر، هنگام ارسال Broadcast می‌توانید نام بسته را با setPackage() مشخص کنید. بنابراین سیستم اندروید Broadcast را به برنامه‌هایی که با بسته ارسال شده مطابقت دارند محدود می‌کند
  • می‌توانید Broadcastهای محلی را با LocalBroadcastManager ارسال کنید

4- در حین دریافت هرگونه Broadcast، ممکن است دریافت کننده برنامه شما Broadcastهای مخربی را دریافت کند. روش‌های زیر برای محدود کردن آن‌ها وجود دارد:

  • می‌توان هنگام ثبت Broadcast مجوزهایی را برای آن تعیین کرد
  • برای receiverهای ثبت شده در manifest، می‌توانید ویژگی android:exported را false کنید تا مانع از Broadcastهای خارج از برنامه شوید

5- متد (onReceive(Context, Intent برروی thread اصلی اجرا می‌شود، بنابراین باید سریع اجرا و return شود. اگر شما نیاز به انجام عملیات طولانی دارید، مراقب باشید که یک thread جدید بسازید و یا یک سرویس را شروع کنید، زیرا ممکن است سیستم پس از return شدن onReceive() فرایند را از بین ببرد.

6- هرگز اکتیویتی را از BroadcastReceiver اجرا نکنید، زیرا یک تجریه ناخوشایند برای کاربر ایجاد می‌کند.

منبع

گردآوری و تالیف پوریا شریفی

ابتدا که با برنامه‌نویسی آشنا شدم به سمت php و طراحی وب رفتم، بعد از اون به توسعه‌ی اندروید علاقه‌مند شدم و تقریبا ۲ سال است که مشغول به برنامه‌نویسی اندروید هستم، همچنین عاشق یادگیری چیزهای جدید هستم.