J'aimerais savoir quelle est la meilleure pratique/méthode pour enregistrer par programmation un récepteur de diffusion. Je souhaite enregistrer des destinataires spécifiques en fonction du choix de l'utilisateur.
Comme l'enregistrement se fait via le fichier manifeste, je me demande s'il existe un moyen approprié de réaliser cela dans le code.
Il semble que vous souhaitiez contrôler l'activation des composants publiés dans votre manifeste, et non enregistrer de manière dynamique un destinataire (via Context.registerReceiver ()) lors de l'exécution.
Si tel est le cas, vous pouvez utiliser PackageManager.setComponentEnabledSetting () pour contrôler si ces composants sont actifs:
Notez que si vous êtes uniquement intéressé à recevoir une émission en cours d'exécution, il est préférable d'utiliser registerReceiver (). Un composant récepteur est surtout utile lorsque vous devez vous assurer que votre application est lancée à chaque fois que la diffusion est envoyée.
Dans votre méthode onCreate
, vous pouvez enregistrer un récepteur comme ceci:
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);
}
N'oubliez pas de lancer ceci dans la méthode onDestroy
:
@Override
protected void onDestroy() {
if (receiver != null) {
unregisterReceiver(receiver);
receiver = null;
}
super.onDestroy();
}
Un point important que les gens oublient de mentionner est la durée de vie du Broadcast Receiver
. La différence entre l'enregistrer par programme et l'enregistrer dans AndroidManifest.xml est que. Dans le fichier manifeste, cela ne dépend pas de la durée de vie de l'application. Bien que l'enregistrement par programme dépende de la durée de vie de l'application. Cela signifie que si vous vous enregistrez dans AndroidManifest.xml, vous pouvez capturer les intentions diffusées même lorsque votre application n'est pas en cours d'exécution.
Edit: La note mentionnée n'est plus vraie depuis Android 3.1, le système Android exclut tous les destinataires de la réception par défaut si l'application correspondante n'a jamais été démarrée par l'utilisateur ou si l'utilisateur l'a explicitement arrêtée via le Menu Android (dans Gérer → Application). https://developer.Android.com/about/versions/Android-3.1.html
Il s'agit d'une fonctionnalité de sécurité supplémentaire, car l'utilisateur peut être sûr que seules les applications qu'il a démarrées recevront des intentions de diffusion.
On peut donc comprendre que les destinataires enregistrés par programme dans la fonction onCreate()
de l'application auraient le même effet que ceux déclarés dans AndroidManifest.xml à partir d'Android 3.1 ci-dessus.
Définissez un récepteur de diffusion n'importe où dans Activity/Fragment comme ceci:
mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG," onRecieve"); //do something with intent
}
};
Définir IntentFilter dans onCreate ()
mIntentFilter=new IntentFilter("action_name");
Enregistrez maintenant BroadcastReciever dans onResume () et annulez son enregistrement dans onPause [car il n'y a aucune utilisation de broadcast si l'activité est suspendue].
@Override
protected void onResume() {
super.onResume();
registerReceiver(mReceiver, mIntentFilter);
}
@Override
protected void onPause() {
if(mReceiver != null) {
unregisterReceiver(mReceiver);
mReceiver = null;
}
super.onPause();
}
Pour plus de détails sur le didacticiel, jetez un œil à récepteur de radiodiffusion - deux façons de mettre en œuvre .
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();
}
}
Il est recommandé de toujours fournir l'autorisation lors de l'enregistrement du récepteur, sinon vous recevrez une autorisation pour toute application qui envoie une intention correspondante. Cela peut permettre à des applications malveillantes d'être diffusées vers votre récepteur.
En fonction de l'écoute et de la diffusion de messages globaux et de la définition d'alarmes dans Tâches courantes et comment les utiliser dans Android :
Si la classe d'accueil n'est pas enregistré en utilisant dans son manifeste, vous pouvez dynamiquement Instancier et enregistrer un récepteur de appelant Context.registerReceiver ().
Jetez un coup d'œil à registerReceiver (récepteur BroadcastReceiver, filtre IntentFilter) pour plus d'informations.
pour LocalBroadcastManager
Intent intent = new Intent("any.action.string");
LocalBroadcastManager.getInstance(context).
sendBroadcast(intent);
et vous inscrire à onResume
LocalBroadcastManager.getInstance(
ActivityName.this).registerReceiver(chatCountBroadcastReceiver, filter);
et annuler l'enregistrement onStop
LocalBroadcastManager.getInstance(
ActivityName.this).unregisterReceiver(chatCountBroadcastReceiver);
et le recevoir ..
mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.e("mBroadcastReceiver", "onReceive");
}
};
où IntentFilter est
new IntentFilter("any.action.string")
Créer un récepteur de diffusion
[BroadcastReceiver (Enabled = true, Exported = false)]
public class BCReceiver : BroadcastReceiver
{
BCReceiver receiver;
public override void OnReceive(Context context, Intent intent)
{
//Do something here
}
}
De votre activité, ajoutez ce code:
LocalBroadcastManager.getInstance(ApplicationContext)
.registerReceiver(receiver, filter);
1) Si vous souhaitez lire la diffusion uniquement lorsque l'activité est visible,
registerReceiver(...
) dans onStart()
et unregisterReceiver(...)
dans onStop()
2) Si vous voulez lire la diffusion même si l’activité est en arrière-plan,
registerReceiver(...)
dans onCreate(...)
et unregisterReceiver(...)
dans onDestroy()
Si vous êtes paresseux
Si vous ne voulez pas écrire le code standard pour enregistrer et désenregistrer un BroadcastReceiver encore et encore dans chaque activité,
Voici l'extrait de code:
Activité abstraite
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();
}
En utilisant cette approche, vous pouvez écrire plus de code passe-partout, comme écrire des animations communes, être lié à un service, etc.