Android-машина не в сети

У меня проблема с запуском сетевой службы, когда мое приложение подключается к сети Wi-Fi. Я получаю следующее исключение,

java.net.SocketException: socket failed: ENONET (Machine is not on the network) в методе openPort() ниже

BroadcastReceiver

@Override
public void onReceive(Context context, Intent intent) {

    String action = intent.getAction();

    if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {

        NetworkInfo networkInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);

        if (networkInfo.getState() == NetworkInfo.State.CONNECTED) {
            welcomeService = new BroadcastService(context, "Welcome");
            Log.i(TAG, "onReceive: SUPPLICANT-STATE ---> Connected");
            //do something
            if (!serviceRegistered) {
                welcomeService.registerService();
                serviceRegistered = true;
            }
        }

        if (networkInfo.getState() == NetworkInfo.State.DISCONNECTED) {
            Log.i(TAG, "onReceive: SUPPLICANT-STATE ---> Disconnected");
            //do something
            unRegisterService();
        }
    }

}

public void unRegisterService() {
    if (serviceRegistered && welcomeService != null) {
        welcomeService.unregisterService();
        serviceRegistered = false;

    }
}

Служба вещания

public void registerService() {
    NsdServiceInfo serviceInfo  = new NsdServiceInfo();
    serviceInfo.setServiceName(mServiceName);
    serviceInfo.setServiceType("_http._tcp.");
    serviceInfo.setPort(openPort());

    mNsdManager = (NsdManager) mContext.getSystemService(Context.NSD_SERVICE);

    mNsdManager.registerService(serviceInfo, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener);
}

private int openPort() {
    try{
        // Line that throws the exception
        return  new ServerSocket(0).getLocalPort();
    }catch (IOException ioe){
        Crashlytics.logException(ioe);
        ioe.printStackTrace();
        return 0;
    }
}

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


person Lonergan6275    schedule 07.11.2016    source источник
comment
столкнулся с той же проблемой   -  person Ninad Kambli    schedule 21.03.2017
comment
@NinadKambli есть ли в сети подключение к Интернету. поскольку моя проблема была вызвана подключением к сети без Интернета, а Android вместо этого выбрал соединение 3/4G, когда устройство, с которым я пытаюсь связаться, недоступно.   -  person Lonergan6275    schedule 22.03.2017
comment
проблема решена. Я ограничивал свое устройство отправкой данных через Wi-Fi только, даже если сеть на Wi-Fi не работает, и я забыл отключить ее, когда пользователь подключен к мобильным данным.   -  person Ninad Kambli    schedule 23.03.2017
comment
В моем случае это был вызов ConnectivityManager.bindProcessToNetwork(), который вызвал проблему. Повторный вызов этого метода с аргументом null решил проблему.   -  person Slav    schedule 23.05.2017
comment
@ Lonergan6275 Я столкнулся с той же проблемой. Но это не может повториться, я до сих пор не знаю, почему это произошло и как это решить. Не могли бы вы рассказать мне ваш анализ?   -  person Shuyun6    schedule 13.12.2020


Ответы (1)


Используйте службу, которая запускает службу и останавливает службу при изменении сети или при остановке сети. Также сначала проверьте тот же порт, который использует выпуск, а затем используйте этот порт. Выполните любую задачу, которую хотите, в onStartCommand().

@Override
public void onReceive(Context context, Intent intent) {
  Date now = new Date();
  Long time = now.getTime();
  String action = intent.getAction();



  NetworkInfo networkInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);

  if (networkInfo.getState() == NetworkInfo.State.CONNECTED) {


    boolean check = isMyServiceRunning(context,
    service.getName());
    if (check) {
      Intent i = new Intent(sqlitewraper.context,service.class);
      stopService(i);
    }
    else{
      Intent i = new Intent(sqlitewraper.context,service.class);
      startservice(i);

    }

  }

  if (networkInfo.getState() == NetworkInfo.State.DISCONNECTED) {

    boolean check = isMyServiceRunning(context,
    service.getName());
    if (check) {
      Intent i = new Intent(sqlitewraper.context,service.class);
      stopService(i);
    }
  }


  private boolean isMyServiceRunning(Context context, String Myservice) {
    ActivityManager manager = (ActivityManager) context
    .getSystemService(Context.ACTIVITY_SERVICE);
    for (RunningServiceInfo service : manager
    .getRunningServices(Integer.MAX_VALUE)) {
      if (Myservice.equals(service.service.getClassName())) {

        return true;
      }
    }
    return false;
  }
}
person MIkka Marmik    schedule 07.11.2016
comment
Спасибо за ваш ответ, но не могли бы вы объяснить это более подробно или привести пример - person Lonergan6275; 07.11.2016
comment
Я не понимаю, как это решает проблему с new ServerSocket(0).getLocalPort(); - person Lonergan6275; 07.11.2016
comment
это из-за ресурсов освобождения, которые уже выделены при запуске службы, если вы останавливаете службу во время изменения сети, то ее ресурсы освобождения, которые уже выделены. - person MIkka Marmik; 07.11.2016
comment
Я не думаю, что manager.getRunningServices(Integer.MAX_VALUE) возвращает службы NSDManager (Network Discovery). - person Lonergan6275; 07.11.2016
comment
попробуйте это, и если проблема не исчезнет, ​​подтвердите меня, потому что я проверил это. - person MIkka Marmik; 07.11.2016
comment
это не решает проблему. проблема в том, что приложение не может связаться с хостом `ошибка сокета: ENONET (машина не в сети)`. если я убью приложение и запущу его снова, оно сработает. - person Lonergan6275; 07.11.2016