4

I want to do the exact same thing mentioned in the question in the following link Call an activity method from a BroadcastReceiver class. But solution given there is not working for me and I can't comment there as I don't have enough reputation. I did everything mentioned in the solution but my broadcast receiver is not working with that code.

I just want to call the method in the activity on receiving the broadcast request without creating an instance of the activity. Can it be done?

EDIT: Now I am adding the code.

Here is my MainActivity class

public class MainActivity extends Activity {

    public static final String TAG="App1";
    private ActionReceiver receiver = null;

    //private YourBroadcastReceiverClassName yourBR = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // receiver= new ActionReceiver();
        //IntentFilter filter = new IntentFilter();
        //filter.addAction("com.example.app1.printSomething");

        // printSomething();

    }

    public void printSomething(){
        Toast.makeText(this,"Hello World",Toast.LENGTH_LONG);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

  }

This is my ActionReceiver class which is BroadcastReceiver

public class ActionReceiver extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
        if("com.example.app1.printSomething".equalsIgnoreCase(intent.getAction()))
            Toast.makeText(context,"Hello World", Toast.LENGTH_LONG).show();
    }
}

This is my AndroidManifest.xml file:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.app1"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="7"
        android:targetSdkVersion="16" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.app1.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

        </activity>
        <receiver android:name=".ActionReceiver">
            <intent-filter>
                <action android:name="com.example.app1.printSomething"/>
            </intent-filter>
        </receiver>
    </application>

</manifest>

Now, I want to call printSomething() Method written in MainActivity from onReceive() in ActionReceiver class. But I don't want to launch MainActivity for that. Can it be done?

Rohit Singh
  • 16,950
  • 7
  • 90
  • 88
Kiran
  • 747
  • 2
  • 10
  • 35
  • Hello @Kiran...Even I am trying to enable/disable a button of MainActivity from a broadcast receiver...Your question is some what related to that.Did you find any solution for this..If yes,kindly share it.... – Prabs Feb 27 '15 at 12:33
  • 1
    Hi @PrathibhaKirthi I did it in hardway. I registered a broadcast receiver for mainactivity and I am using that to call the method. – Kiran Mar 04 '15 at 04:36
  • I did the same @KIran..Its working.. :) – Prabs Mar 04 '15 at 06:12

5 Answers5

1

you can call a method inside MainActivity without instantiating it. You just need to fetch a reference to the hosting Activity. Making it static is not obligatory:

((MainActivity) getActivity()).printSomething();

in MainActivity:

public void printSomething() {
      doStuff();
}
bofredo
  • 2,348
  • 6
  • 32
  • 51
  • i am running this out of a fragment that gets hosted by MainActivity. I am not 100% sure if it works with the receiver too. – bofredo Oct 16 '13 at 10:21
  • 1
    Hi, when I tried to execute the above line in `OnReceive()` method of `BroadcastReceiver`, it is giving an error saying can't find symbol method `getActivity()`. Can you tell me what I am missing? – Kiran Oct 16 '13 at 17:44
  • you have to get the context of the activity. I thought it was getActivity(). I looked it up, you need context.printSomething(). I will alter my answer – bofredo Oct 16 '13 at 18:32
  • 2
    Hi, I updated my code by using context as `((MainActivity)context.getApplicationContext()).printSomething()` in `onReceive()` method of `BroadcastReceiver`. The app is installed perfectly. In the second application I am creating a broadcast intent for this Receiver but "the application is stopping unexpectedly". So, can you tell me whether this will work? – Kiran Oct 17 '13 at 18:44
  • psot some errorlog from logcat please. hard to figure it else – bofredo Oct 17 '13 at 19:55
0

If u just need to execute a method without create an instance, make that method static.

if u cant make that method static, you need to get the instance of that activity.

EDIT:

if u want to execute a method in a instance, you have to create that instance. that means that u have to create and start an activity. if u want to execute a method without the activity, just create that method static.

modify the method in the activity:

public static void printSomething(){
    Toast.makeText(this,"Hello World",Toast.LENGTH_LONG);
}

and then call it from your broadcast:

@Override
    public void onReceive(Context context, Intent intent) {
        if("com.example.app1.printSomething".equalsIgnoreCase(intent.getAction()))
          MainActivity.printSomething();
    }
carlo.marinangeli
  • 2,958
  • 2
  • 17
  • 17
  • EEven I tried to make instance of that activity by calling `(new MainActivity()).thatMethod()` But it is not working... – Kiran Oct 10 '13 at 20:39
  • you cant make an instance of that activity in that way. you should set that instance in the class with the broadcast to do that. I'm sorry but without the code I cant understand what u want to do – carlo.marinangeli Oct 10 '13 at 20:58
  • I modified my answer. is the only way u can do that (without an instance of the activity) – carlo.marinangeli Oct 16 '13 at 10:08
0

There are few possible solutions, you can use Local Broadcast Receiver to send the message to your activity, in this case you need to subscribe your activity.

Or you can use EventBus for that, that could be Otto event bus or GreenDroid... In this case you would do the same, subscribe your activity to event bus but in more elegant way :)

Viktor Yakunin
  • 2,927
  • 3
  • 24
  • 39
0

Create a Callback

You can use interface to communicate back to Activity(ie invoking methods of Activity).

1) Create a CallBack interface

public interface ReceiverCallback{

    public void doSomeTask();

} 

2) Add this Callback in your Broadcast receiver

public class ActionReceiver extends BroadcastReceiver{

    private ReceiverCallback callback; 

    public ActionReceiver(ReceiverCallback callback){
        this.callback = callback;         //<--- Initialse callback
    }

    @Override
    public void onReceive(Context context, Intent intent) {

        callback.doSomeTask();

    } 
}

3) Implement in your Activity and Override the doSomeTask() method

public class MainActivity extends Activity implements ReceiverCallback{

    // Activity related Code //


   public void printSomething(){
    Toast.makeText(this,"Hello World",Toast.LENGTH_LONG);
   }

   @Override
   public void doSomeTask(){
       printSomething()        //<-- call your method
   }

Advantage?

Using an interface makes a BroadcastReceiver decoupled(independent) of any Activity. You can use this BroadcastReceiver with any Activity without any code-change in the BroadcastReceiver. Which is awesome.

Relevant Link:

If you want to read an even deeper explanation you can READ THIS

Rohit Singh
  • 16,950
  • 7
  • 90
  • 88
-3

You can do it like this in the BroadcastReceiver class:-

   MainActivity mainActivity;

@Override
public void onReceive(Context context, Intent intent) {
    if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
        mainActivity= new MainActivity();
        mainActivity.printSomething();



    }
Muiruri
  • 45
  • 6
  • 1
    this won't get to the running activity, but will creatr an empty instance of the Activity Class, but not the one we want - which is on screen – zaxy78 Sep 17 '14 at 15:46