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。
好的,有说明的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。