在BroadcastReceiver中创建AlertDialog??这可行吗?

9

在广播接收器中创建AlertDialog?这可行吗?我正在开发一个应用程序,如果我收到短信,它将弹出一个对话框。我试图在BroadcastReceiver中编写此代码。但是我无法使用以下代码行 AlertDialog.Builder builder = new AlertDialog.Builder(this);。请问有人能给我一些提示吗!

public class SMSPopUpReceiver extends BroadcastReceiver {

    private static final String LOG_TAG = "SMSReceiver";
    public static final int NOTIFICATION_ID_RECEIVED = 0x1221;
    static final String ACTION = "android.provider.Telephony.SMS_RECEIVED";

    public void onReceive(Context context, Intent intent) {
        Log.i(LOG_TAG, "onReceive");

        if (intent.getAction().equals(SMSPopUpReceiver.ACTION)) {
            StringBuilder sb = new StringBuilder();
            Bundle bundle = intent.getExtras();
            if (bundle != null) {
            Object[] pdus = (Object[]) bundle.get("pdus");

            for (Object pdu : pdus){
                    SmsMessage messages =
            SmsMessage.createFromPdu((byte[]) pdu);

            sb.append("Received SMS\nFrom: ");
            sb.append(messages.getDisplayOriginatingAddress());
            sb.append("\n----Message----\n");
            sb.append( messages.getDisplayMessageBody());
            }
            }
            Log.i(SMSPopUpReceiver.LOG_TAG,
            "[SMSApp] onReceiveIntent: " + sb);
            Toast.makeText
            (context, sb.toString(), Toast.LENGTH_LONG).show();
            }

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

}

为什么您无法使用 AlertDialog.Builder builder = new AlertDialog.Builder(this);,它是否不满意 this 引用?如果是这种情况,请尝试将其替换为调用 getApplicationContext()。我不确定这是否是您遇到的问题。我觉得在这种情况下,对话框只会在 BroadcastReceiver 返回之前在屏幕上闪烁一秒钟。 - Will Tate
无法使用getApplicationContext()! - Java Review
在用户的角度来看,突然弹出一个对话框听起来像是糟糕的界面设计。为什么不使用通知呢?那正是它们的用途所在。 - Edward Falk
这是完整的示例,请查看链接 http://stackoverflow.com/a/41137562/4344659 - Sanjeev Sangral
5个回答

13

主要问题:尽量避免将耗时的功能放入 BroadcastReceiver 中,它只应接收并在绑定的 Activity/Service 中启动进一步处理。

更新:

请参考以下可能有用的来源:

StackOverflow 上的类似问题:

如何将数据从 BroadcastReceiver 发送到 Android 的 Activity 中?

Android 短信接收器不工作

Android SDK 演示示例:

android-sdk-windows\samples\android-8\ApiDemos\src\com\example\android\apis\os\SmsMessagingDemo.java

当然还有标准的 Android API 文档:http://developer.android.com/reference/android/content/BroadcastReceiver.html

更新2:

添加应用程序框架,应该是这样的。请注意,没有定义内容视图。这是因为您的应用程序将具有透明屏幕。为了实现这一点

@android:style/Theme.Translucent

在 AndroidManifest.xml 文件中为此活动输入在 Theme 标记下。

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

我认为你是正确的。你能帮我解决这个问题吗? - Java Review
请问您能告诉我在哪里查找吗?我对这一切都很陌生。如果您愿意,可以通过Google Talk与我联系,我的用户名是StutteringJohnSmith。 - Java Review
更新了我的答案,包括有用的知识来源。 - Zelimir
@Zelimir 如何在从命令提示符触发事件后,从活动中显示对话框? - AndroidOptimist
你的意思是使用adb(因为你提到了命令提示符)?你可以定义广播Intent并从通过adb连接的手机的命令提示符发送它(请查看文档)。你可以调整你的应用程序以在接收该广播时做出反应并相应地触发一些活动。这是否是你所询问的内容,还是完全失败了? - Zelimir
显示剩余7条评论

7
我一直在研究,并且BroadcastReceiver的文档实际上说:

public abstract void onReceive (Context context, Intent intent)
自API Level 1开始,在广播接收器接收到意图广播时调用此方法。在此期间,您可以使用BroadcastReceiver上的其他方法来查看/修改当前结果值。该函数通常在其进程的主线程中调用,因此您不应在其中执行长时间运行的操作(系统允许10秒的超时时间,否则会认为接收器被阻塞并成为可能被杀死的候选对象)。您不能在onReceive()的实现中启动弹出对话框。

您不能在onReceive()的实现中启动弹出对话框。

因此似乎不可能。


3

可能有所迟缓,但这可能会对某些人有所帮助。

您无法在广播接收器内使用提示对话框,我们只能在活动或服务中使用。请尝试以下方法:

在广播接收器的onReceive方法中添加以下内容:

Intent i = new Intent(context, yourclass.class);
                i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(i);

在你的类中设置对话框信息,这样当触发接收器事件时它就会出现。我尝试过这个方法,并且成功了。希望这能对某些人有所帮助 :-)


0

你可以创建一个新的透明活动,然后在该活动中创建警报对话框,每当需要显示警报时,从广播接收器调用该活动,这可能有效,但未经测试。


-1

在 AlertDilaog 中将单词 "this" 替换为 "context" -- 即您 onRecieve 方法的第一个参数。

 public void onReceive(Context context, Intent intent)

我尝试使用上下文,但我从未看到对话框。 - Java Review
它从不会显示出来,因为你必须使用 show() 将其显示。AlertDialog alert = builder.create(); alert.show(); - ccheneson
2
我是如何得到这个错误的:01-30 16:03:21.748: WARN/WindowManager(34): 尝试添加具有非应用程序令牌WindowToken{43c345e8 token=null}的窗口。中止。 - Java Review
@Java 代码审查:你是否按照Umesh的建议更改了你的代码为 AlertDialog.Builder builder = new AlertDialog.Builder(context); - ccheneson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接