13

I am having a problem Running a network service when my app connects to a WiFi network. I am getting a the following exception,

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

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;

    }
}

BroadcastService

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;
    }
}

This the Broadcast Receiver only runs on when the main activity is showing. and it works fine on the first run but when I change the WiFi network this happens. Help world be greatly appreciated.

Lonergan6275
  • 1,739
  • 5
  • 28
  • 61
  • facing same problem – Ninad Kambli Mar 21 '17 at 18:29
  • @NinadKambli does the network have an internet connection. as my issue was caused by connecting to a network with no internet and android choses to use 3/4G connection instead where the device i am trying to communicate with is not reachable – Lonergan6275 Mar 22 '17 at 09:57
  • issue solved. I was restricting my device to send data through wifi only even if net on wifi is down and i have forgot to disable it when user is connected to mobile data. – Ninad Kambli Mar 23 '17 at 14:09
  • 4
    In my case it was a call to `ConnectivityManager.bindProcessToNetwork()` that caused the problem. Calling this method again with `null` argument solved the issue. – Slav May 23 '17 at 15:00
  • @Lonergan6275 I met a same problem. But it cannot happend again, I still don't know why it happend and how to solve it. Could you tell me your analysis? – Shuyun6 Dec 13 '20 at 08:10

1 Answers1

0

Use Service which start service and stop service when network would be change or when stop network.Also check same port which is using release first and after that use that port.Do whatever task you want in 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;
  }
}
MIkka Marmik
  • 1,051
  • 10
  • 28
  • Thank you for your answer but could you please explain it in more detail or give an example – Lonergan6275 Nov 07 '16 at 12:33
  • I dont see how this addresses the problem with `new ServerSocket(0).getLocalPort();` – Lonergan6275 Nov 07 '16 at 12:51
  • its because of release resources which is already allocated when service is started if you are stop service while network changed then its release resources which is already allocated. – MIkka Marmik Nov 07 '16 at 12:54
  • I don't think `manager.getRunningServices(Integer.MAX_VALUE)` returns NSDManager (Network Discovery) Services. – Lonergan6275 Nov 07 '16 at 13:10
  • try this and if problem continues then acknowledge me because i tested it. – MIkka Marmik Nov 07 '16 at 13:11
  • 2
    this does not solve the issue. the issue is the app cannot communicate with the host ` socket failed: ENONET (Machine is not on the network)`. if i kill the app and run it again it works. – Lonergan6275 Nov 07 '16 at 17:24