简体   繁体   English

断开互联网连接后如何显示弹出窗口?

[英]how to display a pop_up window when losing the Internet connection?

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: 我希望我的android应用在互联网连接断开时显示一个弹出窗口,以告知用户他断开了连接,我试图捕获空流,然后启动一个弹出窗口,但是它给了我例外:

03-20 10:16:35.015: W/System.err(2922): android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; 03-20 20:16:35.015:W / System.err(2922):android.view.WindowManager $ BadTokenException:无法添加窗口-令牌null无效; 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.solacea 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) :位于android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:248)03-20 10:16:35.016:W / System.err(2922):位于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):在android.widget.PopupWindow.showAtLocation(PopupWindow.java:847)03-20 10:16:35.016:W / System.err(2922):在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) ):位于android.app.Activity.runOnUiThread(Activity.java:4662)03-20 10:16:35.016:W / System.err(2922):位于com.example.solaceap.Login.init_conn_lost_popup(Login.java: 119)03-20 10:16:35.016:W / System.err(2922):at com.example.solacea p.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) p.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):在android.os.Handler.dispatchMessage(Handler.java:92)03-20 10:16:35.017:W / System.err(2922):在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):在java.lang.reflect.Method.invokeNative(本机方法)03-20 10:16:35.017:W / System.err(2922):在java.lang .reflect.Method.invoke(Method.java:511)03-20 10:16:35.017:W / System.err(2922):在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):在dalvik.system.NativeStart.main(本机方法)

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 : 值得一提的是,流从一个普通的Java类得到了工具Runnable不活动类,正如我刚才跑了一直给我输入的数据从流,看一个线程:

    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 : 这是pop_up方法:

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 : 更换inflater

    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 : 将上下文( Login.this )更改为:

1- getApplicationContext() . 1- getApplicationContext()

2- getBaseContext() . 2- getBaseContext()

3- creating an Application class to retrieve the context from then called the desired method ( MyApplication.getAppContext() ).as explained here . 3-创建一个Application类来检索从当时称为期望的方法的上下文( MyApplication.getAppContext()如说明这里

Instead of creating popup functionality into activity itself,try to create the seperate activity for it and when internet connection gone,call this activity and while declaring that activity into android manifest file use the following tag 与其在活动本身中创建弹出功能,不如尝试为其创建单独的活动,并在断开互联网连接时调用此活动,并在将其声明为android清单文件的同时使用以下标记

android:theme="@style/Theme.Transparent" 

so that you will not get the error even if you are not into application 这样即使您不进入应用程序也不会收到错误

why don't you just register broadcast receiver, that will notify you when connection is lost? 您为什么不注册广播接收器,当连接断开时会通知您? It would be more easier, than that you do now. 它比您现在做的要容易得多。

private final BroadcastReceiver connectionStateReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (!isNetworkAvailable(context)) {
            init_conn_lost_popup();
        }
    }
}

privaate boolean isNetworkAvailable(final Context context) {
    ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
    return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}

and now just register this receiver in onResume() method, also unregister it in onPause() 现在只需在onResume()方法中注册此接收器,也可以在onPause()注销它

//Declare your AlertDialog here
    private AlertDialog alertDialog;
    .....
    .....
//Your Broadcasr receiver in Mainactivity for connection change info     
    private BroadcastReceiver networkReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
                    NetworkInfo networkInfo = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
                    if (networkInfo != null && networkInfo.getDetailedState() == NetworkInfo.DetailedState.CONNECTED) {
                        try {
                            if (alertDialog != null && alertDialog.isShowing())
                                alertDialog.dismiss();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    } else if (networkInfo != null && networkInfo.getDetailedState() == NetworkInfo.DetailedState.DISCONNECTED) {
                        if (alertDialog == null || !alertDialog.isShowing()) {
                            AlertDialog.Builder builder = new AlertDialog.Builder(context);
//Define your custom layout here
                            LayoutInflater inflater = getLayoutInflater();
                            View dialoglayout = inflater.inflate(R.layout.dialog_networl_lost, null);
                            builder.setView(dialoglayout);
                            builder.setCancelable(false);
                            alertDialog = builder.create();
                            alertDialog.show();
                        }
                    }
                }
            }
        };

        @Override
        protected void onResume() {
            super.onResume();
            IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
            registerReceiver(networkReceiver, intentFilter);
        }

        @Override
        protected void onPause() {
            super.onPause();
            if (networkReceiver != null)
                unregisterReceiver(networkReceiver);
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM