Secara terprogram mendaftarkan penerima siaran

149

Saya ingin tahu apa cara / cara terbaik mendaftarkan penerima siaran secara terprogram. Saya ingin mendaftarkan penerima tertentu sesuai dengan pilihan pengguna.

Karena pendaftaran dilakukan melalui file manifes, saya bertanya-tanya apakah ada cara yang tepat untuk mencapai ini dalam kode.

CoolStraw
sumber
2
CoderzPassion Broadcast Reciever, tutorial detail terbaik yang pernah ada
karanatwal.github.io
Silakan merujuk Tautan ini stackoverflow.com/questions/15698790/…

Jawaban:

64

Sepertinya Anda ingin mengontrol apakah komponen yang diterbitkan dalam manifes Anda aktif, tidak secara dinamis mendaftarkan penerima (melalui Context.registerReceiver ()) saat berjalan.

Jika demikian, Anda dapat menggunakan PackageManager.setComponentEnabledSetting () untuk mengontrol apakah komponen ini aktif:

http://developer.android.com/reference/android/content/pm/PackageManager.html#setComponentEnabledSetting(android.content.ComponentName, int, int)

Catatan jika Anda hanya tertarik menerima siaran saat Anda menjalankan, lebih baik menggunakan registerReceiver (). Komponen penerima terutama berguna ketika Anda perlu memastikan aplikasi Anda diluncurkan setiap kali siaran dikirim.

hackbod
sumber
1
Pandai! Anda membuat saya lurus. Terima kasih banyak
CoolStraw
Bagus - tidak tahu Anda bisa melakukan ini :)
Chris Noldus
itu mirip dengan stackoverflow.com/questions/24140894/…
Ankit Srivastava
1
@hackbod Bagaimana cara menambahkan tag meta-data di penerima kustom? Apakah Anda punya ide !! Saya perlu menambahkan tag meta-data yang mana yang kami gunakan di androidmanifest.xml.
Zala Janaksinh
1
Tutorial terbaik hingga tanggal coderzpassion.com/implement-broadcastreceiver-android dan dalam bahasa yang sederhana
Jagjit Singh
269

Dalam onCreatemetode Anda, Anda dapat mendaftarkan penerima seperti ini:

private BroadcastReceiver receiver;

@Override
public void onCreate(Bundle savedInstanceState){

  // your oncreate code should be

  IntentFilter filter = new IntentFilter();
  filter.addAction("SOME_ACTION");
  filter.addAction("SOME_OTHER_ACTION");

  receiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
      //do something based on the intent's action
    }
  };
     registerReceiver(receiver, filter);
}

Ingatlah untuk menjalankan ini dalam onDestroymetode:

 @Override
 protected void onDestroy() {
  if (receiver != null) {
   unregisterReceiver(receiver);
   receiver = null;
  }
  super.onDestroy();
 }
Eric Nordvik
sumber
19
Terima kasih, ini berhasil. Untuk mengirim siaran saya menggunakan kode Intent i = new Intent ("SOME_ACTION"); sendBroadcast (i);
Ben Clayton
7
mengapa tidak melanjutkan dan memulai?
Syed Raza Mehdi
Apa yang akan terjadi jika saya tidak membatalkan registrasi penerima siaran? Apakah akan membiarkan penerima siaran terdaftar, bahkan setelah reboot?
Jaydev
5
Itu tidak dijamin yang onDestroy()akan dipanggil, sehingga menciptakan potensi kebocoran memori. Lebih baik mendaftar / tidak mendaftar di onStart()/ onStop().
Neria Nachum
Apakah ini berarti saya tidak perlu membuat kelas penerima siaran? Saya hanya bisa meletakkan semua kode onReceive () saya di sini dan itu akan berhasil?
Taslim Oseni
70

Satu poin penting yang orang lupa sebutkan adalah waktu hidup Broadcast Receiver. Perbedaan pemrograman mendaftar itu dari mendaftar di AndroidManifest.xml adalah itu. Dalam file manifes, itu tidak bergantung pada waktu hidup aplikasi. Sementara ketika mendaftar secara program itu tergantung pada waktu hidup aplikasi. Ini berarti bahwa jika Anda mendaftar di AndroidManifest.xml , Anda dapat menangkap maksud yang disiarkan meskipun aplikasi Anda tidak berjalan.

Sunting: Catatan yang disebutkan tidak lagi berlaku untuk Android 3.1, sistem Android mengecualikan semua penerima dari menerima maksud secara default jika aplikasi yang sesuai tidak pernah dimulai oleh pengguna atau jika pengguna secara eksplisit menghentikan aplikasi melalui menu Android (dalam Kelola → Aplikasi). https://developer.android.com/about/versions/android-3.1.html

Ini adalah fitur keamanan tambahan karena pengguna dapat yakin bahwa hanya aplikasi yang ia mulai akan menerima maksud siaran.

Jadi itu dapat dipahami karena penerima yang terdaftar secara program di Aplikasi onCreate()akan memiliki efek yang sama dengan yang dinyatakan dalam AndroidManifest.xml dari Android 3.1 di atas.

Krypton
sumber
1
Ini catatan yang bagus. Saya benar-benar melihat buku yang saya baca tentang android dan bertanya-tanya mengapa kedua metode implementasi siaran telah dilakukan. Tampaknya bagi saya itu untuk kompatibilitas ke belakang. Tapi saya tidak yakin.
Neon Warge
Nah, apakah Anda benar-benar menganggap bahwa pengeditan itu benar? Maksud saya kalimat terakhir. Android kemungkinan akan mematikan aplikasi Anda kapan saja, yang akan mengakibatkan penerima Anda yang terdaftar secara program tidak berfungsi lagi, tetapi manifes yang terdaftar masih akan berfungsi.
JacksOnF1re
40

Tetapkan penerima siaran di mana saja di Activity / Fragment seperti ini:

mReceiver = new BroadcastReceiver() {
 @Override
 public void onReceive(Context context, Intent intent) {
     Log.d(TAG," onRecieve"); //do something with intent
   }
 };

Tentukan IntentFilter di onCreate()

mIntentFilter=new IntentFilter("action_name");

Sekarang daftarkan BroadcastReciever onResume()dan Batalkan registrasi di onPause()[karena tidak ada penggunaan siaran jika aktivitas dijeda].

@Override
protected void onResume() {
     super.onResume();
     registerReceiver(mReceiver, mIntentFilter);
}

@Override
protected void onPause() {
    if(mReceiver != null) {
            unregisterReceiver(mReceiver);
            mReceiver = null;
    }
    super.onPause();
}

Untuk tutorial detail, lihat penerima siaran-dua cara untuk mengimplementasikan .

SohailAziz
sumber
contoh terbaik sejauh ini yang saya temukan! Terima kasih!
Ayush Goyal
1
@SohailAziz Tautan ini memberikan jawaban yang bagus. Bisakah Anda meletakkan konteks tautan dalam jawaban Anda, sehingga jika tautannya turun, jawaban Anda tetap relevan?
iRuth
dalam pandangan pribadi saya, siaran harus terdaftar di onResume dan onPause seperti yang Anda sarankan tetapi beberapa orang mengatakan itu harus di onCreate dan onDestroy, dapatkah Anda menjelaskan pro dan kontra untuk keduanya?
Syed Raza Mehdi
2
@SyedRazaMehdi jika siaran digunakan untuk memperbarui UI [yang dalam kebanyakan kasus] Anda harus mendaftarkannya di onResume dan membatalkan pendaftaran di onPause karena siaran akan menjadi tidak berguna jika tidak.
SohailAziz
Terima kasih. Ini jawaban terbaik.
Saeid Z
4
package com.example.broadcastreceiver;


import android.app.Activity;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends Activity {

   UserDefinedBroadcastReceiver broadCastReceiver = new UserDefinedBroadcastReceiver();

   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
   }

   @Override
   public boolean onCreateOptionsMenu(Menu menu) {
      getMenuInflater().inflate(R.menu.main, menu);
      return true;
   }

   /**
    * This method enables the Broadcast receiver for
    * "android.intent.action.TIME_TICK" intent. This intent get
    * broadcasted every minute.
    *
    * @param view
    */
   public void registerBroadcastReceiver(View view) {

      this.registerReceiver(broadCastReceiver, new IntentFilter(
            "android.intent.action.TIME_TICK"));
      Toast.makeText(this, "Registered broadcast receiver", Toast.LENGTH_SHORT)
            .show();
   }

   /**
    * This method disables the Broadcast receiver
    *
    * @param view
    */
   public void unregisterBroadcastReceiver(View view) {

      this.unregisterReceiver(broadCastReceiver);

      Toast.makeText(this, "unregistered broadcst receiver", Toast.LENGTH_SHORT)
            .show();
   }
}
Sunil Pandey
sumber
1
Bisakah Anda jelaskan kepada OP mengapa ini praktik terbaik?
Martin Prikryl
1
Mereka tidak menjelaskan, "mereka" selalu memposting kode, karena jauh lebih baik lho. -sarcasm
Neon Warge
2

Menurut Mendengarkan dan Menyiarkan Pesan Global, dan Mengatur Alarm di Tugas Umum dan Cara Melakukannya di Android :

Jika kelas penerima tidak terdaftar menggunakan manifesnya, Anda dapat secara instantiate dan mendaftarkan penerima secara dinamis dengan memanggil Context.registerReceiver () .

Lihatlah registerReceiver (penerima BroadcastReceiver, filter IntentFilter) untuk info lebih lanjut.

McStretch
sumber
1
saya mencoba menelepon context.registerReceivertetapi tidak bisa dipanggil tolong lihat pertanyaan ini stackoverflow.com/questions/13238600/…
Hunt
2

Ini adalah praktik terbaik untuk selalu memberikan izin saat mendaftarkan penerima, jika tidak, Anda akan menerima untuk aplikasi apa pun yang mengirimkan maksud yang cocok. Ini dapat memungkinkan aplikasi jahat untuk menyiarkan ke penerima Anda.

ChopperCharles
sumber
1

untuk LocalBroadcastManager

   Intent intent = new Intent("any.action.string");
   LocalBroadcastManager.getInstance(context).
                                sendBroadcast(intent);

dan mendaftar onResume

LocalBroadcastManager.getInstance(
                    ActivityName.this).registerReceiver(chatCountBroadcastReceiver, filter);

dan batalkan registrasi onStop

LocalBroadcastManager.getInstance(
                ActivityName.this).unregisterReceiver(chatCountBroadcastReceiver);

dan menerimanya ..

mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.e("mBroadcastReceiver", "onReceive");
        }
    };

di mana IntentFilter berada

 new IntentFilter("any.action.string")
Zar E Ahmer
sumber
1

Dua pilihan

1) Jika Anda ingin membaca Siaran hanya ketika Aktivitas terlihat,

registerReceiver(...) di onStart()dan unregisterReceiver(...)dionStop()

2) Jika Anda ingin membaca Siaran bahkan jika Aktivitas di Latar Belakang,

registerReceiver(...)masuk onCreate(...)dan unregisterReceiver(...)masukonDestroy()

Bonus:

Jika kamu malas

Jika Anda tidak ingin menulis kode boilerplate untuk mendaftar dan membatalkan registrasi BroadcastReceiver lagi dan lagi di setiap Kegiatan,

  1. Buat Aktivitas abstrak
  2. Tulis kode boilerplate di Activity
  3. Biarkan implementasi sebagai metode abstrak

Berikut ini cuplikan kode:

Aktivitas Abstrak

public abstract class BasicActivity extends AppCompatActivity {

    private BroadcastReceiver broadcastReceiver;
    private IntentFilter filter;
    private static final String TAG = "BasicActivity";

    /**********************************************************************
    *                   Boilerplate code
    **********************************************************************/

    @Override
    public void onCreate(Bundle sis){
        super.onCreate(sis);
        broadcastReceiver = getBroadcastReceiver();
        filter = getFilter();
    }

    @Override
    public void onStart(){
        super.onStart();
        register();
    }

    @Override
    public void onStop(){
        super.onStop();
        unregister();
    }

    private void register(){
        registerReceiver(broadcastReceiver,filter);
    }

    private void unregister(){
        unregisterReceiver(broadcastReceiver);
    }

    /**********************************************************************
    *                   Abstract methods
    **********************************************************************/

    public abstract BroadcastReceiver getBroadcastReceiver();

    public abstract IntentFilter getFilter();

}

Dengan menggunakan pendekatan ini Anda dapat menulis lebih banyak kode boilerplate seperti menulis animasi umum, mengikat ke layanan, dll.

Lihat kode lengkap:

SINI

Rohit Singh
sumber
0

Buat penerima siaran

[BroadcastReceiver (Diaktifkan = benar, Diekspor = salah)]

public class BCReceiver : BroadcastReceiver
{

    BCReceiver receiver;

    public override void OnReceive(Context context, Intent intent)
    {
        //Do something here
    }
}

Dari aktivitas Anda, tambahkan kode ini:

LocalBroadcastManager.getInstance(ApplicationContext)
    .registerReceiver(receiver, filter);
fulgen
sumber