0

I have the following android code snippet

public class Alarm extends BroadcastReceiver
{
    public void makeQuery(String symbol) {   
        RequestQueue queue = Volley.newRequestQueue(Alarm.this);
        ....

and I am trying to call makeQuery from my main activity. However, during compilation, I get the following error:

actual argument Alarm cannot be converted to Context by method invocation conversion

I understand that the current object cannot be converted into a context, which Volley obviously needs. Is this a property of BroadcastReceiver? Can the this-variable only be converted into a context for special classes? Should I move this function makeQuery into a different class?

I am preliminary interested in an explanation rather than a solution!

In Addition: The current setup is for testing purposes only. The method later is called from within the Alarm class itself! Then there is no Main Activity! I need a solution to make it work then!

MainActivity.java:

public class MainActivity extends AppCompatActivity {    

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

        Alarm alarm = new Alarm();
        alarm.makeQuery("Test");
Mohammed Aouf Zouag
  • 17,042
  • 4
  • 41
  • 67
Alex
  • 41,580
  • 88
  • 260
  • 469

3 Answers3

4

Use the application's context to avoid leaking the Activity or the broadcast receiver if someone passes one in:

public class Alarm extends BroadcastReceiver
{
    private Context mContext;

    public Alarm() {}

    public Alarm(Context context) {
        mContext = context;
    }

    public void makeQuery(String symbol) {
        RequestQueue queue = Volley.newRequestQueue(mContext.getApplicationContext());
    }

    ....
}

The RequestQueue expects an Activity or an Application context:

MainActivity.java

Alarm alarm = new Alarm(this); // Pass in the Activity's context
alarm.makeQuery("Test");
Mohammed Aouf Zouag
  • 17,042
  • 4
  • 41
  • 67
  • Calling the method from the main activity is just for testing purposes. I plan to call this method later from the Alarm class itself! Then I have no context and your suggestion does not work! – Alex Nov 22 '15 at 10:52
  • Well, this class will be instantiated, sooner or later right ? – Mohammed Aouf Zouag Nov 22 '15 at 10:52
  • But now I get an error during running: "Alarm has no zero argument constructor" upon trying – Alex Nov 22 '15 at 10:58
  • 1
    add the no-args constructor : `public Alarm() {}` – Mohammed Aouf Zouag Nov 22 '15 at 10:59
  • yes, sure! After reading the error again, I also came up with this. I just hope, the class is never instantiated and used without argument, as the context will be null... – Alex Nov 22 '15 at 11:01
  • I believe that you will never have to use the **no-args** constructor, since you control the instantiation of the object, you can always choose the **overloaded** one. – Mohammed Aouf Zouag Nov 22 '15 at 11:03
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/95835/discussion-between-alex-and-jdev). – Alex Nov 22 '15 at 11:04
1

BroadcastReceiver not inherits from Context, so you can't use your Alarm class as context.

You can use the activity Context:

public void makeQuery(Context context, String symbol) {   
        RequestQueue queue = Volley.newRequestQueue(context);
        ....
}

And from activity:

Alarm alarm = new Alarm();
alarm.makeQuery(MainActivity.this, "Test");
Rami
  • 7,879
  • 12
  • 36
  • 66
  • But WHY is that? I am more interested in the WHY? Does a BroadcastReceiver not have a context? – Alex Nov 22 '15 at 10:47
  • 1
    Activity inherits Context while BroadcastReceiver not, so you can cast an Activity to Context and not a BroadcastReceiver. – Rami Nov 22 '15 at 10:54
1

Here:

RequestQueue queue = Volley.newRequestQueue(Alarm.this);

Alarm extending BroadcastReceiver but BroadcastReceiver is not sub-class of Context class. so it's not possible to use the class's context which is not extending Service,Activity,FragmentActivity,... as Context.

In BroadcastReceiver onReceive method contains two parameters first parameter is Context which you can also use as a Context for creating Volley requests. like:

Mohammed Aouf Zouag
  • 17,042
  • 4
  • 41
  • 67
ρяσѕρєя K
  • 132,198
  • 53
  • 198
  • 213
  • Finally an explanation which makes sense! Thanks – Alex Nov 22 '15 at 10:53
  • @Alex: my question is why extending `BroadcastReceiver ` in Alarm class? – ρяσѕρєя K Nov 22 '15 at 11:01
  • I followed an example given here (the idea later is that this method is being called from with this Alarm class, set up by a service): http://stackoverflow.com/questions/4459058/alarm-manager-example – Alex Nov 22 '15 at 11:03