0

The code looks like this:

1) Declare the new activity in manifest file. (AndroidManifest.xml):

    <activity
        android:name=".ConfirmDialog"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.Dialog"
        android:launchMode="singleTask"
        android:screenOrientation="vertical">          
    </activity>

2) Create new class extends activity. (public class ConfirmDialog extends Activity)

private static final int DIALOG_YES_NO_MESSAGE = 1;

@Override
protected Dialog onCreateDialog(int id) {
    switch (id) {
    case DIALOG_YES_NO_MESSAGE:
        return new AlertDialog.Builder(ConfirmDialog.this)
            .setIconAttribute(android.R.attr.alertDialogIcon)
            .setTitle(R.string.app_name)
            .setMessage(R.string.ask_confirm)
            .setPositiveButton(R.string.ask_confirm_yes, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                    dialog.cancel();
                    finish();
                }
            })
            .setNegativeButton(R.string.ask_confirm_no, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                    dialog.cancel();
                    finish();
                }
            })
            .create();
    }
    return null;
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    showDialog(DIALOG_YES_NO_MESSAGE);
}

3) Use the new created activity in phonestatelistener. (public class Listener extends PhoneStateListener)

public void onCallStateChanged(int state, String incomingNumber){

    switch(state){              
        case TelephonyManager.CALL_STATE_OFFHOOK:
            confirmCall();          
        break;
    }

    super.onCallStateChanged(state, incomingNumber);

}   

private void confirmCall(){
    Intent intent = new Intent();
    intent.setComponent(new ComponentName("com.example", "com.example.ConfirmDialog"));
    mContext.startActivity(intent);
}
Ludiaz
  • 99
  • 7
  • And what is the error log output? – Cat Oct 20 '12 at 00:10
  • android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application – Ludiaz Oct 20 '12 at 00:30
  • `mContext` is probably null. It's impossible to tell without the full log and code. – Cat Oct 20 '12 at 00:59
  • mContext is not null, because the code Toast.makeText(mContext, "error!", Toast.LENGTH_LONG).show(); in exception of try works fine! – Ludiaz Oct 20 '12 at 01:02
  • 1
    The `Context` that you're using may not be valid for doing window operations, such as making dialogs. See the answers to [this question](http://stackoverflow.com/questions/5796611/dialog-throwing-unable-to-add-window-token-null-is-not-for-an-application-wi) for some suggestions. As Eric said, we need to see the code. – acj Oct 20 '12 at 01:13
  • try using `mContext.getApplicationContext()` instead of just mContext – toadzky Oct 20 '12 at 05:01
  • @Ludiaz We need to see where `mContext` is being initialized. – acj Oct 20 '12 at 13:05
  • @acj the mContext is initilized, because Toast works. Anyway, mContext is a wore the getApplicationContext(), stored in a Config class. This Config class received context of a SherlockFragmentActivity. I have altered the activity of this config.setContext (getApplicationContext) for config.setContext (this). Now is working. The problem is that there is still exactly what I wanted, because I have to open my app to user wiew the alert. I wanted this alert "exploded" on the screen without opening the app. – Ludiaz Oct 20 '12 at 15:40
  • @acj the app crashes and freezes the android. after a while it reboots. sometimes I have to remove the battery. I noticed that if I take the lines that call the activity of the dialog (in confirmCall ()), the app works normally. – Ludiaz Oct 20 '12 at 22:29
  • @Ludiaz You're starting an activity in your own app, so you can use the simpler form `new Intent(this, ConfirmDialog.class)`. Also, be sure that `ConfirmDialog` is declared in the manifest. – acj Oct 21 '12 at 00:37
  • i'm trying this, but eclipse show error "the constructor intent is undefined and show has solution "remove arguments". – Ludiaz Oct 22 '12 at 20:02

1 Answers1

0

Not all Context objects are equal, and reusing them is dangerous because it can result in the error that you're seeing. Per your comment, your revised code is storing a Context from SherlockFragmentActivity in your Config class, and then using it later when that Activity (and the window that it was using) may not exist anymore. The Context isn't null and can probably be used to do a Toast, but doing windowing operations is very risky.

One solution is to create a dialog-themed activity in your app that will only show the dialog. In confirmCall(), launch your activity with startActivity(), and then let the activity create the dialog. To the user, a dialog will appear on the screen without an app running, but in fact your app is running and can respond to the user's Yes/No choice on the dialog. Be sure to use

new AlertDialog.Builder(this)

so that the dialog's Context is an Activity.

acj
  • 4,821
  • 4
  • 34
  • 49