How can I within a class extending from Broadcastreceiver make any changes to the graphical interface?

Asked

Viewed 656 times

0

Having an Activitymain(inherits from Activity) calls a broadcast, and then the Broadcast class is started. But when performed some action in this broadcast I want to change information from the textView that belongs to the class Activitymain and is part of a custom Adapter (Basedapter).

  • You could create another receiver within your Activity notified by the first receiver that you used, passing all the parameters you need to change the interface.

  • @Wakim I already use a receiver that I urge on the Activity itself.. but wanted to know if there is any way to do issu "separate", ie broadcast being a class the part outside of Activity

  • Yes, just use the pattern Observer (Listener) in that class. Having an interface that Activity or another class implements, to be notified by the receiver. You can use a Handler of MainThread to process events. More details on: https://developer.android.com/training/multiple-threads/communicate-ui.html.

1 answer

2


There are several ways to update the View of a Activity of an external class, I will illustrate two that are easy to implement:

1. Using the Pattern Design Observer (Listener)

Definition of the Listener interface

public interface OnEventChangedListener {
    public void onEventChanged(/* Parametros */);
}

This interface will be used by BroadcastReceiver and implemented by Activity to address the occurrence of the event.

Definition of BroadcastReceiver

If you’re registering it in your AndroidManifest and not creating and programmatically recording in their Activity, the OnEventChangedListener needs to be static, otherwise it may be an instance variable and with a Setter nonstatic.

public class MyBroadcastReceiver extends BroadcastReceiver {

    static OnEventChangedListener mListener;

    @Override
    public void onReceive(Context context, Intent intent) {
        if(mListener != null) {
            mListener.onConnectionChanged(/* Parametros */);
        }
    }

    public static void setOnOnEventChangedListener(OnEventChangedListener listener) {
        mListener = listener;
    }
}

public class MyBroadcastReceiver extends BroadcastReceiver {

    OnEventChangedListener mListener;

    @Override
    public void onReceive(Context context, Intent intent) {
        if(mListener != null) {
            mListener.onConnectionChanged(/* Parametros */);
        }
    }

    public void setOnOnEventChangedListener(OnEventChangedListener listener) {
        mListener = listener;
    }
}

In his Activity, you need to just register the Listener:

Definition of Activity

public class MainActivity extends Activity implements OnEventChangedListener {

    @Override
    public void onDestroy() {
        // Remover a referência para não causar um Leak de memória!
        MyBroadcastReceiver.setOnOnEventChangedListener(null);
    }

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

        // Restante do código de sua Activity

        // Registro do Listener
        MyBroadcastReceiver.setOnOnEventChangedListener(this);
    }

    @Override
    public void onPause() {
        super.onPause();
        // É legal tirar a referência quando a Activity sair do topo do TaskStack.
        MyBroadcastReceiver.setOnOnEventChangedListener(null);
    }

    @Override
    public void onResume() {
        super.onResume();
        // Recolocando quando ela vier a ser o topo do TaskStack.
        MyBroadcastReceiver.setOnOnEventChangedListener(this);
    }

    @Override
    public void onEventChanged(/* Parametros */) {
        // Tratamento do evento
    }
}

If you create and register the BroadcastReceiver in his Activity:

public class MainActivity extends Activity implements OnEventChangedListener {

    MyBroadcastReceiver mReceiver;
    IntentFilter mItentFilter;

    @Override
    public void onDestroy() {
        // Remover a referência para não causar um Leak de memória!
        mReceiver.setOnOnEventChangedListener(null);
    }

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

        // Registro do BroadcastReceiver
        mReceiver = new MyBroadcastReceiver();

        mReceiver.setOnOnEventChangedListener(this);

        mItentFilter = new IntentFilter();
        mItentFilter.addAction("SEU_ACTION");

        // Espera para registrar no onResume
        //registerReceiver(mReceiver, mItentFilter);
    }

    @Override
    public void onPause() {
        super.onPause();
        unregisterReceiver(mReceiver);
        // É legal tirar a referência quando a Activity sair do topo do TaskStack.
        MyBroadcastReceiver.setOnOnEventChangedListener(null);
    }

    @Override
    public void onResume() {
        super.onResume();
        registerReceiver(mReceiver, mItentFilter);
        // Recolocando quando ela vier a ser o topo do TaskStack.
        MyBroadcastReceiver.setOnOnEventChangedListener(this);
    }
}

2, Using a Handler

In that case, we will create a Handler in Main Thread, who will receive messages from BroadcastReceiver, updating the View.

Definition of Activity

public class MainActivity extends Activity implements OnEventChangedListener {

    Handler mHandler;
    MyBroadcastReceiver mReceiver;
    IntentFilter mItentFilter;

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

        mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                if(msg.what == CONSTANTE_ATUALIZAR_VIEW) {
                    Bundle data = msg.getData();

                    // Mensagem enviada pelo BroadcastReceiver.
                    // Será executada na MainThread.
                    // Atualizar a View com os parametros.
                }
            }
        };

        // Registro do BroadcastReceiver
        mReceiver = new MyBroadcastReceiver();

        mReceiver.setHandler(mHandler);

        mItentFilter = new IntentFilter();

        mItentFilter.addAction("SEU_ACTION");

        // Espera para registrar no onResume
        //registerReceiver(receiver, mItentFilter);
    }

    @Override
    public void onPause() {
        super.onPause();
        unregisterReceiver(mReceiver);
    }

    @Override
    public void onResume() {
        super.onResume();
        registerReceiver(mReceiver, mItentFilter);
    }
}

As remembered by Piovezan, we leave to record on onResume of Activity, and remove the record on onPause. To avoid consuming unnecessary resources while Activity is not visible. Of course it may be a decision not to do, it may be urgent to treat the event even with the Activity unobtrusive.

Definition of BroadcastReceiver

public class MyBroadcastReceiver extends BroadcastReceiver {

    Handler mHandler;

    @Override
    public void onReceive(Context context, Intent intent) {
        if(mHandler != null) {
            Message msg = mHandler.obtainMessage(CONSTANTE_ATUALIZAR_VIEW);

            Bundle data = new Bundle();

            // Seta os parametros no Bundle

            msg.setData(data);

            // Envio a mensagem para o Handler na MainActivity
            mHandler.sendMessage(msg);
        }
    }

    public void setHandler(Handler handler) {
        mHandler = handler;
    }
}

The process for the BroadcastReceiver registered at AndroidManifest is analogous.

References:

  1. https://developer.android.com/training/multiple-threads/communicate-ui.html
  • Very good answer. I just suggest calling registerReceiver()/unregisterReceiver() in the methods onResume()/onPause() (among which the Activity is effectively active on screen) rather than onCreate()/onDestroy().

  • Cool, @Piovezan, well remembered. I had never used the programmatic record, always direct on AndroidManifest, I’ll add that to the answer.

  • @Wakim I had already made the first option using interface... and it hadn’t worked because I didn’t : public void setOnOnEventChangedListener(Oneventchangedlistener Listener) { mListener = Listener; } the rest had done the same... now with this method solved my problem, but I still could not understand why it needs it...

  • @Pedrorangel, updated the answer, allowing to remove the reference to Activity in the BroadcastReceiver when it is no longer necessary. This is good to avoid Memory Leak. Since the Activity is a very heavy object.

  • @Wakim very good.. I already use it.. but I put in onStart() and onStop()...

  • @Pedrorangel, maybe, but the onPause occurs when you open a Dialog or DialogFragment or a new Activity (When a new Window is created and made visible). Ai is just test to see which is best in this case. I am without the environment at the moment, when I have a time I can add this information

  • @Wakim of good...I took a look at the life cycle of Activity I will use on onPause even, thank you very much.

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.