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

问题描述 投票:0回答:7

美好的一天,我正在尝试在广播接收器中的系统重新启动后显示警报对话框。我已在清单中添加了接收器并调用了所需的权限,但在显示对话框时出现错误。请问我怎样才能正确实现这个?..谢谢

我的代码:

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)
android
7个回答
51
投票

问题是您试图从

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


29
投票

你不能在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


7
投票

这里有一篇关于如何操作的post。您可以从here获取源代码。

您无法直接从广播接收器显示对话框。您必须使用

Activity
。此外,为了接收
ACTION_BOOT_COMPLETED
,您的活动必须首先由用户或另一个应用程序显式启动(谷歌应用程序停止状态以获取更多信息)。

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

  1. 创建显示对话框的透明活动。
  2. 创建
    BroadcastReceiver
    ,接收
    ACTION_BOOT_COMPLETED
    并开始您的活动。
  3. 在清单中注册您的广播接收器并获取适当的权限。

此外,this问题提供了有关如何创建透明活动的更多信息。


7
投票

最好的方法是制作一个 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);

    }
}

4
投票

这可能是旧的且已回答的线程,但已回答的答案根本没有帮助。

您无法在 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);

希望有帮助。快乐编码。


1
投票
  1. 无法从广播接收器显示对话框。
  2. 我们应该只显示 Activity 中的对话框。
  3. 但是您的应用程序上下文只有广播接收器,那么我们应该将活动启动为“FLAG_ACTIVITY_NEW_TASK”,然后它创建堆栈。
  4. 如果我们使用此标志“FLAG_ACTIVITY_NEW_TASK”启动活动,我们无法从堆栈中删除。

  5. 因此,关闭应用程序后,我们尝试从堆栈启动应用程序,它显示相同的 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();
        }

这对我有用。


-1
投票

在 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);
}
© www.soinside.com 2019 - 2024. All rights reserved.