Search code examples
javaandroidbroadcastreceiverandroid-alertdialogandroid-context

Retrieving calling context in a BroadcastReceiver()


I am trying to show a alert dialog fragment from a broadcast receiver but the receiver is not in the activity that will be showing the fragment (the receiver handles all errors broadcast on this event, regardless of whether it is active activity or not).

Here is my current receiver:

private BroadcastReceiver mHttpPostReceiver = new BroadcastReceiver() {
      @Override
      public void onReceive(Context context, Intent intent) { 
              if (intent.getStringExtra("Error") != null) { // error occurred
                      // called from a fragment in another activity
                      NetworkError.show(((Activity) context).getFragmentManager(), error);
               }
      }
};        

But the context parameter in the function is the current context of the activity it is in and causes runtime illegal state exceptions since this activity isn't on the screen. Is there any way to send the calling function's context like through the broadcast? Or is there another way I should be implementing this?

The specific error I am currently getting is:

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState


Solution

  • You should add extras that say the calling Activity from the Intent that you are bcroadcasting, then based on that, writes to something like SharedPreferences. Then in the Activity's onResume(), you check to see if the preferences' key contains a message, and updates the UI then.

    Eg

    @Override
    public void onReceive(Context context, Intent intent) { 
      if (intent.getStringExtra("Error") != null) { 
        String callingActivity = intent.getStringExtra ("CallingActivity");
        if (callingActivity != null);
        context.getSharedPreferences (callingActivity, Context.MODE_PRIVATE).edit().putString ("errorMessage", "You have an error").commit();
      }
    }
    

    Then in each Activity's onResume()

    @Override
     protected void onResume()
    {
      super.onResume();
      String errorMsg =context.getSharedPreferences ("ThisActivityName", Context.MODE_PRIVATE).getString ("error");
      if (errorMsg.equals ("You have an error")){
        //update fragment code here.  
        //set SharedPreference errorMessage key to hold something else.
      } 
    }
    

    The way I have it, each Activity has its own SharedPreferences database, with the database name the same name as callingActivity. This means when you read in from onResume(), "ThisActivityName" should be the same string as callingActivity. But this is the main idea, you can modify this.