Cara untuk memeriksa jika Penerima terdaftar di Android?

Saya perlu memeriksa jika saya terdaftar penerima masih terdaftar jika tidak bagaimana saya memeriksa setiap metode?

Mengomentari pertanyaan (1)

Tidak ada API yang berfungsi untuk memeriksa apakah penerima terdaftar. Solusinya adalah menempatkan kode dalam mencoba menangkap blok seperti yang dilakukan di bawah.

try {

 //Register or UnRegister your broadcast receiver here

} catch(IllegalArgumentException e) {

    e.printStackTrace();
}
Komentar (9)
Larutan

Saya tidak yakin API menyediakan langsung API, jika anda mempertimbangkan thread ini:

saya bertanya-tanya hal yang sama. Dalam kasus saya, saya memiliki BroadcastReceiver implementasi yang panggilan Konteks#unregisterReceiver(BroadcastReceiver) lewat dirinya sebagai argumen setelah penanganan Maksud yang diterimanya. Ada kemungkinan kecil bahwa penerima's onReceive(Konteks, Maksud) metode ini disebut lebih dari sekali, karena hal ini terdaftar dengan beberapa IntentFilters, menciptakan potensi untuk IllegalArgumentException dilempar dari Konteks#unregisterReceiver(BroadcastReceiver).

Dalam kasus saya, saya dapat menyimpan pribadi disinkronkan anggota untuk memeriksa sebelum memanggil Konteks#unregisterReceiver(BroadcastReceiver), tapi itu akan menjadi jauh lebih bersih jika API yang disediakan cek metode.

Komentar (0)

solusi yang paling sederhana

penerima:

public class MyReceiver extends BroadcastReceiver {   
    public boolean isRegistered;

    /**
    * register receiver
    * @param context - Context
    * @param filter - Intent Filter
    * @return see Context.registerReceiver(BroadcastReceiver,IntentFilter)
    */
    public Intent register(Context context, IntentFilter filter) {
        try {
              // ceph3us note:
              // here I propose to create 
              // a isRegistered(Contex) method 
              // as you can register receiver on different context  
              // so you need to match against the same one :) 
              // example  by storing a list of weak references  
              // see LoadedApk.class - receiver dispatcher 
              // its and ArrayMap there for example 
              return !isRegistered 
                     ? context.registerReceiver(this, filter) 
                     : null;
            } finally {
               isRegistered = true;
            }
    }

    /**
     * unregister received
     * @param context - context
     * @return true if was registered else false
     */
     public boolean unregister(Context context) {
         // additional work match on context before unregister
         // eg store weak ref in register then compare in unregister 
         // if match same instance
         return isRegistered 
                    && unregisterInternal(context);
     }

     private boolean unregisterInternal(Context context) {
         context.unregisterReceiver(this); 
         isRegistered = false;
         return true;
     }

    // rest implementation  here 
    // or make this an abstract class as template :)
    ...
}

dalam kode:

MyReceiver myReceiver = new MyReceiver();
myReceiver.register(Context, IntentFilter); // register 
myReceiver.unregister(Context); // unregister 

ad 1

-- di balas ke:

Ini benar-benar isn't yang elegan karena anda harus ingat untuk mengatur isRegistered bendera setelah anda mendaftar. – Stealth Rabbi

-- "lebih ellegant cara" menambahkan metode dalam receiver untuk mendaftarkan dan menetapkan bendera

ini tidak't bekerja Jika anda me-restart perangkat, atau jika aplikasi anda terbunuh oleh OS. – amin 6 jam yang lalu

@amin - lihat seumur hidup dalam kode (tidak terdaftar pada sistem dengan entri manifest) yang terdaftar penerima :)

Komentar (6)

Saya menggunakan solusi ini

public class ReceiverManager {

    private static List receivers = new ArrayList();  
    private static ReceiverManager ref;
    private Context context;

    private ReceiverManager(Context context){
        this.context = context;
    }

    public static synchronized ReceiverManager init(Context context) {      
        if (ref == null) ref = new ReceiverManager(context);
        return ref;
    }

    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter intentFilter){
        receivers.add(receiver);
        Intent intent = context.registerReceiver(receiver, intentFilter);
        Log.i(getClass().getSimpleName(), "registered receiver: "+receiver+"  with filter: "+intentFilter);
        Log.i(getClass().getSimpleName(), "receiver Intent: "+intent);
        return intent;
    }

    public boolean isReceiverRegistered(BroadcastReceiver receiver){
        boolean registered = receivers.contains(receiver);
        Log.i(getClass().getSimpleName(), "is receiver "+receiver+" registered? "+registered);
        return registered;
    }

    public void unregisterReceiver(BroadcastReceiver receiver){
        if (isReceiverRegistered(receiver)){
            receivers.remove(receiver);
            context.unregisterReceiver(receiver);
            Log.i(getClass().getSimpleName(), "unregistered receiver: "+receiver);
        }
    }
}
Komentar (9)

Anda memiliki beberapa pilihan

  1. Anda dapat menempatkan bendera ke kelas atau kegiatan. Menempatkan variabel boolean ke kelas dan melihat bendera ini untuk mengetahui jika anda memiliki Penerima yang terdaftar.

  2. Membuat kelas yang meluas Penerima dan di sana anda dapat menggunakan:

  3. Singleton pattern untuk hanya memiliki satu instance dari kelas ini dalam proyek anda.

  4. Menerapkan metode untuk mengetahui jika Penerima mendaftar.

Komentar (3)

Anda harus menggunakan try/catch:

try {
    if (receiver!=null) {
        Activity.this.unregisterReceiver(receiver);
    }
} catch (IllegalArgumentException e) {
    e.printStackTrace();
}
Komentar (0)

Anda dapat melakukannya dengan mudah....

  1. buat sebuah variabel boolean ...
private boolean bolBroacastRegistred;
  1. Ketika anda mendaftar anda Penerima Siaran, set ke TRUE
...
bolBroacastRegistred = true;
this.registerReceiver(mReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
....
  1. Dalam onPause() melakukannya...
if (bolBroacastRegistred) {
    this.unregisterReceiver(mReceiver);
    bolBroacastRegistred = false
}

Hanya itu, dan sekarang, anda tidak akan menerima pesan galat pengecualian pada onPause().

Tip1: Selalu gunakan unregisterReceiver() di onPause() tidak onDestroy() Tip2: Jangan lupa untuk mengatur bolBroadcastRegistred variabel PALSU ketika menjalankan unregisterReceive()

Sukses!

Komentar (0)

Jika anda menempatkan ini pada onDestroy atau onStop metode. Saya berpikir bahwa ketika aktivitas yang telah dibuat lagi MessageReciver itu't sedang dibuat.

@Override 
public void onDestroy (){
    super.onDestroy();
LocalBroadcastManager.getInstance(context).unregisterReceiver(mMessageReceiver);

}
Komentar (0)

Aku digunakan Niat untuk membiarkan Penerima Siaran tahu tentang Handler contoh dari Kegiatan utama thread dan menggunakan Pesan untuk menyampaikan pesan kepada kegiatan Utama

Saya telah menggunakan mekanisme tersebut untuk memeriksa jika Penerima Siaran sudah terdaftar atau tidak. Kadang-kadang hal ini diperlukan ketika anda mendaftarkan Penerima Siaran secara dinamis dan tidak ingin membuatnya dua kali atau anda hadir untuk pengguna jika Penerima Siaran berjalan.

Kegiatan utama:

public class Example extends Activity {

private BroadCastReceiver_example br_exemple;

final Messenger mMessenger = new Messenger(new IncomingHandler());

private boolean running = false;

static class IncomingHandler extends Handler {
    @Override
    public void handleMessage(Message msg) {
        running = false;    
        switch (msg.what) {
        case BroadCastReceiver_example.ALIVE:
    running = true;
            ....
            break;
        default:

            super.handleMessage(msg);
        }

    }
    }

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    IntentFilter filter = new IntentFilter();
        filter.addAction("pl.example.CHECK_RECEIVER");

        br_exemple = new BroadCastReceiver_example();
        getApplicationContext().registerReceiver(br_exemple , filter); //register the Receiver
    }

// call it whenever you want to check if Broadcast Receiver is running.

private void check_broadcastRunning() {    
        /**
        * checkBroadcastHandler - the handler will start runnable which will check if Broadcast Receiver is running
        */
        Handler checkBroadcastHandler = null;

        /**
        * checkBroadcastRunnable - the runnable which will check if Broadcast Receiver is running
        */
        Runnable checkBroadcastRunnable = null;

        Intent checkBroadCastState = new Intent();
        checkBroadCastState .setAction("pl.example.CHECK_RECEIVER");
        checkBroadCastState .putExtra("mainView", mMessenger);
        this.sendBroadcast(checkBroadCastState );
        Log.d(TAG,"check if broadcast is running");

        checkBroadcastHandler = new Handler();
        checkBroadcastRunnable = new Runnable(){    

            public void run(){
                if (running == true) {
                    Log.d(TAG,"broadcast is running");
                }
                else {
                    Log.d(TAG,"broadcast is not running");
                }
            }
        };
        checkBroadcastHandler.postDelayed(checkBroadcastRunnable,100);
        return;
    }

.............
}

Penerima Siaran:

public class BroadCastReceiver_example extends BroadcastReceiver {

public static final int ALIVE = 1;
@Override
public void onReceive(Context context, Intent intent) {
    // TODO Auto-generated method stub
    Bundle extras = intent.getExtras();
    String action = intent.getAction();
    if (action.equals("pl.example.CHECK_RECEIVER")) {
        Log.d(TAG, "Received broadcast live checker");
        Messenger mainAppMessanger = (Messenger) extras.get("mainView");
        try {
            mainAppMessanger.send(Message.obtain(null, ALIVE));
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    .........

}

}
Komentar (0)

Secara pribadi saya menggunakan metode panggilan unregisterReceiver dan menelan terkecuali jika itu's dilemparkan. Saya setuju ini jelek tapi metode terbaik saat ini.

I've mengangkat permintaan fitur untuk mendapatkan boolean metode untuk memeriksa jika penerima terdaftar ditambahkan ke API Android. Mohon dukungan itu di sini jika anda ingin melihat ditambahkan: https://code.google.com/p/android/issues/detail?id=73718

Komentar (0)

Saya mendapatkan masalah anda, saya menghadapi masalah yang sama dalam Aplikasi saya. Aku menelepon registerReceiver() beberapa waktu dalam aplikasi.

Sebuah solusi sederhana untuk masalah ini adalah untuk memanggil registerReceiver() dalam Aplikasi Kustom Kelas. Ini akan memastikan bahwa penerima Siaran akan dipanggil satu-satunya di seluruh siklus hidup Aplikasi.

public class YourApplication extends Application
{
    @Override
    public void onCreate()
    {
        super.onCreate();

        //register your Broadcast receiver here
        IntentFilter intentFilter = new IntentFilter("MANUAL_BROADCAST_RECIEVER");
        registerReceiver(new BroadcastReciever(), intentFilter);

    }
}
Komentar (0)

Ini adalah bagaimana saya melakukannya, itu adalah versi modifikasi dari jawaban yang diberikan oleh ceph3us dan diedit oleh slinden77 (di antara hal-hal lain yang saya telah dihapus kembali nilai-nilai dari metode yang saya tidak perlu):

public class MyBroadcastReceiver extends BroadcastReceiver{
    private boolean isRegistered; 

    public void register(final Context context) {
        if (!isRegistered){
            Log.d(this.toString(), " going to register this broadcast receiver");
            context.registerReceiver(this, new IntentFilter("MY_ACTION"));
            isRegistered = true;
        }
    }
    public void unregister(final Context context) {
        if (isRegistered) {            
            Log.d(this.toString(), " going to unregister this broadcast receiver");
            context.unregisterReceiver(this);
            isRegistered = false;
        }
    }
    @Override
    public void onReceive(final Context context, final Intent intent) {        
        switch (getResultCode()){
        //DO STUFF
        }        
    }        
}

Kemudian pada suatu Kegiatan kelas:

public class MyFragmentActivity extends SingleFragmentActivity{
    MyBroadcastReceiver myBroadcastReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        registerBroacastReceiver();       
    }

    @Override
    protected Fragment createFragment(){
        return new MyFragment();
    }

    //This method is called by the fragment which is started by this activity, 
    //when the Fragment is done, we also register the receiver here (if required)
    @Override
    public void receiveDataFromFragment(MyData data) {
        registerBroacastReceiver();
        //Do some stuff                
    }

    @Override
    protected void onStop(){        
        unregisterBroacastReceiver();
        super.onStop();
    }

    void registerBroacastReceiver(){
        if (myBroadcastReceiver == null)
            myBroadcastReceiver = new MyBroadcastReceiver();
        myBroadcastReceiver.register(this.getApplicationContext());
    }

    void unregisterReceiver(){
        if (MyBroadcastReceiver != null)
            myBroadcastReceiver.unregister(this.getApplicationContext());
    }
}
Komentar (0)

saya menempatkan kode ini pada orang tua saya kegiatan

Daftar registeredReceivers = new ArrayList<>();

@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
    registeredReceivers.add(System.identityHashCode(receiver));
    return super.registerReceiver(receiver, filter);
}

@Override
public void unregisterReceiver(BroadcastReceiver receiver) {
    if(registeredReceivers.contains(System.identityHashCode(receiver)))
    super.unregisterReceiver(receiver);
}
Komentar (0)

Anda dapat menggunakan Belati untuk membuat referensi dari penerima.

Pertama memberikan:

@Provides
@YourScope
fun providesReceiver(): NotificationReceiver{
    return NotificationReceiver()
}

Maka inject ini di mana anda perlu (menggunakan pembina atau lapangan injeksi)

dan hanya lulus untuk registerReceiver.

Juga memasukkannya ke dalam try/catch block terlalu.

Komentar (0)

Berikut ini's apa yang saya lakukan untuk memeriksa apakah Penyiar sudah terdaftar, bahkan jika anda menutup aplikasi (finish())

Oral menjalankan aplikasi anda, mengirim siaran pertama ini akan mengembalikan nilai true/false tergantung pada jika anda penyiar di masih berjalan atau tidak.

Saya Penyiar

public class NotificationReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if(intent.getExtras() != null && intent.getStringExtra("test") != null){
            Log.d("onReceive","test");
            return;
        }
    }
}

Saya MainActivity

// init Broadcaster
private NotificationReceiver nr = new NotificationReceiver();

Intent msgrcv = new Intent("Msg");
msgrcv.putExtra("test", "testing");
boolean isRegistered = LocalBroadcastManager.getInstance(this).sendBroadcast(msgrcv);

if(!isRegistered){
    Toast.makeText(this,"Starting Notification Receiver...",Toast.LENGTH_LONG).show();
    LocalBroadcastManager.getInstance(this).registerReceiver(nr,new IntentFilter("Msg"));
}
Komentar (0)
if( receiver.isOrderedBroadcast() ){
     // receiver object is registered
}
else{
     // receiver object is not registered
}
Komentar (1)

Hanya memeriksa NullPointerException. Jika penerima tidak ada, maka...

try{
    Intent i = new Intent();
    i.setAction("ir.sss.smsREC");
    context.sendBroadcast(i);
    Log.i("...","broadcast sent");
}
catch (NullPointerException e)
{
    e.getMessage();
}
Komentar (3)