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:
Context
– KelasAndroid.Content.Context
dapat digunakan untuk mendaftarkan penerima siaran yang akan merespons peristiwa di seluruh sistem. iniContext
juga digunakan untuk menerbitkan siaran di seluruh sistem.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
.
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 salahSendBroadcast
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);
Context.SendOrderedBroadcast – Metode ini sangat mirip
Context.SendBroadcast
dengan , 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);