Programmieren Sie programmgesteuert einen Rundfunkempfänger

149

Ich würde gerne wissen, wie man einen Rundfunkempfänger programmgesteuert registriert. Ich möchte bestimmte Empfänger entsprechend der Benutzerauswahl registrieren.

Da die Registrierung über die Manifestdatei erfolgt, frage ich mich, ob es einen geeigneten Weg gibt, dies im Code zu erreichen.

CoolStraw
quelle
2
CoderzPassion Broadcast Reciever detailliertestes Tutorial aller Zeiten
karanatwal.github.io
Bitte beziehen Sie sich auf diesen Link stackoverflow.com/questions/15698790/…

Antworten:

64

Es hört sich so an, als ob Sie steuern möchten, ob in Ihrem Manifest veröffentlichte Komponenten aktiv sind, und einen Empfänger während der Ausführung nicht dynamisch registrieren (über Context.registerReceiver ()).

In diesem Fall können Sie mit PackageManager.setComponentEnabledSetting () steuern, ob diese Komponenten aktiv sind:

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

Hinweis: Wenn Sie nur während der Ausführung eine Sendung empfangen möchten, ist es besser, registerReceiver () zu verwenden. Eine Empfängerkomponente ist in erster Linie nützlich, wenn Sie sicherstellen müssen, dass Ihre App bei jedem Senden der Sendung gestartet wird.

Hackbod
quelle
1
Klug ! Du hast mich klar gebracht. Vielen Dank
CoolStraw
Netter - hatte keine Ahnung, dass Sie dies tun könnten :)
Chris Noldus
es ist ähnlich stackoverflow.com/questions/24140894/…
Ankit Srivastava
1
@hackbod Wie kann ein Metadaten-Tag in einem benutzerdefinierten Empfänger hinzugefügt werden? Hast du eine Idee !! Ich muss ein Metadaten-Tag hinzufügen, das wir in androidmanifest.xml verwenden.
Zala Janaksinh
1
Bestes Tutorial bis heute coderzpassion.com/implement-broadcastreceiver-android und in einfacher Sprache
Jagjit Singh
269

In Ihrer onCreateMethode können Sie einen Empfänger wie folgt registrieren:

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);
}

Denken Sie daran, dies in der folgenden onDestroyMethode auszuführen :

 @Override
 protected void onDestroy() {
  if (receiver != null) {
   unregisterReceiver(receiver);
   receiver = null;
  }
  super.onDestroy();
 }
Eric Nordvik
quelle
19
Danke, das hat super funktioniert. Zum Senden der Sendung habe ich den Code Intent i = new Intent ("SOME_ACTION") verwendet; sendBroadcast (i);
Ben Clayton
7
Warum nicht beim Lebenslauf und beim Start?
Syed Raza Mehdi
Was würde passieren, wenn ich die Registrierung des Rundfunkempfängers nicht aufhebe? Würde der Broadcast-Empfänger auch nach einem Neustart registriert bleiben?
Jaydev
5
Es ist nicht garantiert, dass onDestroy()der Aufruf erfolgt, wodurch ein potenzieller Speicherverlust entsteht. Es ist besser, sich in onStart()/ zu registrieren / abzumelden onStop().
Neria Nachum
Bedeutet dies, dass ich keine Broadcast-Empfängerklasse erstellen muss? Ich könnte einfach meinen gesamten onReceive () - Code hier einfügen und es würde funktionieren?
Taslim Oseni
70

Ein wichtiger Punkt, den die Leute vergessen zu erwähnen, ist die Lebenszeit des Broadcast Receiver. Der Unterschied zwischen der programmgesteuerten Registrierung und der Registrierung in AndroidManifest.xml besteht darin, dass. In der Manifestdatei hängt dies nicht von der Lebensdauer der Anwendung ab. Bei der programmgesteuerten Registrierung hängt dies von der Lebensdauer der Anwendung ab. Dies bedeutet, dass Sie bei der Registrierung in AndroidManifest.xml die gesendeten Absichten auch dann erfassen können, wenn Ihre Anwendung nicht ausgeführt wird.

Bearbeiten: Der erwähnte Hinweis gilt ab Android 3.1 nicht mehr. Das Android-System schließt standardmäßig alle Empfänger vom Empfang von Absichten aus, wenn die entsprechende Anwendung vom Benutzer noch nie gestartet wurde oder wenn der Benutzer die Anwendung explizit über das Android-Menü gestoppt hat (in Verwalten → Anwendung). https://developer.android.com/about/versions/android-3.1.html

Dies ist eine zusätzliche Sicherheitsfunktion, da der Benutzer sicher sein kann, dass nur die von ihm gestarteten Anwendungen Broadcast-Absichten erhalten.

Es kann also verstanden werden, dass Empfänger, die programmgesteuert in Anwendungen registriert onCreate()sind, den gleichen Effekt haben wie Empfänger , die in AndroidManifest.xml von Android 3.1 oben deklariert wurden .

Krypton
quelle
1
Dies ist eine gute Anmerkung. Ich schaue mir gerade ein Buch an, das ich über Android lese, und frage mich, warum beide Methoden zur Implementierung von Broadcast durchgeführt wurden. Es scheint mir, dass es aus Gründen der Abwärtskompatibilität ist. Ich bin mir aber nicht sicher.
Neon Warge
Glaubst du wirklich, dass die Bearbeitung wahr ist? Ich meine den letzten Satz. Android wird Ihre Anwendung wahrscheinlich jederzeit beenden, was dazu führt, dass Ihre programmgesteuert registrierten Empfänger nicht mehr funktionieren, das registrierte Manifest jedoch weiterhin funktioniert.
JacksOnF1re
40

Definieren Sie einen Broadcast-Empfänger an einer beliebigen Stelle in Aktivität / Fragment wie folgt:

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

Definieren Sie IntentFilter in onCreate()

mIntentFilter=new IntentFilter("action_name");

Registrieren Sie nun den BroadcastReciever in onResume()und heben Sie die Registrierung auf onPause()[da Broadcast nicht verwendet wird, wenn die Aktivität angehalten wird].

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

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

Im Detail-Tutorial sehen Sie sich die zwei Möglichkeiten zur Implementierung des Broadcast-Empfängers an .

SohailAziz
quelle
bestes Beispiel, das ich bisher gefunden habe! Vielen Dank!
Ayush Goyal
1
@SohailAziz Der Link bietet eine gute Antwort. Könnten Sie den Kontext des Links in Ihre Antwort aufnehmen, damit Ihre Antwort relevant bleibt, wenn der Link ausfällt?
iRuth
Meiner persönlichen Meinung nach sollte die Sendung in onResume und onPause registriert sein, wie Sie vorgeschlagen haben, aber einige Leute sagen, dass sie in onCreate und onDestroy sein muss. Können Sie Vor- und Nachteile für beide erklären?
Syed Raza Mehdi
2
@SyedRazaMehdi Wenn Broadcast zum Aktualisieren der Benutzeroberfläche verwendet wird (was in den meisten Fällen der Fall ist), sollten Sie es in onResume registrieren und die Registrierung in onPause aufheben, da Broadcast sonst unbrauchbar wird.
SohailAziz
Danke. Das ist die beste Antwort.
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
quelle
1
Können Sie OP bitte erklären, warum dies die beste Vorgehensweise ist?
Martin Prikryl
1
Sie erklären nicht, "sie" schreiben immer Postleitzahl, weil es viel besser ist, wissen Sie. -sarkasmus
Neon
2

Laut Abhören und Senden globaler Nachrichten sowie Festlegen von Alarmen in allgemeinen Aufgaben und Vorgehensweise in Android :

Wenn die empfangende Klasse nicht mit ihrem Manifest registriert ist, können Sie einen Empfänger dynamisch instanziieren und registrieren, indem Sie Context.registerReceiver () aufrufen .

Weitere Informationen finden Sie unter registerReceiver (BroadcastReceiver-Empfänger, IntentFilter-Filter) .

McStretch
quelle
1
Ich habe versucht anzurufen , context.registerReceiveraber es wird nicht angerufen. Können
Hunt
2

Es wird empfohlen, bei der Registrierung des Empfängers immer die Berechtigung anzugeben. Andernfalls erhalten Sie für jede Anwendung, die eine übereinstimmende Absicht sendet. Dadurch können böswillige Apps an Ihren Empfänger gesendet werden.

ChopperCharles
quelle
1

für LocalBroadcastManager

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

und registrieren Sie sich in onResume

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

und hebe die Registrierung auf onStop

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

und erhalte es ..

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

wo IntentFilter ist

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

Zwei Möglichkeiten

1) Wenn Sie Broadcast nur lesen möchten, wenn die Aktivität sichtbar ist,

registerReceiver(...) in onStart()und unregisterReceiver(...)inonStop()

2) Wenn Sie Broadcast lesen möchten, auch wenn sich die Aktivität im Hintergrund befindet,

registerReceiver(...)in onCreate(...)und unregisterReceiver(...)inonDestroy()

Bonus:

Wenn Sie faul sind

Wenn Sie keinen Boilerplate-Code schreiben möchten, um einen BroadcastReceiver in jeder Aktivität immer wieder zu registrieren und die Registrierung aufzuheben, dann

  1. Erstellen Sie eine abstrakte Aktivität
  2. Schreiben Sie den Boilerplate-Code in Aktivität
  3. Belassen Sie die Implementierung als abstrakte Methode

Hier ist das Code-Snippet:

Abstrakte Aktivität

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();

}

Mit diesem Ansatz können Sie mehr Boilerplate-Code schreiben, z. B. allgemeine Animationen schreiben, an einen Dienst binden usw.

Siehe vollständigen Code:

HIER

Rohit Singh
quelle
0

Erstellen Sie einen Rundfunkempfänger

[BroadcastReceiver (Aktiviert = wahr, Exportiert = falsch)]

public class BCReceiver : BroadcastReceiver
{

    BCReceiver receiver;

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

Fügen Sie aus Ihrer Aktivität diesen Code hinzu:

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