Android:在应用程序中连接时,无法在网络上安装ping设备

时间:2016-10-12 11:53:19

标签: android socket.io network-programming wifi wifimanager

我使用Socket.io和android网络发现构建了一个应用程序。当服务器启动并且android设备解析服务时我尝试创建套接字,但它在第一次尝试时从不起作用。我必须杀死应用程序并重新启动它然后它工作正常。 服务器正在接入点上运行。与网络的连接很好,但我不能ping服务器。但正如前面提到的,如果我杀死应用程序并再次运行它可以正常工作。

Eidt 2

经过进一步调试后,我将崩溃范围缩小到我的应用程序设置wifi连接的任何时间。 ssid和密码是从qrcode获得的,应用程序设置了wifi连接。

读取qr代码数据

        @Override
        public void receiveDetections(Detector.Detections<Barcode> detections) {
            final SparseArray<Barcode> barCodes = detections.getDetectedItems();

            if (!receivedDetection) {
                if (barCodes.size() != 0) {

                    Log.i(TAG, "received a Barcode");
                    receivedDetection = true;

                    Gson g = new Gson();
                    try {
                        barCodeData = g.fromJson(barCodes.valueAt(0).rawValue, AccessPointCredentials.class);
                    } catch (Exception e) {
                        barCodeData = new AccessPointCredentials();
                        barCodeData.setSsid(barCodes.valueAt(0).rawValue);
                        barCodeData.setPass(null);
                        e.printStackTrace();
                    }

                    connectToWifi(barCodeData);

                }
            }
        }

connectToWifi()

private void connectToWifi(final AccessPointCredentials credentials) {

    new AsyncTask<Object, Object, Object>() {
        @Override
        protected Object doInBackground(Object... objects) {
            WifiManager wifiManager = (WifiManager) mActivity.getSystemService(Context.WIFI_SERVICE);

            wifiManager.setWifiEnabled(true);
            int netId;

            try {
                Thread.sleep(100);
            } catch (InterruptedException ie) {
                ie.printStackTrace();
            }

            for (WifiConfiguration tmp : wifiManager.getConfiguredNetworks()) {
                if (tmp.SSID.equals("\"" + credentials.getSsid() + "\"")) {

                    netId = tmp.networkId;
                    boolean enabled = wifiManager.enableNetwork(netId, true);

                    Log.i(TAG, "doInBackground: Enabled? " + enabled);

                    mActivity.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            mActivity.onBackPressed();
                        }
                    });
                    return null;
                }
            }


            final String[] apSettings = {credentials.getSsid(), credentials.getPass()};
            final WifiConnect WifiTask = new WifiConnect(mActivity);
            mActivity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    WifiTask.execute(apSettings);
                }
            });
            this.cancel(true);
            return null;
        }

        @TargetApi(23)
        @Override
        protected void onPostExecute(Object aVoid) {
            super.onPostExecute(aVoid);

            if (Build.VERSION.RELEASE.equalsIgnoreCase("6.0")) {
                if (!Settings.System.canWrite(mActivity)) {
                    Intent goToSettings = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
                    goToSettings.setData(Uri.parse("package:" + mActivity.getPackageName()));
                    mActivity.startActivity(goToSettings);
                } else {
                    bindToNetwork();
                }


            } else {
                bindToNetwork();
            }
        }
    }.execute();
}

bindToNetwork()

private void bindToNetwork() {
    final ConnectivityManager connectivityManager = (ConnectivityManager) mActivity.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkRequest.Builder builder;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        builder = new NetworkRequest.Builder();
        //set the transport type do WIFI
        builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
        connectivityManager.requestNetwork(builder.build(), new ConnectivityManager.NetworkCallback() {
            @Override
            public void onAvailable(Network network) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    connectivityManager.bindProcessToNetwork(network);

                } else {
                    //This method was deprecated in API level 23
                    ConnectivityManager.setProcessDefaultNetwork(network);
                }
                try {
                    //do a callback or something else to alert your code that it's ok to send the message through socket now
                } catch (Exception e) {
                    e.printStackTrace();
                }
                connectivityManager.unregisterNetworkCallback(this);
            }
        });
    }
}

修改

布尔方法isServerReachable()拖出异常

java.net.SocketException: socket failed: ENONET (Machine is not on the network)

public boolean isServerReachable(){

        boolean isReachable;
        try {
            isReachable = InetAddress.getByName(mService.getHost().getHostAddress()).isReachable(5000);

        } catch (Exception e) {
            e.printStackTrace();
            isReachable = false;
        }
        Log.i(TAG, "onServiceResolved: Server reachable? " + String.valueOf(isReachable));

        Log.i(TAG, "onServiceResolved: Is Network online? " + String.valueOf(isNetworkOnline()));

    if (isReachable){
        return true;
    } else {
        return false;
    }
}

2 个答案:

答案 0 :(得分:1)

从症状看起来你期望wifiManager.enableNetwork()调用被阻止,但事实上并非如此。因此,在实际连接网络之前,请调用isServerReachable()。

您可以在this topic(第一个答案)中找到有关如何操作的详细说明。

答案 1 :(得分:0)

我解决了这个问题,但我不相信这是最好的解决方案,并且如果添加的话会接受更好的解决方案。

我通过在connectToWifi()之后添加Thread.sleep(500);来调整wifiManager.enableNetwork()方法中的for循环,现在它正在运行。

for (WifiConfiguration tmp : wifiManager.getConfiguredNetworks()) {
    if (tmp.SSID.equals("\"" + credentials.getSsid() + "\"")) {
        netId = tmp.networkId;
        boolean enabled = wifiManager.enableNetwork(netId, true);

        try {
            Thread.sleep(500);
        } catch (InterruptedException ie) {
            ie.printStackTrace();
        }

        mActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mActivity.onBackPressed();
            }
        });
        return null;
    }
}