Minggu, September 30, 2018

Dasar Android : Penerima Siaran

Penerima Siaran

Materi:
Maksud eksplisit digunakan untuk memulai aktivitas tertentu yang benar-benar memenuhi syarat, serta untuk meneruskan informasi di antara aktivitas di aplikasi Anda. Maksud implisit digunakan untuk memulai aktivitas berdasarkan komponen terdaftar yang diketahui sistem, misalnya fungsionalitas umum.
Dalam pelajaran ini Anda akan mempelajari tentang maksud siaran, yang tidak memulai aktivitas namun dikirimkan ke penerima siaran.

Maksud siaran

Maksud yang telah Anda lihat sejauh ini selalu menghasilkan aktivitas yang akan diluncurkan, baik aktivitas tertentu dari aplikasi Anda maupun aktivitas dari aplikasi lain yang bisa memenuhi aksi yang diminta. Namun kadang-kadang maksud tidak memiliki penerima tertentu, dan kadang-kadang Anda tidak ingin aktivitas diluncurkan sebagai respons terhadap maksud. Misalnya, bila aplikasi Anda menerima maksud sistem yang menunjukkan bahwa keadaan jaringan di perangkat sudah berubah, Anda mungkin tidak ingin meluncurkan aktivitas, melainkan mungkin ingin menonaktifkan beberapa fungsionalitas aplikasi.
Karena alasan ini, ada tipe maksud ketiga yang bisa dikirimkan ke aplikasi yang tertarik: maksud siaran. Meskipun maksud siaran didefinisikan dengan cara yang sama seperti maksud implisit, setiap tipe maksud memiliki karakteristik pembeda yang penting:
  • Maksud siaran dikirim menggunakan sendBroadcast() atau metode terkait, sementara tipe maksud lainnya menggunakan startActivity() untuk memulai aktivitas. Bila menyiarkan maksud, Anda tidak akan pernah menemukan atau memulai aktivitas. Demikian juga, tidak ada cara bagi penerima siaran untuk melihat atau menangkap maksud yang digunakan bersama startActivity().
  • Maksud siaran adalah operasi latar belakang yang biasanya tidak diketahui pengguna. Memulai aktivitas bersama maksud, di sisi lain, adalah operasi latar depan yang memodifikasi apa yang sedang berinteraksi dengan pengguna.
Ada dua tipe maksud siaran, yang dikirimkan oleh sistem (maksud siaran sistem), dan yang dikirimkan oleh aplikasi Anda (maksud siaran khusus).

Maksud siaran sistem

Sistem mengirimkan maksud siaran sistem bila ada kejadian sistem yang mungkin menarik aplikasi. Misalnya:
  • Bila perangkat sedang booting, sistem akan mengirim sebuah maksud siaran sistem ACTION_BOOT_COMPLETED . Maksud ini berisi nilai konstanta "android.intent.action.BOOT_COMPLETED".
  • Bila perangkat terhubung ke daya eksternal, sistem akan mengirim ACTION_POWER_CONNECTED, yang berisi nilai konstanta "android.intent.action.ACTION_POWER_CONNECTED". Bila perangkat terlepas dari daya eksternal, sistem akan mengirim ACTION_POWER_DISCONNECTED.
  • Bila memori perangkat minim, sistem akan mengirim ACTION_DEVICE_STORAGE_LOW. Maksud ini berisi nilai konstanta "android.intent.action.DEVICE_STORAGE_LOW".
ACTION_DEVICE_STORAGE_LOW merupakan siaran melekat, maksudnya adalah nilai siaran bertahan di cache. Jika Anda perlu mengetahui apakah penerima siaran memproses nilai yang ada di cache (melekat) atau nilai yang disiarkan pada saat ini, gunakan isInitialStickyBroadcast().
Untuk informasi selengkapnya tentang siaran sistem umum, kunjungi referensi Intent .
Untuk menerima maksud siaran sistem, Anda perlu membuat penerima siaran.

Maksud siaran khusus

Maksud siaran khusus adalah maksud siaran yang dikirim aplikasi Anda. Gunakan maksud siaran khusus bila Anda ingin agar aplikasi mengambil suatu aksi tanpa meluncurkan aktivitas, misalnya bila Anda ingin membiarkan aplikasi lainnya mengetahui bahwa data telah diunduh ke perangkat dan tersedia untuk digunakan.
Untuk membuat maksud siaran khusus, buat aksi maksud khusus. Untuk mengirim siaran khusus ke aplikasi lainnya, teruskan maksud ke sendBroadcast()sendOrderedBroadcast(), atau sendStickyBroadcast(). (Untuk detail tentang metode ini, lihat dokumentasi referensi Context .)
Misalnya, metode berikut membuat sebuah maksud dan menyiarkannya ke semua [penerima siaran] yang tertarik(#broadcast_receivers):
public void sendBroadcastIntent() {
Intent intent = new Intent();
intent.setAction("com.example.myproject.ACTION_SHOW_TOAST");
sendBroadcast(intent);
}
Catatan: Bila Anda menetapkan aksi untuk maksud, gunakan nama paket unik (com.example.myproject dalam contoh) untuk memastikan maksud tersebut tidak konflik dengan maksud yang disiarkan dari aplikasi lain atau dari sistem.

Penerima siaran

Maksud siaran tidak ditargetkan pada penerima tertentu. Sebagai gantinya, aplikasi yang tertarik mendaftarkan komponen untuk "mendengarkan" jenis maksud ini. Komponen pendengar ini disebut penerima siaran.
Gunakan penerima siaran untuk merespons pesan yang disiarkan dari aplikasi lain atau dari sistem. Untuk membuat penerima siaran:
  1. Definisikan sub kelas dari kelas BroadcastReceiver dan implementasikan metode onReceive() .
  2. Daftarkan penerima siaran secara dinamis di Java, atau secara statis di file manifes aplikasi Anda.
    Sebagai bagian dari langkah ini, gunakan filter maksud untuk menetapkan jenis maksud siaran yang ingin Anda terima.
Langkah-langkah ini dijelaskan di bawah.

Definisikan subkelas BroadcastReceiver

Untuk membuat penerima siaran, definisikan subkelas dari kelas BroadcastReceiver . Di subkelas inilah maksud dikirim (jika cocok dengan filter maksud yang Anda setel saat mendaftarkan subkelas, yang terjadi di langkah berikutnya).
Dalam definisi subkelas Anda:
  • Implementasikan metode onReceive() yang diperlukan.
  • Sertakan logika apa pun yang diperlukan penerima siaran Anda.

Contoh: Buat penerima siaran

Dalam contoh ini, subkelas AlarmReceiver dari BroadcastReceiver menampilkan pesan Toast jika maksud siaran yang masuk memiliki aksi ACTION_SHOW_TOAST:
private class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_SHOW_TOAST)) {
int duration = Toast.LENGTH_SHORT;
CharSequence text = "Broadcast Received!";
}
Toast toast = Toast.makeText(context, text, duration); toast.show(); }
}
Catatan: Jangan menggunakan operasi asinkron dalam implementasi onReceive(), karena setelah kode Anda kembali dari onReceive(), sistem akan menganggap objek BroadcastReceiver akan diselesaikan. Jika onReceive() memulai operasi asinkron, sistem akan mematikan proses BroadcastReceiver sebelum operasi asinkron memiliki kesempatan untuk diselesaikan.
Jika Anda memerlukan operasi yang berjalan lama yang tidak memerlukan UI, gunakan Service yang diluncurkan dari penerima siaran. Khususnya:
  • Anda tidak bisa menampilkan dialog dari dalam BroadcastReceiver. Sebagai gantinya, gunakan NotificationManager API.
  • Anda tidak bisa mengikat ke layanan dari dalam BroadcastReceiver. Sebagai gantinya, gunakan Context.startService() untuk mengirim perintah ke layanan.

Mendaftarkan penerima siaran Anda dan menyetel filter maksud

Ada dua cara untuk mendaftarkan penerima siaran: secara statis di manifes, atau secara dinamis di aktivitas Anda.

Pendaftaran statis

Untuk mendaftarkan penerima siaran secara statis, tambahkan elemen  ke file AndroidManifest.xml Anda. Dalam elemen  :
  • Gunakan jalur ke subkelas BroadcastReceiver sebagai atribut android:name .
  • Untuk mencegah aplikasi lain mengirim siaran ke penerima Anda, setel atribut android:exportedopsional ke false. Ini adalah [panduan keamanan] penting(#security).
  • Untuk menetapkan tipe maksud yang akan didengarkan komponen, gunakan elemen  yang disarangkan.

Contoh: Pendaftaran statis dan filter maksud untuk maksud siaran khusus

Cuplikan kode berikut adalah contoh pendaftaran statis untuk penerima siaran yang mendengarkan maksud siaran khusus bersama "ACTION_SHOW_TOAST" dalam nama aksinya:
  • name penerima adalah nama modul ditambah nama subkelas BroadcastReceiver yang didefinisikan di atas (AlarmReceiver).
  • Penerima tidak diekspor, berarti tidak ada aplikasi lain yang bisa mengirim siaran ke aplikasi ini.
  • Penerima menyertakan filter maksud yang memeriksa apakah maksud yang masuk menyertakan aksi bernama ACTION_SHOW_TOAST.
    android:name="com.example.myproject.AlarmReceiver"
    android:exported="false">

Filter maksud

Bila sistem menerima maksud implisit untuk memulai aktivitas, sistem akan menelusuri aktivitas terbaik bagi maksud tersebut dengan membandingkannya dengan filter maksud, berdasarkan tiga aspek:
  • Aksi: Apakah aksi yang ditetapkan dalam maksud cocok dengan salah satu nama  yang tercantum dalam filter? Dalam contoh di atas, hanya maksud yang berisi ACTION_SHOW_TOAST dalam nama aksinya yang akan cocok dengan filter tersebut.
  • Data: Apakah data dalam maksud cocok dengan salah satu tipe  yang tercantum dalam filter?
  • Kategori: Apakah setiap kategori dalam maksud cocok dengan  yang namanya disebutkan dalam filter?

Contoh: Filter maksud untuk maksud siaran sistem

Contoh ini menampilkan filter maksud bagi penerima yang mendengarkan perangkat untuk menyelesaikan booting:
Untuk mengetahui selengkapnya tentang menggunakan filter maksud guna memilih maksud, lihat bagian Resolusi Maksud pada panduan maksud.
Jika tidak ada filter maksud yang ditetapkan, penerima siaran hanya bisa diaktifkan dengan maksud siaran eksplisit yang memberi nama komponen berdasarkan nama. (Tindakan ini mirip dengan cara Anda meluncurkan aktivitas melalui nama kelasnya bersama maksud eksplisit.)
Jika Anda menggunakan pendaftaran statis untuk penerima siaran, sistem Android akan membuat proses baru untuk menjalankan penerima siaran jika tidak ada proses berjalan yang dikaitkan dengan aplikasi Anda. Ini berarti penerima akan merespons, sekalipun aplikasi Anda tidak berjalan.

Pendaftaran dan menghapus pendaftaran dinamis

Anda juga bisa mendaftarkan penerima siaran secara dinamis, yang mengikat operasinya ke daur hidup aktivitas. Untuk mendaftarkan penerima Anda secara dinamis, panggil registerReceiver() dan teruskan objek BroadcastReceiver dan filter maksud. Misalnya:
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ACTION_SHOW_TOAST);
registerReceiver(mReceiver, intentFilter);
mReceiver = new AlarmReceiver();
Catatan: Jika mendaftarkan penerima untuk menerima siaran lokal saja, Anda harus mendaftarkannya secara dinamis; pendaftaran statis bukanlah opsi.
Anda juga perlu mencabut pendaftaran penerima dengan memanggil unregisterReceiver() dan meneruskan objek BroadcastReceiver . Misalnya:
unregisterReceiver(mReceiver);
Tempat Anda memanggil metode ini bergantung pada daur hidup yang diinginkan objek BroadcastReceiver :
  • Jika penerima hanya diperlukan bila aktivitas terlihat (misalnya, untuk menonaktifkan fungsi jaringan bila jaringan tidak tersedia), maka daftarkan penerima di onResume(). Hapus pendaftaran penerima di onPause().
  • Anda juga bisa menggunakan pasangan metode onStart()/onStop() atau onCreate()/onDestoy() , jika pasangan tersebut lebih tepat untuk kasus penggunaan Anda.

Panduan keamanan

Bila Anda menggunakan maksud siaran dan penerima siaran, informasi akan dikirim di antara aplikasi, yang akan menimbulkan risiko keamanan. Untuk menghindari risiko ini, Anda bisa menggunakan LocalBroadcastManager (dijelaskan di bawah ini), atau Anda bisa mengikuti panduan ini:
  • Pastikan nama tindakan maksud dan string lainnya ada dalam namespace yang Anda miliki, jika tidak maka Anda akan mengalami konflik dengan aplikasi lain secara tidak sengaja. Namespace maksud bersifat global.
  • Bila Anda menggunakan registerReceiver(), aplikasi apa pun bisa mengirim siaran ke penerima yang didaftarkan itu. Untuk mengontrol siapa yang bisa mengirimkan siaran, gunakan izin yang dijelaskan di bawah ini.
  • Bila Anda mendaftarkan penerima siaran secara statis, aplikasi lainnya bisa mengirim siaran ke penerima tersebut, filter apa pun yang Anda tetapkan. Untuk mencegah aplikasi lain mengirim ke penerima tersebut, jadikan aplikasi itu tidak tersedia dengan android:exported="false".
  • Bila Anda menggunakan sendBroadcast() atau metode terkait, aplikasi lain akan bisa menerima siaran Anda. Untuk mengontrol siapa saja yang bisa menerima siaran tersebut, gunakan izin yang dijelaskan di bawah ini.
Baik pengirim maupun penerima siaran bisa memberlakukan izin akses:
  • Untuk memberlakukan izin saat mengirim siaran, berikan argumen izin bukan-nol ke sendBroadcast().
    Hanya penerima yang telah diberi izin ini (dengan memintanya melalui tag  di AndroidManifest.xml) yang akan bisa menerima siaran.
  • Untuk memberlakukan izin saat menerima siaran, berikan izin bukan-nol saat mendaftarkan penerima Anda, baik saat memanggil registerReceiver() maupun dalam tag statis  di AndroidManifest.xml.
    Hanya penyiar yang telah diberi izin ini (dengan memintanya melalui tag  di AndroidManifest.xml) yang akan bisa mengirimkan maksud ke penerima. Penerima harus meminta izin di manifes, terlepas apakah pengirim didaftarkan secara statis atau dinamis.

[LocalBroadcastManager]

Agar tidak perlu menangani aspek keamanan yang dijelaskan dalam Panduan keamanan, gunakan kelas LocalBroadcastManager . LocalBroadcastManager memungkinkan Anda mengirim dan menerima siaran dalam satu proses dan satu aplikasi, sehingga Anda tidak perlu khawatir tentang keamanan lintas aplikasi.

Mengirim siaran lokal

Untuk mengirim siaran menggunakan LocalBroadcastManager:
  1. Dapatkan instance LocalBroadcastManager dengan memanggil getInstance() dan meneruskan konteks aplikasi.
  2. Panggil sendBroadcast() di instance, dengan meneruskan maksud yang ingin disiarkan.
Misalnya:
LocalBroadcastManager.getInstance(this).sendBroadcast(customBroadcastIntent);

Mendaftarkan penerima Anda untuk siaran lokal

Untuk mendaftarkan penerima Anda guna menerima siaran lokal saja:
  1. Dapatkan instance LocalBroadcastManager dengan memanggil getInstance() dan meneruskan konteks aplikasi.
  2. Panggil registerReceiver(), dengan meneruskan penerima dan filter maksud seperti yang diinginkan untuk penerima siaran biasa. Anda harus mendaftarkan penerima lokal secara dinamis, karena pendaftaran statis di manifes tidak tersedia.
Misalnya:
LocalBroadcastManager.getInstance(this).registerReceiver
(mReceiver, new IntentFilter(CustomReceiver.ACTION_CUSTOM_BROADCAST));
Untuk mencabut pendaftaran penerima siaran:
LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);