美好的一天,我正在尝试在广播接收器中的系统重新启动后显示警报对话框。我已在清单中添加了接收器并调用了所需的权限,但在显示对话框时出现错误。请问我怎样才能正确实现这个?..谢谢
我的代码:
public void onReceive(final Context context, Intent intent) {
Log.d(TAG, "received boot completed broadcast receiver... starting settings");
String settings = context.getResources().getString(R.string.restart_setting);
String yes = context.getResources().getString(R.string.Settings);
String no = context.getResources().getString(R.string.Cancel);
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(settings)
.setCancelable(false)
.setPositiveButton(yes, new DialogInterface.OnClickListener() {
public void onClick(@SuppressWarnings("unused") final DialogInterface dialog, @SuppressWarnings("unused") final int id)
Intent config = new Intent(context, WeatherConfigure.class)
context.startActivity(config);
}
})
.setNegativeButton(no, new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, @SuppressWarnings("unused") final int id) {
dialog.cancel();
}
});
final AlertDialog alert = builder.create();
alert.show();
}
收到此日志错误:
01-07 01:42:01.559: ERROR/AndroidRuntime(2004): Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
01-07 01:42:01.559: ERROR/AndroidRuntime(2004): at android.view.ViewRoot.setView(ViewRoot.java:548)
01-07 01:42:01.559: ERROR/AndroidRuntime(2004):at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
01-07 01:42:01.559: ERROR/AndroidRuntime(2004): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
01-07 01:42:01.559: ERROR/AndroidRuntime(2004):at android.app.Dialog.show(Dialog.java:288)
01-07 01:42:01.559: ERROR/AndroidRuntime(2004):at com.MuaaApps.MyWeatherUpdate.myWeatherBroadcastReceiver.onReceive(MyWeatherBroadcastReceiver.java:59)
01-07 01:42:01.559: ERROR/AndroidRuntime(2004): at android.app.ActivityThread.handleReceiver(ActivityThread.java:1994)
问题是您试图从
AlertDialog
显示 BroadcastReceiver
,这是不允许的。您无法从 AlertDialog
显示 BroadcastReceiver
。只有活动才能显示对话框。
您应该执行其他操作,让
BroadcastReceiver
像您一样启动并启动一个活动来显示对话框。
这里有一篇博客文章,有更多相关内容。
编辑:
这是我建议的做法。从您的
BroadcastReceiver
开始一个 Activity
与 AlertDialog
这样..
public class NotifySMSReceived extends Activity
{
private static final String LOG_TAG = "SMSReceiver";
public static final int NOTIFICATION_ID_RECEIVED = 0x1221;
static final String ACTION = "android.provider.Telephony.SMS_RECEIVED";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
IntentFilter filter = new IntentFilter(ACTION);
this.registerReceiver(mReceivedSMSReceiver, filter);
}
private void displayAlert()
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Are you sure you want to exit?").setCancelable(
false).setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
}).setNegativeButton("No",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
private final BroadcastReceiver mReceivedSMSReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION.equals(action))
{
//your SMS processing code
displayAlert();
}
}
}
}
正如你在这里看到的,我从来没有打电话过
setContentView()
。这是因为该活动将具有透明视图,并且仅显示警报对话框。
你不能在BroadcastReceiver上使用对话框, 因此,您最好从 BroadcastReceiver 调用对话框的活动,
将此代码添加到您的 onReceive 函数中:
@Override
public void onReceive(Context context, Intent intent)
{
Intent i = new Intent(context, {CLASSNAME}.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
用对话框活动填充 {CLASSNAME},这是我的对话框活动:
package com.example.mbanking;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
// ALERT DIALOG
// Sources : http://techblogon.com/alert-dialog-with-edittext-in-android-example-with-source-code/
public class AlertDialogActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder
.setTitle("Test")
.setMessage("Are you sure you want to exit?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
dialog.cancel();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
}
我在哪里得到答案?,在这里:如何在 Android 的广播接收器中使用警报对话框? 感谢 Femi !!,我刚刚传播了这个消息 :D
最好的方法是制作一个 Activity 并将其“主题”属性设置为“Theme.Translucent”
<activity
android:name=".MyAlertDialog"
android:label="@string/title_activity_alert_dialog"
android:launchMode="singleInstance"
android:theme="@android:style/Theme.Translucent" >
</activity>
并在您的活动中创建一个警报对话框:
public class MyAlertDialog extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); //hide activity title
setContentView(R.layout.activity_my_alert_dialog);
AlertDialog.Builder Builder=new AlertDialog.Builder(this)
.setMessage("Do You Want continue ?")
.setTitle("exit")
.setIcon(android.R.drawable.ic_dialog_alert)
.setNegativeButton(R.string.No, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
MyAlertDialog.this.finish();
}
})
.setPositiveButton(R.string.Yes,null);
AlertDialog alertDialog=Builder.create();
alertDialog.show();
}
}
在广播接收器中:
@Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context.getApplicationContext(),MyAlertDialog.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
这可能是旧的且已回答的线程,但已回答的答案根本没有帮助。
您无法在 onReceive() 的实现中启动弹出对话框。 广播接收器
您可以使用主题为对话框的活动来代替对话框或弹出窗口
<activity
android:taskAffinity=""
android:name=".activity.CallActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.Dialog" />
请注意,我在块(AndroidManifest.xml)内添加taskAffinity
然后您就可以将其用作常规活动。
Intent intentPhoneCall = new Intent(context, CallActivity.class);
intentPhoneCall.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intentPhoneCall.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intentPhoneCall);
希望有帮助。快乐编码。
如果我们使用此标志“FLAG_ACTIVITY_NEW_TASK”启动活动,我们无法从堆栈中删除。
因此,关闭应用程序后,我们尝试从堆栈启动应用程序,它显示相同的 Activity,因为该 Activity 具有标志“FLAG_ACTIVITY_NEW_TASK”,所以它不应该创建新实例并使用现有实例。
但我们只想显示该对话框一次。为此,我们需要处理编程盟友。
if (count == 0) {
mBuilder = new Dialog(this);
mMsg = getIntent().getStringExtra(AlarmSchedulerUtils.EXTRA_MSG);
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
mRingTome = RingtoneManager.getRingtone(ReminderDialog.this, notification);
mRingTome.play();
count++;
showReminderDialog();
} else {
Intent intent=new Intent(ReminderDialog.this,SplashActivity.class);
startActivity(intent);
finish();
}
这对我有用。
在 onReceive 上调用意图时,你只需要把它放入延迟 400 毫秒的处理程序中,对我来说,它就像魅力一样醒来
@Override
public void onReceive(Context context, Intent intent)
{
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Intent i = new Intent(context, {CLASSNAME}.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}, 400);
}