系统重启后,在广播接收器中显示警告对话框

时间:2012-01-07 02:07:07

标签: android

美好的一天,我想在广播接收器中重启系统后显示警告对话框。我在清单中添加了接收器并调用了所需的权限,但在显示对话框时出错。请问我该如何正确实现?谢谢

我的代码:

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)

7 个答案:

答案 0 :(得分:46)

问题是您尝试显示来自AlertDialog的{​​{1}},这是不允许的。您无法从BroadcastReceiver显示AlertDialog。只有活动才能显示对话框。

您应该做其他事情,让BroadcastReceiver启动时启动并启动活动以显示对话框。

此处有blog post更多信息。

编辑:

以下是我推荐的方法。从BroadcastReceiver开始BroadcastReceiverActivity为......

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(); } } } } 。这是因为活动将具有透明视图,并且仅显示警告对话框。

答案 1 :(得分:27)

你不能在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();
}
}

我得到了答案?,在这里:How do you use an alert dialog box in a broadcast receiver in android? 感谢Femi !!,我只传播新闻:D

答案 2 :(得分:7)

以下是关于如何操作的post。您可以从here获取源代码。

您无法直接从广播接收器显示对话框。您必须使用Activity。此外,为了接收ACTION_BOOT_COMPLETED您的活动必须首先由用户或其他应用程序明确启动(谷歌应用程序停止状态以获取更多信息)。

基本上,要实现所需的功能,您需要执行以下操作:

  1. 创建显示对话框的透明活动。
  2. 创建接收BroadcastReceiver的{​​{1}}并开始您的活动。
  3. 在清单中注册您的广播接收器并获得适当的许可。
  4. 此外,this问题提供了有关如何创建透明活动的更多信息。

答案 3 :(得分:3)

最好的方法是制作一个活动并将其“主题”属性设置为“Theme.Translucen”

NULL

并在您的活动中创建一个警告对话框:

 <activity
        android:name=".MyAlertDialog"
        android:label="@string/title_activity_alert_dialog"
        android:launchMode="singleInstance"
        android:theme="@android:style/Theme.Translucent" >
    </activity>

和brodcastreciver:

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

}

}

答案 4 :(得分:1)

  1. 无法从广播接收器显示对话框。
  2. 我们应该只显示来自活动的对话框。
  3. 但是您的应用程序上下文只有广播接收器,那么我们应该以&#34; FLAG_ACTIVITY_NEW_TASK&#34;启动活动,然后创建堆栈。
  4. 如果我们使用此标志启动活动&#34; FLAG_ACTIVITY_NEW_TASK&#34;我们无法从筹码中删除。

  5. 因此在关闭应用程序之后,我们尝试从堆栈启动应用程序,它显示相同的Activity,因为此活动具有标记&#34; FLAG_ACTIVITY_NEW_TASK&#34;,所以它不应该创建新实例并使用现有实例。

  6. 但我们只想展示对话一次。为此,我们需要处理程序化的盟友。

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

    这对我有用。

答案 5 :(得分:0)

这可能是陈旧的并且回答了问题,但回答的答案根本没用。

  

您无法在onReceive()的实现中启动弹出对话框。   BroadcastReceiver

您可以使用以对话框

为主题的活动,而不是对话框或popupWindow
 <activity 
   android:taskAffinity=""
   android:name=".activity.CallActivity"
   android:label="@string/app_name"
   android:theme="@style/AppTheme.Dialog" />

请注意,我添加 taskAffinity 在块内(AndroidManifest.xml)

然后你可以将它用作常规活动。

Intent intentPhoneCall = new Intent(context, CallActivity.class);
intentPhoneCall.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intentPhoneCall.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intentPhoneCall);

希望它有所帮助。快乐的编码。

答案 6 :(得分:0)

在 onReceive 中调用 Intent 时,您只需要将它放入延迟 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);
}