I want my android app to display a pop-up window when the internet connection lost in order to tells the user that he lost the connection, I tried to catch null stream and then initiate a pop-up then, but it gives me that exception:
03-20 10:16:35.015: W/System.err(2922): android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running? 03-20 10:16:35.016: W/System.err(2922): at android.view.ViewRootImpl.setView(ViewRootImpl.java:646) 03-20 10:16:35.016: W/System.err(2922): at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:248) 03-20 10:16:35.016: W/System.err(2922): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69) 03-20 10:16:35.016: W/System.err(2922): at android.widget.PopupWindow.invokePopup(PopupWindow.java:993) 03-20 10:16:35.016: W/System.err(2922): at android.widget.PopupWindow.showAtLocation(PopupWindow.java:847) 03-20 10:16:35.016: W/System.err(2922): at android.widget.PopupWindow.showAtLocation(PopupWindow.java:811) 03-20 10:16:35.016: W/System.err(2922): at com.example.solaceap.Login$5.run(Login.java:135) 03-20 10:16:35.016: W/System.err(2922): at android.app.Activity.runOnUiThread(Activity.java:4662) 03-20 10:16:35.016: W/System.err(2922): at com.example.solaceap.Login.init_conn_lost_popup(Login.java:119) 03-20 10:16:35.016: W/System.err(2922): at com.example.solaceap.Login$6$1.run(Login.java:281) 03-20 10:16:35.016: W/System.err(2922): at android.os.Handler.handleCallback(Handler.java:725) 03-20 10:16:35.017: W/System.err(2922): at android.os.Handler.dispatchMessage(Handler.java:92) 03-20 10:16:35.017: W/System.err(2922): at android.os.Looper.loop(Looper.java:153) 03-20 10:16:35.017: W/System.err(2922): at android.app.ActivityThread.main(ActivityThread.java:5299) 03-20 10:16:35.017: W/System.err(2922): at java.lang.reflect.Method.invokeNative(Native Method) 03-20 10:16:35.017: W/System.err(2922): at java.lang.reflect.Method.invoke(Method.java:511) 03-20 10:16:35.017: W/System.err(2922): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833) 03-20 10:16:35.017: W/System.err(2922): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600) 03-20 10:16:35.017: W/System.err(2922): at dalvik.system.NativeStart.main(Native Method)
I don't know is the app crashed before running or that because as I'm not in the inflated activity at that time, And this is my code:
Worth to mention that the stream is got from a normal java class that implements Runnable
not an activity class, as I just ran a thread that keeps giving me Input data from the stream , look at that :
public String getServerResponse() throws JSONException {
String responseLine, server_response = null_string;
InputStream stream = null;
try{
stream = socket.getInputStream();
}catch(Exception e){
e.printStackTrace();
Login login = new Login();
login.init_conn_lost_popup();
}
if(stream != null){
input = new BufferedReader(new InputStreamReader(
stream));
try {
while ((responseLine = input.readLine()) != null){
server_response = server_response + responseLine;
}
} catch (IOException e) {
Login.errorMessage.setText(conn_err);
}
}
return null;
}
And then in the activity that ran the past thread at the first:
Thread run_time = new Thread() {
@Override
public void run() {
ConnectToServer connect = new ConnectToServer(); // this is the Runnable class
while (true) {
String server_response = null;
try {
server_response = connect.getServerRespons(Login.this);
} catch (Exception e1) {
}
try {
if (!server_response.equals(null)) {
}
} catch (Exception e) {
if (!this.isInterrupted()) {
flag = true;
runOnUiThread(new Runnable() {
public void run() {
flag = false;
init_conn_lost_popup();
}
});
}
}
}
}
};
run_time.start();
And this is the pop_up method :
public void init_conn_lost_popup() {
runOnUiThread(new Runnable() {
@Override
public void run() {
try {
LayoutInflater inflater = (LayoutInflater) Login.this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.connection_popup,
(ViewGroup) findViewById(R.id.conn_pop));
// create a 300px width and 470px height PopupWindow
final PopupWindow pw = new PopupWindow(layout,
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT, true);
// display the popup in the center
pw.showAtLocation(layout, Gravity.CENTER, 0, 0); // this is where i'm getting the Exception
}
});
}
And I just made a lot of tries like :
Replacing the
inflater
with :getWindow().addContentView(layout,new ViewGroup.LayoutParams (ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT)); // after declaring the Layout View of course
Changing the context (
Login.this
) to :
1- getApplicationContext()
.
2- getBaseContext()
.
3- creating an Application
class to retrieve the context from then called the desired method (MyApplication.getAppContext()
).as explained here.