Периодически проверяйте соединение Ethernet Android

Пытаюсь периодически проверять сетевое соединение. Однако это для китайского Android Mini PC, а не для планшета или смартфона. Я использую адаптер Ethernet-USB вместо Wi-Fi. Сначала я использовал класс широковещательного приемника:

public class NetworkStateReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getExtras() != null) {
            @SuppressWarnings("deprecation")
            NetworkInfo eni = (NetworkInfo) intent.getExtras().get(
                    ConnectivityManager.EXTRA_NETWORK_INFO);

            if (eni != null && eni.getState() == NetworkInfo.State.CONNECTED) {
                Log.d(TAG, "Network " + eni.getTypeName() + " connected.");
            }
        }
        if (intent.getExtras().getBoolean(
                ConnectivityManager.EXTRA_NO_CONNECTIVITY, Boolean.FALSE)) {
            Log.d(TAG, "There's no network connectivity.");
        }
    }
}

Это отлично работает для Wi-Fi и мобильных устройств. Однако для Ethernet есть сложности. Когда я подключаю адаптер ethernet к usb, он думает, что он уже имеет соединение ETHERNET, независимо от того, подключен кабель ethernet или нет. Только при удалении адаптера он знает, что соединение Ethernet было удалено.

Я попытался использовать сокет, и это работает:

    private static boolean checkSocket(String host, int port) {
        Socket socket = null;
        boolean reachable = false;
        try {
            socket = new Socket(InetAddress.getByName(host), port);
            reachable = true;
        } catch (UnknownHostException e) {
        } catch (IOException e) {
        } finally {
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                }
            }
        }
        return reachable;
    }

При наличии связи работает отлично и быстро. Когда соединение потеряно, программе требуется слишком много времени, чтобы узнать об этом. Мне нужно это решение, но оно должно намного быстрее узнать, что соединение Ethernet было потеряно. Кроме того, это зависит от исключений, которые мне совсем не нравятся.

Наконец, я попробовал простое сообщение ICMP:

    try {
        InetAddress address = InetAddress.getByName(host);
        if (address.isReachable(timeout)) {
            return true;
        }
    } catch (UnknownHostException e) {
    } catch (IOException e) {
    }
    return false;

Это должно работать, верно? К сожалению, это не так. До сих пор я всегда получал false при выполнении этого кода.

Что я делаю неправильно и как правильно это сделать?

ИЗМЕНИТЬ 1

Сейчас я попробовал это решение, которое работает и не работает. Это смешно и раздражает, так как я проверяю это в onResume(). После нескольких правильных попыток он внезапно останавливается. Я понятия не имею, почему.

    boolean reachable = false;
    try {
        Process p1 = java.lang.Runtime.getRuntime().exec("ping -c 1 " + host);
        int retValue = p1.waitFor();
        reachable = (retValue == 0);
        Log.d(TAG, String.valueOf(reachable));
        p1.destroy();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return reachable;

person Armadillo    schedule 22.08.2013    source источник


Ответы (1)