0

Ok, there is stated id documentation:

You cannot launch a popup dialog in your implementation of onReceive().

Nevertheless, this code is beatufilly working:

public class MainActivity extends AppCompatActivity {
    final String ACTION = "myActionForBroadcast";

    private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d("MyTag", "onReceive: context" + context.getPackageCodePath());
            showDialog();
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        IntentFilter filter = new IntentFilter();
        filter.addAction(ACTION);
        registerReceiver(broadcastReceiver, filter);

        final Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                Log.d("MyTag", "Handler run: before send broadcast");
                sendBroadcast(new Intent(ACTION));
            }
        }, 5_000);
    }

    private void showDialog() {
        final AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);

        builder.setTitle("Title");
        builder.setMessage("Message");

        builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText(MainActivity.this, "Dialog: onClick()", Toast.LENGTH_SHORT).show();
            }
        });

        Log.d("MyTag", "showDialog: before showing dialog");
        builder.show();
        Log.d("MyTag", "showDialog: before showing toast");
        Toast.makeText(MainActivity.this, "showDialog: showing toast", Toast.LENGTH_SHORT).show();
    }
}

Why is it working? What am I missing in documentation?? Thanks.

Goltsev Eugene
  • 3,325
  • 6
  • 25
  • 48
  • 2
    Yeah, that's not written very well. I believe what they're trying to say is that you can't use the `Context` passed into to `onReceive()` to create and display a `Dialog`. A `Dialog` needs an `Activity` `Context`, which the `Context` passed into `onReceive()` is not. In your case, the `BroadcastReceiver` is an inner class of `MainActivity`, and you're using `MainActivity`'s `Context` to create the `Dialog`, so it's good. – Mike M. Apr 17 '16 at 16:05
  • Ah, ok. I saw the coming context is BroadcastRestrictedContext, something like that. But Toast can be shown with this context, right? – Goltsev Eugene Apr 17 '16 at 16:12
  • 1
    Yes, you can show a `Toast` with that `Context`. – Mike M. Apr 17 '16 at 16:18

2 Answers2

2

In my opinion, your 'showDialog()' method is called by using Context from an Activity (your MainActivity) which is allowed, not by using Context from a BroadcastReceiver which is not allowed. You can refer this answer for more details: show an alert dialog in broadcast receiver after a system reboot

Community
  • 1
  • 1
sonngaytho
  • 111
  • 5
1

The alert dialog shows because you use the context of MainActivity to build that dialog. AlertDialog needs activity context to build, not application context, or service context. The doc says because sometimes the context you get from the first parameter passed in

onReceive(Context context, Intent intent)

may not be an activity context. actually, for dynamic broadcast receivers, the context you get from onReceive(Context context, Intent intent) depends on where you register them. If you register it in activity, then the context is Activity. Or Application if you do it in application instance. And you cannot build dialog using Application context, it will cause crash.

for static broadcast receivers, the context is BoradcastRestrictedContext, which is definitely cannot be used to build dialogs.

G.Zxuan
  • 66
  • 3