以编程方式打开Wifi热点并出现WiFi错误

时间:2018-11-13 12:51:20

标签: java android android-wifi android-7.1-nougat hotspot

我正在使用StackOverflow上一篇文章中有关此问题的以下代码

public static boolean configApState(Context context) {
    WifiManager wifimanager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
    WifiConfiguration wificonfiguration = null;
    try {
        // if WiFi is on, turn it off
        if(isApOn(context)) {
            if (wifimanager != null) {
                wifimanager.setWifiEnabled(false);
            }
        }
        Method method = wifimanager != null ? wifimanager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class) : null;



        if (method != null) {
            method.invoke(wifimanager, null, !isApOn(context));
        }else{
            return false;
        }
        return true;
    }
    catch (Exception e) {
        e.printStackTrace();
    }
    return false;
}

看起来工作正常。就我用于静态IP而言,我正在运行Android 7.0的Android TV Box X96 mini上使用此代码。 但是当我尝试自动连接时,Android TV的DHCP为连接设备提供了非常奇怪的IP。

我得到的是 169.254.68.26 另一方面,如果我尝试对通过静态IP 192.168.43.50 连接的设备执行ping操作, PING:传输失败。常规失败。错误消息。

另一方面,如果我尝试从设置菜单手动启用wifi热点,则获得的IP是正常的,并且ping也可以正常工作。再次关闭热点,然后尝试通过App开启热点,然后显示与上述相同的行为。

有什么我想念的吗?

这是我正在使用上述功能的服务类

public class MyPersistingService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Toast.makeText(getApplicationContext(),""+AppManager.isApOn(getApplicationContext()),Toast.LENGTH_LONG).show();
    if(!AppManager.isApOn(getApplicationContext())) {
        WifiManager wifi = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        if (wifi != null) {
            wifi.setWifiEnabled(false);
            AppManager.configApState(getApplicationContext());
        }else{
            Toast.makeText(getApplicationContext(), "No Wifi Found", Toast.LENGTH_SHORT).show();
        }

    }

    return  START_STICKY;
}}

修改 我在两种情况下都尝试了以下功能以获得IP地址

 public  static  String getIPInfo2(Context context) throws SocketException {
    Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();

    String finalIP = "";
    while (interfaces.hasMoreElements())
    {
        NetworkInterface networkInterface = interfaces.nextElement();

        if (networkInterface.isLoopback())
            continue; // Don't want to broadcast to the loopback interface

        for (InterfaceAddress interfaceAddress : networkInterface.getInterfaceAddresses())
        {
            InetAddress broadcast = interfaceAddress.getBroadcast();

             InetAddress ip = interfaceAddress.getAddress();
            // interfaceAddress.getNetworkPrefixLength() is another way to express subnet mask

            // Android seems smart enough to set to null broadcast to
            //  the external mobile network. It makes sense since Android
            //  silently drop UDP broadcasts involving external mobile network.
            if (broadcast == null)
                continue;

            finalIP = ip.getHostAddress();


        }
    }

    return  finalIP;
}

,我观察到了奇怪的行为。 当我从设置手动进行热点共享时。该函数返回 192.168.43.1 ,但是当我通过Code开启wifi时,上述函数将返回“” 空字符串。

1 个答案:

答案 0 :(得分:0)

192.168.43.1 是设备以编程方式或手动打开热点时应返回的正确IP地址。由于Android设备的IP地址不会更改。

PS: 除非是其Android Pie或Google Pixel设备。

使用以下代码打开热点。这是使用android的私有API的反映。不建议这样做,但是如果您没有其他选择,那么也许您想这样做:

 public boolean setWifiEnabled(WifiConfiguration wifiConfig, boolean enabled) { 
    try {   
      if (enabled) { //disables wifi hotspot if it's already enabled    
        wifiManager.setWifiEnabled(false);  
      } 

       Method method = wifiManager.getClass()   
          .getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);   
      return (Boolean) method.invoke(wifiManager, wifiConfig, enabled); 
    } catch (Exception e) { 
      Log.e(this.getClass().toString(), "", e); 
      return false; 
    }   
  }

这是您可以用来获取IP地址的代码。从API 15到Pie,在所有设备上均可正常运行。在我的演示应用Spotserve上进行了测试。

  private String getIpAddress() {
    Log.v("DANG", "Inside getIpAdress()");
    String ip = "";
    try {
      Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface
          .getNetworkInterfaces();
      while (enumNetworkInterfaces.hasMoreElements()) {
        NetworkInterface networkInterface = enumNetworkInterfaces
            .nextElement();
        Enumeration<InetAddress> enumInetAddress = networkInterface
            .getInetAddresses();
        while (enumInetAddress.hasMoreElements()) {
          InetAddress inetAddress = enumInetAddress.nextElement();

          if (inetAddress.isSiteLocalAddress()) {
            ip += inetAddress.getHostAddress() + "\n";
          }
        }
      }
      //To remove extra characters from IP for Android Pie
      if (ip.length() > 14) {
        for (int i = 15, j = 12; i < 18; i++, j++) {
          if ((ip.charAt(i) == '.')) {
            ip = ip.substring(0, j + 1);
            break;
          }
        }
      }
    } catch (SocketException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      ip += "Something Wrong! " + e.toString() + "\n";
    }

    Log.v("DANG", "Returning : " + "http://" + ip);
    return "http://" + ip;
  }