Bagikan melalui


Broadcast Receivers di Xamarin.Android

Bagian ini membahas cara menggunakan Penerima Siaran.

Gambaran Umum Penerima Siaran

Penerima siaran adalah komponen Android yang memungkinkan aplikasi merespons pesan (AndroidIntent) yang disiarkan oleh sistem operasi Android atau oleh aplikasi. Siaran mengikuti model terbitkan-berlangganan - peristiwa menyebabkan siaran diterbitkan dan diterima oleh komponen yang tertarik dengan peristiwa tersebut.

Android mengidentifikasi dua jenis siaran:

  • Siaran eksplisit – Jenis siaran ini menargetkan aplikasi tertentu. Penggunaan paling umum dari siaran eksplisit adalah memulai Aktivitas. Contoh siaran eksplisit saat aplikasi perlu menghubungi nomor telepon; ini akan mengirimkan Niat yang menargetkan aplikasi Telepon di Android dan meneruskan nomor telepon yang akan diputar. Android kemudian akan merutekan niat ke aplikasi Telepon.
  • Siaran implisit - Siaran ini dikirim ke semua aplikasi di perangkat. Contoh siaran implisit adalah niatnya ACTION_POWER_CONNECTED . Niat ini diterbitkan setiap kali Android mendeteksi bahwa baterai pada perangkat sedang diisi dayanya. Android akan merutekan niat ini ke semua aplikasi yang telah mendaftar untuk acara ini.

Penerima siaran adalah subkelas dari BroadcastReceiver jenis dan harus mengambil alih OnReceive metode . Android akan dijalankan OnReceive pada utas utama, sehingga metode ini harus dirancang untuk dijalankan dengan cepat. Perawatan harus diambil saat menelurkan utas karena OnReceive Android dapat mengakhiri proses ketika metode selesai. Jika penerima siaran harus melakukan pekerjaan jangka panjang, disarankan untuk menjadwalkan pekerjaan menggunakan JobScheduler atau Firebase Job Dispatcher. Penjadwalan pekerjaan dengan pekerjaan akan dibahas dalam panduan terpisah.

Filter niat digunakan untuk mendaftarkan penerima siaran sehingga Android dapat merutekan pesan dengan benar. Filter niat dapat ditentukan pada runtime (ini kadang-kadang disebut sebagai penerima yang terdaftar konteks atau sebagai pendaftaran dinamis) atau dapat ditentukan secara statis dalam Manifes Android ( penerima terdaftar manifes). Xamarin.Android menyediakan atribut C#, IntentFilterAttribute, yang akan secara statis mendaftarkan filter niat (ini akan dibahas secara lebih rinci nanti dalam panduan ini). Mulai dari Android 8.0, aplikasi tidak dapat mendaftar secara statis untuk siaran implisit.

Perbedaan utama antara penerima terdaftar manifes dan penerima yang terdaftar konteks adalah bahwa penerima yang terdaftar konteks hanya akan merespons siaran saat aplikasi berjalan, sementara penerima terdaftar manifes dapat merespons siaran meskipun aplikasi mungkin tidak berjalan.

Ada dua set API untuk mengelola penerima siaran dan mengirim siaran:

  1. Context – Kelas Android.Content.Context dapat digunakan untuk mendaftarkan penerima siaran yang akan merespons peristiwa di seluruh sistem. ini Context juga digunakan untuk menerbitkan siaran di seluruh sistem.
  2. LocalBroadcastManager – Ini adalah API yang tersedia melalui paket Xamarin Support Library v4 NuGet. Kelas ini digunakan untuk menjaga siaran dan penerima siaran terisolasi dalam konteks aplikasi yang menggunakannya. Kelas ini dapat berguna untuk mencegah aplikasi lain merespons siaran khusus aplikasi atau mengirim pesan ke penerima privat.

Penerima siaran mungkin tidak menampilkan dialog, dan sangat tidak disarankan untuk memulai aktivitas dari dalam penerima siaran. Jika penerima siaran harus memberi tahu pengguna, maka harus menerbitkan pemberitahuan.

Tidak dimungkinkan untuk mengikat atau memulai layanan dari dalam penerima siaran.

Panduan ini akan membahas cara membuat penerima siaran dan cara mendaftarkannya sehingga dapat menerima siaran.

Membuat Penerima Siaran

Untuk membuat penerima siaran di Xamarin.Android, aplikasi harus mensubkelas BroadcastReceiver kelas, menghiasinya dengan BroadcastReceiverAttribute, dan mengambil alih OnReceive metode :

[BroadcastReceiver(Enabled = true, Exported = false)]
public class SampleReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        // Do stuff here.

        String value = intent.GetStringExtra("key");
    }
}

Saat Xamarin.Android mengkompilasi kelas, Xamarin.Android juga akan memperbarui AndroidManifest dengan meta-data yang diperlukan untuk mendaftarkan penerima. Untuk penerima siaran yang terdaftar secara statis, Enabled yang benar harus diatur ke true, jika tidak, Android tidak akan dapat membuat instans penerima.

Properti Exported mengontrol apakah penerima siaran dapat menerima pesan dari luar aplikasi. Jika properti tidak diatur secara eksplisit, nilai default properti ditentukan oleh Android berdasarkan jika ada filter niat yang terkait dengan penerima siaran. Jika setidaknya ada satu filter niat untuk penerima siaran, Maka Android akan mengasumsikan bahwa Exported properti tersebut adalah true. Jika tidak ada filter niat yang terkait dengan penerima siaran, maka Android akan mengasumsikan bahwa nilainya adalah false.

Metode ini OnReceive menerima referensi ke Intent yang dikirim ke penerima siaran. Ini memungkinkan pengirim niat untuk meneruskan nilai ke penerima siaran.

Mendaftarkan Penerima Siaran secara statis dengan Filter Niat

Ketika dihiasi dengan IntentFilterAttribute, Xamarin.Android akan menambahkan elemen yang BroadcastReceiver diperlukan <intent-filter> ke manifes Android pada waktu kompilasi. Cuplikan berikut adalah contoh penerima siaran yang akan berjalan ketika perangkat telah selesai melakukan booting (jika izin Android yang sesuai diberikan oleh pengguna):

[BroadcastReceiver(Enabled = true)]
[IntentFilter(new[] { Android.Content.Intent.ActionBootCompleted })]
public class MyBootReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        // Work that should be done when the device boots.     
    }
}

Catatan

Di Android 8.0 (API 26 ke atas), Google menempatkan batasan pada apa yang dapat dilakukan aplikasi saat pengguna tidak berinteraksi langsung dengan mereka. Batasan ini memengaruhi layanan latar belakang dan penerima siaran implisit seperti Android.Content.Intent.ActionBootCompleted. Karena keterbatasan ini, Anda mungkin mengalami kesulitan mendaftarkan Boot Completed penerima siaran pada versi Android yang lebih baru. Jika demikian, perhatikan bahwa pembatasan ini tidak berlaku untuk layanan latar depan, yang dapat dipanggil dari penerima siaran Anda.

Dimungkinkan juga untuk membuat filter niat yang akan merespons niat kustom. Pertimbangkan contoh berikut:

[BroadcastReceiver(Enabled = true)]
[IntentFilter(new[] { "com.xamarin.example.TEST" })]
public class MySampleBroadcastReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        // Do stuff here
    }
}

Aplikasi yang menargetkan Android 8.0 (API level 26) atau yang lebih tinggi mungkin tidak mendaftar secara statis untuk siaran implisit. Aplikasi mungkin masih mendaftar secara statis untuk siaran eksplisit. Ada daftar kecil siaran implisit yang dikecualikan dari pembatasan ini. Pengecualian ini dijelaskan dalam panduan Pengecualian Siaran Implisit dalam dokumentasi Android. Aplikasi yang tertarik dengan siaran implisit harus melakukannya secara dinamis menggunakan metode .RegisterReceiver Ini dijelaskan selanjutnya.

Mendaftarkan Konteks Penerima Siaran

Pendaftaran konteks (juga disebut sebagai pendaftaran dinamis) penerima dilakukan dengan memanggil RegisterReceiver metode , dan penerima siaran harus tidak terdaftar dengan panggilan ke UnregisterReceiver metode . Untuk mencegah kebocoran sumber daya, penting untuk membatalkan pendaftaran penerima ketika tidak lagi relevan untuk konteks (Aktivitas atau layanan). Misalnya, layanan dapat menyiarkan niat untuk menginformasikan Aktivitas bahwa pembaruan tersedia untuk ditampilkan kepada pengguna. Ketika Aktivitas dimulai, Aktivitas akan mendaftar untuk Niat tersebut. Ketika Aktivitas dipindahkan ke latar belakang dan tidak lagi terlihat oleh pengguna, aktivitas harus membatalkan pendaftaran penerima karena UI untuk menampilkan pembaruan tidak lagi terlihat. Cuplikan kode berikut adalah contoh cara mendaftar dan membatalkan pendaftaran penerima siaran dalam konteks Aktivitas:

[Activity(Label = "MainActivity", MainLauncher = true, Icon = "@mipmap/icon")]
public class MainActivity: Activity
{
    MySampleBroadcastReceiver receiver;

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        receiver = new MySampleBroadcastReceiver();

        // Code omitted for clarity
    }

    protected override void OnResume()
    {
        base.OnResume();
        RegisterReceiver(receiver, new IntentFilter("com.xamarin.example.TEST"));
        // Code omitted for clarity
    }

    protected override void OnPause()
    {
        UnregisterReceiver(receiver);
        // Code omitted for clarity
        base.OnPause();
    }
}

Dalam contoh sebelumnya, ketika Aktivitas masuk ke latar depan, itu akan mendaftarkan penerima siaran yang akan mendengarkan niat kustom dengan menggunakan OnResume metode siklus hidup. Saat Aktivitas berpindah ke latar belakang, OnPause() metode akan membatalkan pendaftaran penerima.

Menerbitkan Siaran

Siaran dapat dipublikasikan ke semua aplikasi yang diinstal pada perangkat yang membuat objek Niat dan mengirimkannya dengan SendBroadcast metode atau SendOrderedBroadcast .

  1. Metode Context.SendBroadcast – Ada beberapa implementasi metode ini. Metode ini akan menyiarkan niat ke seluruh sistem. Penerima siaran yang akan menerima niat dalam urutan yang tidak ditentukan. Ini memberikan banyak fleksibilitas tetapi berarti bahwa mungkin bagi aplikasi lain untuk mendaftar dan menerima niat. Hal ini dapat menimbulkan potensi risiko keamanan. Aplikasi mungkin perlu menerapkan keamanan penambahan untuk mencegah akses yang tidak sah. Salah satu solusi yang mungkin adalah menggunakan LocalBroadcastManager yang hanya akan mengirim pesan dalam ruang privat aplikasi. Cuplikan kode ini adalah salah satu contoh cara mengirimkan niat menggunakan salah SendBroadcast satu metode:

    Intent message = new Intent("com.xamarin.example.TEST");
    // If desired, pass some values to the broadcast receiver.
    message.PutExtra("key", "value");
    SendBroadcast(message);
    

    Cuplikan ini adalah contoh lain dari mengirim siaran dengan menggunakan Intent.SetAction metode untuk mengidentifikasi tindakan:

    Intent intent = new Intent();
    intent.SetAction("com.xamarin.example.TEST");
    intent.PutExtra("key", "value");
    SendBroadcast(intent);
    
  2. Context.SendOrderedBroadcast – Metode ini sangat mirip Context.SendBroadcastdengan , dengan perbedaan bahwa niat akan diterbitkan satu per satu kepada penerima, dalam urutan penerima terdaftar.

LocalBroadcastManager

Pustaka Dukungan Xamarin v4 menyediakan kelas pembantu yang disebut LocalBroadcastManager. LocalBroadcastManager ditujukan untuk aplikasi yang tidak ingin mengirim atau menerima siaran dari aplikasi lain di perangkat. hanya LocalBroadcastManager akan menerbitkan pesan dalam konteks aplikasi, dan hanya untuk penerima siaran yang terdaftar di LocalBroadcastManager. Cuplikan kode ini adalah contoh mendaftarkan penerima siaran dengan LocalBroadcastManager:

Android.Support.V4.Content.LocalBroadcastManager.GetInstance(this). RegisterReceiver(receiver, new IntentFilter("com.xamarin.example.TEST"));

Aplikasi lain di perangkat tidak dapat menerima pesan yang diterbitkan dengan LocalBroadcastManager. Cuplikan kode ini menunjukkan cara mengirimkan Niat menggunakan LocalBroadcastManager:

Intent message = new Intent("com.xamarin.example.TEST");
// If desired, pass some values to the broadcast receiver.
message.PutExtra("key", "value");
Android.Support.V4.Content.LocalBroadcastManager.GetInstance(this).SendBroadcast(message);