【问题标题】:Turning on a Wifi Hotspot programmatically and getting a WiFi Error以编程方式打开 Wifi 热点并收到 WiFi 错误
【发布时间】:2018-11-13 12:51:19
【问题描述】:

我正在使用 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 另一方面,如果我尝试 ping 通过静态 IP 192.168.43.50 连接的设备,它会给我 PING:传输失败。一般失败。错误消息。

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

有什么我想念的吗?

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

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

我观察到奇怪的行为。 当我从设置中手动进行 Hotspot Tethering 时。这个函数返回 192.168.43.1 但是当我通过代码打开 wifi 时,上面的函数返回 "" 空字符串。

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 2014-11-04
      • 1970-01-01
      • 1970-01-01
      • 2011-09-17
      • 1970-01-01
      • 1970-01-01
      • 2018-02-09
      • 2016-03-25
      • 1970-01-01
      相关资源
      最近更新 更多