开发者

Showing an OK dialog box from a service/receiver in Android

开发者 https://www.devze.com 2023-02-13 19:23 出处:网络
My application has a receiver which is invoked when an SMS is received. I want to notify the user with a simple 1 button dialog box..

My application has a receiver which is invoked when an SMS is received. I want to notify the user with a simple 1 button dialog box..

This is my code :

AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setMessage("Hello dude").setCancelable(false).setPositiveButton("Got you", new DialogInterface.OnClickListener() {


            @Override
            public void onClick(DialogInterface dialog, int which) {
开发者_运维知识库                // TODO Auto-generated method stub
                //mp.stop();

            }
        }).show();

But, it is throwing an exception :

android.view.WindowManager$BadTokenException

Please help...


First, you cannot display a dialog from a Service or BroadcastReceiver.

Second, please DO NOT INTERRUPT THE USER. The proper way to let the user know about something like this that occurred in the background is to display a Notification.


Here is what I have done: from my service instance I start the activity like this:

final Intent dialog = new Intent(this, BackGroundDialogs.class);
dialog.setType("text/plain");
dialog.putExtra(android.content.Intent.EXTRA_TEXT, reason);
dialog.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        startActivity(dialog);

as for the BackGround Dialogs class, it looks like this:

/**
 * @ To create the illusion of a alert window displayed on its own when app is
 * in the background. Really, this is a Activity but its only displaying an
 * alert window and the Activity borders have been removed.
 */
public class BackGroundDialogs extends Activity {

    public BroadcastReceiver receiver;
    public AlertDialog mAlert;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE); // custom theme with
                                                            // no borders
        IntentFilter filter = new IntentFilter();
        filter.addAction(Consts.DISMISS_DIALOG);// we can dismiss it via an
                                                // intent if we choose
        receiver = new BroadcastReceiver() {

            @Override
            public void onReceive(Context context, final Intent intent) {
                // do something based on the intent's action
                if (context == null) return;
                if (intent.getAction().equals(Consts.DISMISS_DIALOG)) {
                    finish();
                }
            }
        };
        registerReceiver(receiver, filter);
    }

    /**
     * @brief Shows an alert message using a Dialog window.
     * @param reason
     *            :the message you wish to display in the alert
     */
    public void showAlert(final String reason) {
        mAlert = new AlertDialog.Builder(this).create();
        mAlert.setCancelable(false);
        TextView Msg_tv = new TextView(this);
        Msg_tv.setTypeface(null, Typeface.BOLD);
        Msg_tv.setTextSize(16.0f);
        Msg_tv.setText(reason);
        Msg_tv.setGravity(Gravity.CENTER_HORIZONTAL);
        mAlert.setView(Msg_tv);
        mAlert.setButton("OK", new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                finish();
            }
        });
        mAlert.show();
    }

    @Override
    protected void onResume() {
        super.onResume();
        Bundle extras = getIntent().getExtras();
        String reason = extras.getString(Intent.EXTRA_TEXT);
        if (reason.equalsIgnoreCase("DISMISS")) finish();
        else showAlert(reason);// invoke the new dialog to show
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mAlert != null) if (mAlert.isShowing()) mAlert.dismiss();
        finish();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);
    }
}

you don't have to use the BroadcastReceiver calls, I just thought it might be handy to control the alert from somewhere else if required.


Rahim... you can start the activity from the service the way you are starting activity from activiy

Intent newActivity = new Intent(context,servicename.class);
context.startService(newActivity);

Context should be application context


You can do this by using TYPE_SYSTEM_ALERT:

AlertDialog alertDialog = new AlertDialog.Builder(this)
                    .setTitle("Title")
                    .setMessage("Hello dude")
                    .setCancelable(false)
                    .setPositiveButton("Got you", new DialogInterface.OnClickListener() {
                        @Override public void onClick(DialogInterface dialog, int which) {
                            // TODO Auto-generated method stub
                            //mp.stop();
                        }
                    }).create();

alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
alertDialog.show();

Please note that you have to use the following permission:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
0

精彩评论

暂无评论...
验证码 换一张
取 消