-1

I searched a lot but didn't find the solution to the following issue.

Context :

  • I use an AsyncHttpResponseHandler object to handle all my webservice responses
  • If I get a particular error code from the WS, I want to show an alert dialog (whatever the activity currently displayed)
  • I came to think that using the LocalBroadcastManager would be a good solution as the HTTP handler is not aware of the currently displayed activity

Problem : After implementation of all what seems to be needed to make it work, my intent sent from the async handler is not received.

Additional note :

  • the ApplicationContext is stored in my StaticItems class which contains all the static data I need in my app.It is setup via a custom class which inherits from Application
  • If I broadcast the intent from an activity, the OnReceive event is triggered

I thank you in advance for any help you could provide.

Cheers !

Here are some pieces of my code :

The code in the http handler

public class AsyncResponseHandler extends AsyncHttpResponseHandler {
    @Override
    public void onSuccess(int statusCode, Header[] headers, byte[] response) {
        if(response != null && response.length > 0) {
            CrvData data = JsonHelper.getCrvData(new String(response));
            String code = data.getErrorCode();
            if (!TextUtils.isEmpty(code) && code.equals(StaticItems.C_WS_OBSOLETE_VERSION_ERROR)) {
                Intent intent = new Intent();
                intent.setAction(StaticItems.BROADCAST_INTENT_MESSAGE);
                intent.addCategory(Intent.CATEGORY_DEFAULT);
                intent.setData(Uri.parse(data.getValue()));
            LocalBroadcastManager.getInstance(StaticItems.applicationContext).sendBroadcast(intent);
        }
    }
}

The code of the root Activity I use for all my activities :

public class MainActivity extends Activity {

    /**
     * The local broadcast receiver
     */
    protected MyBroadcastReceiver mMessageReceiver = new MyBroadcastReceiver();

    @Override
    protected void onResume() {
        super.onResume();
        // register
        IntentFilter filter = new IntentFilter();
        filter.addCategory(Intent.CATEGORY_DEFAULT);
        filter.addAction(StaticItems.BROADCAST_INTENT_MESSAGE);
        LocalBroadcastManager.getInstance(StaticItems.applicationContext).registerReceiver(mMessageReceiver, filter);
    }

    @Override
    protected void onPause() {
        super.onPause();
        // Unregister
        LocalBroadcastManager.getInstance(StaticItems.applicationContext).unregisterReceiver(mMessageReceiver);
    }
}

The receiver

public class MyBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(final Context context, final Intent intent) {
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setInverseBackgroundForced(true)
                .setNegativeButton(context.getResources().getString(R.string.dlg_no), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                })
                .setIcon(R.drawable.ic_dialog_alert_holo_light)
                .setMessage(R.string.dlg_app_is_obsolete)
                .setPositiveButton(context.getResources().getString(R.string.dlg_yes), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        context.startActivity(intent);
                    }
                });
        builder.show();
    }
}
MarsNoToshi
  • 192
  • 1
  • 9
  • Is `MainActivity ` still running while you send the broadcast? – Emil Sep 01 '15 at 12:12
  • Have you considered an [EventBus](https://github.com/greenrobot/EventBus)? – Knossos Sep 01 '15 at 12:12
  • @Boss As the current displayed activity is a MainActivity (as all the activities in my app), yes it is – MarsNoToshi Sep 01 '15 at 12:15
  • @Knossos nope I wasn't aware of this project. I'll look a it. Though, I would like to understand why my code is not working – MarsNoToshi Sep 01 '15 at 12:15
  • From which part of your `MainActivity` code you are sending the broadcast, can you tell us that? – Emil Sep 01 '15 at 12:18
  • 1
    You know for sure that onReceive is not called? Or you just don't see the dialog coming? – natario Sep 01 '15 at 12:20
  • @Boss The broadcast can be sent from many places. There are http calls from some onResume of an activity or after a user action (click event, mainly) – MarsNoToshi Sep 01 '15 at 12:20
  • @mvai for sure. I put a breakpoint in the onReceive method of the receiver. Furthermore, as mentioned, If I send the broadcast from the activity, the onReceive is triggered. – MarsNoToshi Sep 01 '15 at 12:24
  • If you are sending the broadcast from an activity the `onReceive` is called. Then from where else are you sending that now? I didn't understand that.. – Emil Sep 01 '15 at 12:27
  • @Boss I edited my post. The declaration of the AsyncResponseHandler class (partially but enough of it) has beed added – MarsNoToshi Sep 01 '15 at 12:28

4 Answers4

1

I had a similar problem, for some reason you can not setData(..) on Intent returned via LocalBroadcastManager, when I placed my URI in the extra data, it started to work.... possibly a bug?

pkzip
  • 71
  • 4
0

My guess is that the context you are using is not an activity context and thus can't be used for creating dialogs.

Namely, the context that is passed to onReceive in this case should be your application context, StaticItems.applicationContext, which is not good for showing dialogs.

If this is the case, you should somehow rearrange your code to make sure to pass an activity context rather than the application one.

natario
  • 24,954
  • 17
  • 88
  • 158
  • I understand your guess but the thing is no breakpoint inside the onReceive is reached. As a result I don't think this is the problem – MarsNoToshi Sep 01 '15 at 12:31
  • So your question should be: why `LocalBroadcastManager.getInstance(appContext).sendBroadcast(intent)` works when called from activity and doesn't work when called from another class. I actually see no difference between the two, so there should be another error somewhere (`if` clauses in the onSuccess?). As for the dialog not showing, I'm pretty sure it is a `Context` issue. It is well documented that dialog builder works only with activity contexts. – natario Sep 01 '15 at 13:53
  • Thank you for pointing me to the right direction. I haven't done a copy/paste. After looking at the differences, I found out the issus (answer below) – MarsNoToshi Sep 01 '15 at 14:27
0

Remove addCategory() from your IntentFilter

was solved here

Yazazzello
  • 6,053
  • 1
  • 19
  • 21
  • Thanks for the link but it is not working either. As mentioned by the OP in a comment : _the IntentFilter instance and the Intent instance should have the same category. I modify the code to use the same category for IntentFilter and it works great._ – MarsNoToshi Sep 01 '15 at 13:19
0

OK so... I figured out that the intent was not received because of this line : intent.setData(Uri.parse(data.getValue()));

And as @mvai pointed, the dialog cannot be displayed from the application context. I managed to get the current activity by having a reference to it in my application class. (I checked out to be sure for not having any memory leak)

MarsNoToshi
  • 192
  • 1
  • 9