31

I have a broadcast receiver in my app which is fired every time the user gets an incoming call. Now, when it happens, I need the broadcast receiver to invoke a specific method in a specific activity. Now, I tried to make this method static and therefore available, but something tells me it is a very bad idea.

Accordingly, I tried to instantiate the broadcast receiver inside my activity without declaring it in my manifest but the problem is - when the app is off, the activity dosn't exist and therefore I can't invoke my method.

So my question is - How can I invoke this method when the broadcast receiver is fired up, without making it "public static"?

Here is my activity code(I have deleted the irrelevant parts)

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);
    }
}
Chepech
  • 5,258
  • 4
  • 47
  • 70
David Lasry
  • 1,407
  • 4
  • 26
  • 43
  • 1
    when u receive the call your applicaiton is turns to background.so what u will do with activity(when ur app is in background)?? – KomalG Jan 22 '15 at 07:38
  • does that method necessarily have to be inside of `Activity` class? – mangusta Jan 22 '15 at 07:38
  • What does that method will do?? – Chandrakanth Jan 22 '15 at 07:39
  • you have to use pendingIntent to notify. – Zar E Ahmer Jan 22 '15 at 07:40
  • mangusta - This method is not in the activity. It's inside a fragment but I need some resources that without the activity I wouldn't have access to them such as ContentResolver, Context... Chandrakanth - It will automatically pick a random ringtone Neptster - Could you please elaborate about that? What do you mean PendingIntent? How can I use it? – David Lasry Jan 22 '15 at 07:45
  • Declare the broadcast receiver in the manifest.. So it will active all the time. Let me know if you have any problem. – droidd Jan 22 '15 at 07:50
  • Vivek - Ok but I can I invoke my method from the broadcast receiver? This method is inside a fragment of the activity. – David Lasry Jan 22 '15 at 07:52
  • So what is the problem you are facing now? – droidd Jan 22 '15 at 07:53
  • I don't know how to invoke this specific method from my fragment. I don't have access to this class – David Lasry Jan 22 '15 at 07:55
  • 1
    Declare the method in the same fragment in which you register the broadcast or Create one helper class move the method in this. by creating the object of this class. you will able to do this. – droidd Jan 22 '15 at 07:58
  • Check this https://stackoverflow.com/a/59961601/6667442 – Ketan Ramani Jan 29 '20 at 07:44

3 Answers3

67

You can use observers , like

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 can be used via manifest. ObservableObject - must be singleton.

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
ilw
  • 2,499
  • 5
  • 30
  • 54
6

This might help: how can I notify a running activity from a broadcast receiver?

Also, you can try using Observers

Something like:

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

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

In your broadcast receiver:

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

and the Activity:

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
    }
}
Community
  • 1
  • 1
Archie.bpgc
  • 23,812
  • 38
  • 150
  • 226
1

If anyone needs two-way communication between a BroadcastReceiver and a Activity, I wrote this utility class which simplifies invoking Methods on each other while still being memory-safe.

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

JensV
  • 3,997
  • 2
  • 19
  • 43