web-dev-qa-db-fra.com

Communication entre BroadcastReceiver et Activity - Android

J'ai un récepteur de diffusion dans mon application qui est déclenché à chaque fois que l'utilisateur reçoit un appel entrant. Maintenant, lorsque cela se produit, le récepteur de radiodiffusion doit invoquer une méthode spécifique dans une activité spécifique. Maintenant, j'ai essayé de rendre cette méthode statique et donc disponible, mais quelque chose me dit que c'est une très mauvaise idée.

En conséquence, j'ai essayé d'instancier le récepteur de radiodiffusion dans mon activité sans le déclarer dans mon manifeste, mais le problème est que, lorsque l'application est désactivée, l'activité n'existe pas et, par conséquent, je ne peux pas invoquer ma méthode.

Ma question est donc la suivante: comment puis-je invoquer cette méthode lorsque le récepteur de radiodiffusion est activé, sans la rendre "statique publique"?

Voici mon code d'activité (j'ai supprimé les parties non pertinentes)

package com.silverfix.ringo.activities;

import com.silverfix.ringo.R;
import com.silverfix.ringo.activities.fragments.DataManagerFragment;

import Android.app.ActionBar;
import Android.app.Activity;
import Android.app.FragmentTransaction;
import Android.content.BroadcastReceiver;
import Android.content.Context;
import Android.content.Intent;
import Android.content.IntentFilter;

public class RingtonesActivity extends Activity{

    private DataManagerFragment dataManagerFragment;
    private IntentFilter filter;
    private BroadcastReceiver phoneCall;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ringtones);
        ActionBar ab = getActionBar();
        ab.setDisplayShowTitleEnabled(false);
        ab.setDisplayHomeAsUpEnabled(true);
        dataManagerFragment = new DataManagerFragment();
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.add(dataManagerFragment, "DataManagerFragment");
        ft.commit();
        filter = new IntentFilter();
        filter.addAction("Android.intent.action.PHONE_STATE");
        phoneCall = new BroadcastReceiver() {

            @Override
            public void onReceive(Context context, Intent intent) {
                dataManagerFragment.act();
            }
        };
        registerReceiver(phoneCall, filter);
    }
}
18
David Lasry

Vous pouvez utiliser des observateurs, comme 

public class MyReceiver extends BroadcastReceiver {
    public MyReceiver() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        ObservableObject.getInstance().updateValue(intent);
    }
}

public class MainActivity extends Activity implements Observer {
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ObservableObject.getInstance().addObserver(this);
    }

    @Override
    public void update(Observable observable, Object data) {            
        Toast.makeText(this, String.valueOf("activity observer " + data), Toast.LENGTH_SHORT).show();
    }
}

public class ObservableObject extends Observable {
    private static ObservableObject instance = new ObservableObject();

    public static ObservableObject getInstance() {
        return instance;
    }

    private ObservableObject() {
    }

    public void updateValue(Object data) {
        synchronized (this) {
            setChanged();
            notifyObservers(data);
        }
    }
}

Receiver peut être utilisé via manifest . ObservableObject - doit être singleton.

45
ilw

Cela pourrait aider: comment puis-je notifier une activité en cours à partir d'un récepteur de diffusion?

Vous pouvez aussi essayer d’utiliser Observers

Quelque chose comme:

public class BroadcastObserver extends Observable {
    private void triggerObservers() {
        setChanged();
        notifyObservers();
    }

    public void change() {
        triggerObservers();
    }
}

Dans votre récepteur de diffusion:

@Override
public void onReceive(Context context, Intent intent) {
    BroadcastObserver bco = new BroadcastObserver();
    bco.change();
}

et l'activité:

public class YourActivity extends Activity implements
        Observer {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        BroadcastObserver bco = new BroadcastObserver();
        bco.addObserver(this);
    }

    @Override
    public void update() {
        //TODO: call your desired function
    }
}
6
Archie.bpgc

Si quelqu'un a besoin d'une communication bidirectionnelle entre BroadcastReceiver et Activity, j'ai écrit cette classe d'utilitaires, qui simplifie l'appel de méthodes tout en préservant la mémoire.

https://Gist.github.com/Jenjen1324/4a0c03beff827082cb641fc8fe2c4e71

0
JensV