Wie kann man prüfen, ob Empfänger in Android registriert ist?
Frage
Ich muss überprüfen, ob mein registrierte Empfänger noch registriert ist, wenn nicht, wie kann ich es irgendwelche Methoden überprüfen?
Lösung
Ich bin nicht sicher, dass die API direkt eine API, wenn man bedenkt, dieses Thema :
Ich habe das Gleiche fragen.
In meinem Fall habe ich eineBroadcastReceiver
Implementierung dass AnrufeContext#unregisterReceiver(BroadcastReceiver)
vorbei selbst als Argument nach der Intention der Handhabung, die es empfängt.
Es gibt eine kleine Chance, dass deronReceive(Context, Intent)
Methode des Empfängers aufgerufen da es mit mehrerenIntentFilters
mehr als einmal registriert ist, das Potenzial für eineIllegalArgumentException
Schaffung vonContext#unregisterReceiver(BroadcastReceiver)
geworfen.In meinem Fall kann ich ein eigenes synchronisiert Mitglied Check speichern, bevor
Context#unregisterReceiver(BroadcastReceiver)
anrufen, aber es wäre viel sauberer, wenn die API ein Kontrollverfahren bereitgestellt.
Andere Tipps
Es gibt keine API-Funktion zu überprüfen, ob ein Empfänger registriert ist. Die Abhilfe ist Ihr Code in einem try catch block as done below.
try {
//Register or UnRegister your broadcast receiver here
} catch(IllegalArgumentException e) {
e.printStackTrace();
}
einfachste Lösung
in Empfänger:
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 :)
...
}
in dem Code ein:
MyReceiver myReceiver = new MyReceiver();
myReceiver.register(Context, IntentFilter); // register
myReceiver.unregister(Context); // unregister
ad 1
- in Antwort auf:
Dieser wirklich nicht so elegant, weil Sie daran zu erinnern, haben die festlegen isRegistered Flagge nach der Registrierung. - Stealth Rabbi
- „mehr ellegant Art und Weise“, fügte Verfahren in Empfänger zu registrieren und Einstellmerker
das wird nicht funktionieren, wenn Sie das Gerät oder wenn Ihre Anwendung neu starten, wurde getötet von O. - amin Vor 6 Stunden
@amin - siehe Lebensdauer in Code (System nicht mit offensichtlichem Eintrag registriert) registrierte Empfänger:)
Ich bin mit dieser Lösung
public class ReceiverManager {
private static List<BroadcastReceiver> receivers = new ArrayList<BroadcastReceiver>();
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);
}
}
}
Sie haben mehrere Möglichkeiten
-
Sie können eine Flagge in Ihrer Klasse oder Aktivität setzen. Legen Sie eine boolean Variable in die Klasse und Blick auf diese Flagge zu wissen, ob der Empfänger registriert haben.
-
Erstellen Sie eine Klasse, die den Receiver und es erstreckt können Sie:
-
Singleton-Muster für nur eine Instanz dieser Klasse haben in Ihrem Projekt.
-
Implementieren Sie die Methoden für wissen, ob der Empfänger-Register ist.
-
Sie haben try / catch verwenden:
try {
if (receiver!=null) {
Activity.this.unregisterReceiver(receiver);
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
Sie können es einfach ....
1) erstellen Sie eine boolean Variable ...
private boolean bolBroacastRegistred;
2) Wenn Sie Ihren Sendungs-Empfänger registrieren, setzen Sie sich auf TRUE
...
bolBroacastRegistred = true;
this.registerReceiver(mReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
....
3) Im onPause () zu tun ... es
if (bolBroacastRegistred) {
this.unregisterReceiver(mReceiver);
bolBroacastRegistred = false
}
Just, und jetzt, Sie erhalten nicht mehr Ausnahmefehlermeldung auf onPause ().
Tip1: Verwenden Sie immer die unregisterReceiver () in onPause () nicht in onDestroy () Tip2: Vergessen Sie nicht, die bolBroadcastRegistred Variable auf FALSE zu setzen, wenn die unregisterReceive run ()
Erfolg!
Wenn Sie diese setzen auf onDestroy oder OnStop Methode. Ich denke, dass, wenn die Aktivität wieder erstellt wurde die MessageReciver wurde nicht erstellt werden.
@Override
public void onDestroy (){
super.onDestroy();
LocalBroadcastManager.getInstance(context).unregisterReceiver(mMessageReceiver);
}
I verwendet Intent Broadcast-Empfänger wissen über Handler Instanz Hauptaktivität Thread und gebrauchte Nachricht lassen Sie eine Nachricht an Haupttätigkeit zu übergeben
habe ich solchen Mechanismus zu überprüfen, ob Broadcast-Receiver ist bereits registriert oder nicht. Manchmal ist es erforderlich, wenn Sie Ihren Broadcast-Empfänger dynamisch registrieren und will es nicht zweimal machen oder Sie präsentieren den Benutzer, wenn Broadcast-Empfänger ausgeführt wird.
Haupttätigkeit:
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;
}
.............
}
Broadcast-Empfänger:
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();
}
}
.........
}
}
Ich persönlich verwende die Methode der unregisterReceiver Aufrufs und beim Schlucken der Ausnahme, wenn es geworfen wird. Ich bin damit einverstanden dies ist hässlich, aber die beste Methode, die derzeit zur Verfügung gestellt.
Ich habe einen Feature-Request angehoben ein boolean Verfahren zu überprüfen, um zu bekommen, wenn ein Empfänger registriert ist mit dem Android-API hinzugefügt. Bitte unterstützen Sie hier, wenn Sie sehen möchten, hinzugefügt: https://code.google.com/p/android/issues/detail ? id = 73718
ich Ihr Problem bekommen, stand ich das gleiche Problem in meiner Anwendung. Ich rufe registerReceiver () mehrere Zeit innerhalb der Anwendung.
Eine einfache Lösung für dieses Problem ist es, den registerReceiver () in der Custom Application Klasse zu nennen. Dadurch wird sichergestellt, dass Ihr Rundfunkempfänger wird nur ein in der gesamten Application Lifecycle aufgerufen werden.
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);
}
}
Dies ist, wie ich es getan haben, es ist eine modifizierte Version der Antwort von ceph3us und herausgegeben von slinden77 (unter anderem habe ich entfernt Rückgabewerte von Methoden, die ich nicht notwendig):
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
}
}
}
Dann auf einer Aktivitätsklasse:
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());
}
}
ich diesen Code setzen in meiner Eltern Aktivität
Liste 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);
}
Hier ist, was ich tat, zu überprüfen, ob der Sender bereits registriert ist, auch wenn Sie schließen Sie Anwendung (finish ())
Firstime Ihre Anwendung ausgeführt wird, eine Broadcast sendet erste wird es wahr / falsch zurückgeben hängt davon ab, ob Ihre Broadcaster in noch laufen oder nicht.
Meine Broadcaster
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;
}
}
}
Meine 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"));
}
Sie können mit Dagger einen Verweis von diesem Empfänger schaffen.
Zunächst bieten sie:
@Provides
@YourScope
fun providesReceiver(): NotificationReceiver{
return NotificationReceiver()
}
Dann spritzen sie, wo Sie (mit constructor
oder Feld injection
) benötigen
und einfach übergibt es an registerReceiver
.
es auch zu in try/catch
Block setzen.
if( receiver.isOrderedBroadcast() ){
// receiver object is registered
}
else{
// receiver object is not registered
}
Just Nullpointer überprüfen. Wenn der Empfänger nicht existiert, dann ...
try{
Intent i = new Intent();
i.setAction("ir.sss.smsREC");
context.sendBroadcast(i);
Log.i("...","broadcast sent");
}
catch (NullPointerException e)
{
e.getMessage();
}