Android Broadcastreceiver 为什么启动弹出窗口

Android Broadcastreceiver why popup is launching

好的,有说明的id documentation:

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

尽管如此,此代码运行良好:

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();
    }
}

为什么有效?我在文档中缺少什么?? 谢谢

在我看来,您的 'showDialog()' 方法是通过使用来自 Activity(您的 MainActivity)的 Context 调用的,这是允许的,而不是使用来自 BroadcastReceiver 的 Context不允许。 您可以参考此答案以获取更多详细信息:show an alert dialog in broadcast receiver after a system reboot

显示警告对话框是因为您使用 MainActivity 的上下文来构建该对话框。 AlertDialog 需要 activity 上下文来构建,而不是应用程序上下文或服务上下文。 文档说因为有时你从传入的第一个参数中获得的上下文

onReceive(Context context, Intent intent)

可能不是 activity 上下文。 实际上,对于动态广播接收器,您从 onReceive(Context context, Intent intent) 获得的上下文取决于您注册它们的位置。如果你在activity中注册它,那么上下文就是Activity。或者如果您在应用程序实例中执行此操作,则为应用程序。并且您不能使用应用程序上下文构建对话框,它会导致崩溃。

对于静态广播接收器,context是BoradcastRestrictedContext,绝对不能用来构建dialogs。