Unable to add window error in Android [duplicate] - java

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Android 1.6: "android.view.WindowManager$BadTokenException: Unable to add window — token null is not for an application"
I've tried different things, but I still keep the same error:
android.view.WindowManager$BadTokenException: Unable to add window
At this line:
alertDialog.show();
Can you look at the code?
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.splashscreen);
Context mContext = this;
alertDialog = new AlertDialog.Builder(mContext).create();
LoadData();
}
public void LoadData()
{
Thread t1 = new Thread(this);
t1.start();
}
private Handler handler = new Handler()
{
#Override
public void handleMessage(Message msg)
{
if(!rssItems.isEmpty())
{
switch (msg.what) {
case STOPSPLASH:
//remove SplashScreen from view
//splash.setVisibility(View.GONE);
Intent intent = new Intent(
"news.displayNews");
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
NewsDisplayer.rssItems.clear();
NewsDisplayer.rssItems.addAll(rssItems);
startActivity(intent);
Close();
break;
}
}
else
{
alertDialog.setCancelable(false); // This blocks the 'BACK' button
alertDialog.setMessage("No connection.");
alertDialog.setTitle("Error...");
alertDialog.setButton("Again", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
LoadData();
}
});
alertDialog.setButton2("Close", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
System.exit(0);
}
});
alertDialog.show();
}
}
};

This is because the context you are using to create the alertDialog doesn't support it. So instead of mContext, try getParent() or getApplicationContext(). That might work.

I think that's because you're running this in a thread. alertDialog.show(); has to be executed on the UI thread. Try using an AsyncTask instead.
EDIT: my bad, I didn't read carefully the code.

Related

How can I stop same alert dialog showing every time from handler?

I have an AlertDialog on a method and the method is used inside a Handler. When the Handler running every time the AlertDialog also loading again and again, I want to show the dialog one time if the dialog is still showing I don't want to load it again. For this I have the below code but not working.
Handler handler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
handler.postDelayed(this, 1000);
checkCountry();
}
};
handler.postDelayed(runnable, 1000);
public void checkCountry() {
alertDialogueBuilder = new AlertDialog.Builder(MainActivity.this);
alertDialogueBuilder.setTitle("VPN Detected!");
alertDialogueBuilder.setMessage("Please Turn Of VPN To Continue!");
alertDialogueBuilder.setIcon(R.drawable.errorstop);
alertDialogueBuilder.setCancelable(false);
alertDialogueBuilder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
AlertDialog alertDialog = alertDialogueBuilder.create();
if(alertDialog.isShowing()){
//Do Something
}else{
alertDialog.show();
}
}
Create your Dialog only once and not every time:
private AlertDialog alertDialog;
// ...
initDialog();
Handler handler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
handler.postDelayed(this, 1000);
checkCountry();
}
};
handler.postDelayed(runnable, 1000);
//...
public void initDialog() {
alertDialogueBuilder = new AlertDialog.Builder(MainActivity.this);
alertDialogueBuilder.setTitle("VPN Detected!");
alertDialogueBuilder.setMessage("Please Turn Of VPN To Continue!");
alertDialogueBuilder.setIcon(R.drawable.errorstop);
alertDialogueBuilder.setCancelable(false);
alertDialogueBuilder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
alertDialog = alertDialogueBuilder.create();
}
public void checkCountry() {
if(alertDialog.isShowing()){
//Do Something
}else{
alertDialog.show();
}
}
To show only 1-time dialog call only this checkCountry() method from which you want to show this dialog. And, please remove the Handler code. No need to use Handler here. Use only checkCountry() method to show the dialog.
The oldest trick in the book is to just make a boolean field "isAlertDialogShown" with false initialization, upon creation to true and in the onClick set it to false again (if you want it to be shown again when the handler fires).
private boolean isShown = false;
public void checkCountry() {
if (isShown){
//do something
return;
}
isShown = true;
alertDialogueBuilder = new AlertDialog.Builder(MainActivity.this);
alertDialogueBuilder.setTitle("VPN Detected!");
alertDialogueBuilder.setMessage("Please Turn Of VPN To Continue!");
alertDialogueBuilder.setIcon(R.drawable.errorstop);
alertDialogueBuilder.setCancelable(false);
alertDialogueBuilder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
isShown = false;
finish();
}
});
AlertDialog alertDialog = alertDialogueBuilder.create();
alertDialog.show();
}
if you want to try and use the alertDialog isShowing you need to use the one you created and not the new one, so again save it as a field,
but you will still might have an edge case if the handler timer is running too fast, and that is alertDialog.show() is not an immediate operation:
AlertDialog alertDialog;
public void checkCountry() {
if ( alertDialog != null && alertDialog.isShowing){
//do something
return;
}
alertDialogueBuilder = new AlertDialog.Builder(MainActivity.this);
alertDialogueBuilder.setTitle("VPN Detected!");
alertDialogueBuilder.setMessage("Please Turn Of VPN To Continue!");
alertDialogueBuilder.setIcon(R.drawable.errorstop);
alertDialogueBuilder.setCancelable(false);
alertDialogueBuilder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
alertDialog = alertDialogueBuilder.create();
alertDialog.show();
}

AlertDialog is shown before methods insde thread finished Android Java

The first activity in the app checks if tables and data are loaded correctly before launching the main activity.
If not, it connects to server using volley and loads the data and images and then asks user to restart app.
The problem is: AlertDialog is shown with "message loading complete" directly before the methods finished loading.
I created a thread inside the onCreate method and put all methods inside it but the same problem persists.
My question is: How can I show the alertDialog after methods complete data loading?
Here is my code:
if(! (checkTables()&&checkData())){
progressDialog.show();
new Thread(new Runnable() {
#Override
public void run() {
fillSamples();
fillExams();
fillQuestions();
fillSubQuestions();
}
}).start();
progressDialog.dismiss();
AlertDialog.Builder builder=new AlertDialog.Builder(SplashScreen.this);
builder.setMessage("Loading Data Complete Please restart your App");
builder.setCancelable(false);
builder.setPositiveButton("Restart", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
System.exit(1);
}
});
AlertDialog dialog=builder.create();
dialog.show();
}
Try to use AsyncTask instead of Thread. For more info Threads and AsyncTask
if(! (checkTables()&&checkData())){
GetData.execute();
}
class GetData extends AsyncTask<Void, Void,Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
//Add your progress dialog.
progressDialog.show();
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
AlertDialog.Builder builder=new AlertDialog.Builder(SplashScreen.this);
builder.setMessage("Loading Data Complete Please restart your App");
builder.setCancelable(false);
builder.setPositiveButton("Restart", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
System.exit(1);
}
});
AlertDialog dialog=builder.create();
dialog.show();
}
}
#Override
protected Void doInBackground(Void... voids) {
fillSamples();
fillExams();
fillQuestions();
fillSubQuestions();
return null;
}
}

Exception android.view.WindowManager$BadTokenException: Unable to add window

I get this error every once in a while and not sure how to fix it. I read that the context could be destroyed but no REAL answers on how to solve it, especially for my situation.
The error happens below on Utility.showDialog in the onPostExecute on my BaseLoadOperation. What is the correct way to handle this?
DataTask.java
public class DataTask extends BaseLoadOperation {
public DataTask(Context context) {
super(context);
}
#Override
protected void onPostExecute(Object result) {
super.onPostExecute(result);
Utility.showDialog(this.context.getString(R.string.connectionerror), "OK", this.context);
}
Utility.java
public static void showDialog(String message, String buttonText, Context context, final IDialogCallback callback) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(message)
.setCancelable(true)
.setPositiveButton(buttonText, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
if(callback != null)
{
callback.buttonPress();
}
}
});
AlertDialog alert = builder.show();
TextView messageText = (TextView)alert.findViewById(android.R.id.message);
messageText.setGravity(Gravity.CENTER);
alert.show();
}
Exception android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy#49fff91 is not valid; is your activity running?
android.view.ViewRootImpl.setView (ViewRootImpl.java:900)
android.view.WindowManagerGlobal.addView (WindowManagerGlobal.java:342)
android.view.WindowManagerImpl.addView (WindowManagerImpl.java:97)
android.app.Dialog.show (Dialog.java:419)
android.support.v7.app.AlertDialog$Builder.show (AlertDialog.java:956)
com.exposure.utilities.Utility.showDialog (Utility.java:196)
com.exposure.utilities.Utility.showDialog (Utility.java:181)
com.exposure.utilities.DataTask.onPostExecute (DataTask.java:44)

Attempt to invoke virtual method 'android.support.v7.app.AlertDialog android.support.v7.app.AlertDialog$Builder.create()' on a null object reference

i got an error Attempt to invoke virtual method 'android.support.v7.app.AlertDialog android.support.v7.app.AlertDialog$Builder.create()' on a null object reference everytime i build my app
here's code of my error
07-26 15:04:32.587 18897-18915/com.example.study E/AndroidRuntime: FATAL EXCEPTION: Thread-385
Process: com.example.study, PID: 18897
java.lang.NullPointerException: Attempt to invoke virtual method 'android.support.v7.app.AlertDialog android.support.v7.app.AlertDialog$Builder.create()' on a null object reference
at com.example.study.Splash.checking(Splash.java:66)
at com.example.study.Splash$2.run(Splash.java:51)
it happened on my splash activity, here's my code
package com.example.study;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import com.example.study.helper.SessionManager;
import com.example.study.util.ConnectionDetector;
public class Splash extends AppCompatActivity {
private ConnectionDetector cd;
Boolean isInternetPresent = false;
protected SessionManager session;
private AlertDialog.Builder builder;
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
AlertDialog.Builder builder = new AlertDialog.Builder(Splash.this);
session = new SessionManager(getApplicationContext());
cd = new ConnectionDetector(getApplicationContext());
builder.setTitle("No Connection");
builder.setMessage("Check Your Internet Connection.");
builder.setIcon(R.drawable.fail);
builder.setPositiveButton("OK", new
DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
/* TODO Auto-generated method stub */
dialog.dismiss();
}
});
Thread timer = new Thread(){
public void run(){
try {
sleep(2000);
} catch (Exception e) {
e.printStackTrace();
} finally {
checking();
}
}
};
timer.start();
}
public void checking() {
isInternetPresent = cd.isConnectingToInternet();
if(isInternetPresent) {
session.checkLogin();
finish();
} else {
builder.create().show();
finish();
}
}
}
dunno what to do ... please help to solve this problem,
I think it fails at your checking() method. You have declared a global variable named builder, then you declared another variable inside your onCreate(). In your checking() method, it refers to the global variable which you didn't initialize, only declare.
Possible solution, edit this :
AlertDialog.Builder builder = new AlertDialog.Builder(Splash.this);
to
builder = new AlertDialog.Builder(Splash.this);
Please use this below code for reference, it's working fine for me.
Before onCreate()
AlertDialog.Builder alertDialog;
Within OnCreate()
alertDialog = new AlertDialog.Builder(YourActivity.this);
Create AlertDialog
alertDialog.setMessage("Do you want to continue ?");
alertDialog.setPositiveButton("YES", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//write your code here after click yes
}
});
alertDialog.setNegativeButton("NO", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
alertDialog.show();

Android close dialog after 5 seconds?

I'm working on an accesibility app. When the user wants to leave the app I show a dialog where he has to confirm he wants to leave, if he doesn't confirm after 5 seconds the dialog should close automatically (since the user probably opened it accidentally). This is similar to what happens on Windows when you change the screen resolution (an alert appears and if you don't confirm it, it reverts to the previous configuration).
This is how I show the dialog:
AlertDialog.Builder dialog = new AlertDialog.Builder(this).setTitle("Leaving launcher").setMessage("Are you sure you want to leave the launcher?");
dialog.setPositiveButton("Confirm", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int whichButton) {
exitLauncher();
}
});
dialog.create().show();
How can I close the dialog 5 seconds after showing it?
final AlertDialog.Builder dialog = new AlertDialog.Builder(this).setTitle("Leaving launcher").setMessage("Are you sure you want to leave the launcher?");
dialog.setPositiveButton("Confirm", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int whichButton) {
exitLauncher();
}
});
final AlertDialog alert = dialog.create();
alert.show();
// Hide after some seconds
final Handler handler = new Handler();
final Runnable runnable = new Runnable() {
#Override
public void run() {
if (alert.isShowing()) {
alert.dismiss();
}
}
};
alert.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
handler.removeCallbacks(runnable);
}
});
handler.postDelayed(runnable, 10000);
Use CountDownTimer to achieve.
final AlertDialog.Builder dialog = new AlertDialog.Builder(this)
.setTitle("Leaving launcher").setMessage(
"Are you sure you want to leave the launcher?");
dialog.setPositiveButton("Confirm",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int whichButton) {
exitLauncher();
}
});
final AlertDialog alert = dialog.create();
alert.show();
new CountDownTimer(5000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
// TODO Auto-generated method stub
}
#Override
public void onFinish() {
// TODO Auto-generated method stub
alert.dismiss();
}
}.start();
Late, but I thought this might be useful for anyone using RxJava in their application.
RxJava comes with an operator called .timer() which will create an Observable which will fire onNext() only once after a given duration of time and then call onComplete(). This is very useful and avoids having to create a Handler or Runnable.
More information on this operator can be found in the ReactiveX Documentation
// Wait afterDelay milliseconds before triggering call
Subscription subscription = Observable
.timer(5000, TimeUnit.MILLISECONDS) // 5000ms = 5s
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Long>() {
#Override
public void call(Long aLong) {
// Remove your AlertDialog here
}
});
You can cancel behavior triggered by the timer by unsubscribing from the observable on a button click. So if the user manually closes the alert, call subscription.unsubscribe() and it has the effect of canceling the timer.
This is the code, refer this link:
public class MainActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// get button
Button btnShow = (Button)findViewById(R.id.showdialog);
btnShow.setOnClickListener(new View.OnClickListener() {
//on click listener
#Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
builder.setTitle("How to close alertdialog programmatically");
builder.setMessage("5 second dialog will close automatically");
builder.setCancelable(true);
final AlertDialog closedialog= builder.create();
closedialog.show();
final Timer timer2 = new Timer();
timer2.schedule(new TimerTask() {
public void run() {
closedialog.dismiss();
timer2.cancel(); //this will cancel the timer of the system
}
}, 5000); // the timer will count 5 seconds....
}
});
}
}
HAPPY CODING!
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.game_message);
game_message = builder.create();
game_message.show();
final Timer t = new Timer();
t.schedule(new TimerTask() {
public void run() {
game_message.dismiss(); // when the task active then close the dialog
t.cancel(); // also just top the timer thread, otherwise, you may receive a crash report
}
}, 5000);
Reference : https://xjaphx.wordpress.com/2011/07/13/auto-close-dialog-after-a-specific-time/
For Kotlin inspired by Tahirhan's answer.
This is what worked for my current project. Hope it will help someone else in the near future.
Im calling this function in a fragment. Happy coding!
fun showAlert(message: String) {
val builder = AlertDialog.Builder(activity)
builder.setMessage(message)
val alert = builder.create()
alert.show()
val timer = Timer()
timer.schedule(object : TimerTask() {
override fun run() {
alert.dismiss()
timer.cancel()
}
}, 5000)
}
I added automatic dismiss with the time remaining shown in the positive button text to an AlertDialog.
AlertDialog dialog = new AlertDialog.Builder(getContext())
.setTitle(R.string.display_locked_title)
.setMessage(R.string.display_locked_message)
.setPositiveButton(R.string.button_dismiss, null)
.create();
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
#Override
public void onShow(DialogInterface dialog) {
final Button positiveButton = ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE);
final CharSequence positiveButtonText = positiveButton.getText();
new CountDownTimer(AUTO_DISMISS_MILLIS, 100) {
#Override
public void onTick(long millisUntilFinished) {
positiveButton.setText(String.format(Locale.getDefault(), "%s (%d)",
positiveButtonText,
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) + 1));
}
#Override
public void onFinish() {
dismiss();
}
}.start();
}
});
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
content: Text("Sucess"),
);
});
Timer(Duration(seconds: 2),()=>Navigator.pop(context));
Create a dialog and find a button.
AlertDialog.Builder builder = new AlertDialog.Builder(this).setPositiveButton( android.R.string.ok, null );
final AlertDialog dialog = builder.create();
dialog.show();
View view = dialog.getButton( AlertDialog.BUTTON_POSITIVE );
If you use a custom view for dialog just use it. Next step.
view.postDelayed( new Runnable(){
#Override
public void run(){
dialog.cancel(); // no problem if a user close it manually
}
}, 5000 );
AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create();
then call dismiss meth it work
alertDialog .dismiss();

Categories