美文网首页
Android Q WIFI连接问题 汇总

Android Q WIFI连接问题 汇总

作者: 善良的老农 | 来源:发表于2023-08-08 17:40 被阅读0次

    1.WIFI连接


    var connectivityManager: ConnectivityManager? =null

        // WiFi连接回调

        val networkCallback: ConnectivityManager.NetworkCallback =

        object : ConnectivityManager.NetworkCallback() {

        override fun onUnavailable() {

        super.onUnavailable() 

        //  WIFI连接失败 

        }

        override fun onAvailable(network: Network) {

        super.onAvailable(network)

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

        //  这行必加 不然连上无网络

        connectivityManager?.bindProcessToNetwork(network)

        };

        }

    2.连接WIFI

    @RequiresApi(Build.VERSION_CODES.Q)

    private fun connectWifiQ(pwd: String, it: WifiBean) {

    timerStop()

    val specifier: NetworkSpecifier = WifiNetworkSpecifier.Builder()

    .setBssid(MacAddress.fromString(it.scanResult.BSSID)) // 名称  

    .setWpa2Passphrase(pwd)  // 密码

    .build()

    val request: NetworkRequest = NetworkRequest.Builder()

    .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)

    .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)

    .setNetworkSpecifier(specifier)

    .build()

    connectivityManager =

    applicationContext.getSystemService(CONNECTIVITY_SERVICE)as ConnectivityManager

    currentBssID = it?.scanResult.BSSID

        it?.pwd = pwd

    if (networkCallback !=null) {

    connectivityManager?.requestNetwork(request, networkCallback)

    }

    }

    3.断开  
     //这里解除绑定  会断网  不知道为什么  
    fun disConnectWifi() {

    if (networkCallback !=null) {

    connectivityManager?.unregisterNetworkCallback(networkCallback)

    }

    }


    推荐用这种方式

    @SuppressLint("MissingPermission")

    fun getNewWorkId(wifiManager: WifiManager, SSID: String): Int {

    wifiManager.configuredNetworks?.forEach {

            if (stringReplace(it.SSID)== SSID) {

    var disableNetwork =    wifiManager.disableNetwork(it.networkId)

    var removeNetwork =  wifiManager.removeNetwork(it.networkId)

    if ( stringReplace(it.SSID) == getConnectedWifiInfo(wifiManager)?.ssid ){  //如果需要断开 则调用   否则  不调用disconnet 断开

        var disconnect =      wifiManager.disconnect()

    }

    AppLog.getInstance().i("getNewWorkId 1  =  ${ it.networkId} disableNetwork =$disableNetwork  removeNetwork= $removeNetwork disconnect= $disconnect")

    return it.networkId;

            }

    }

        AppLog.getInstance().i("not find networkId ")

    return 0;

    }

    //符号替换

    private fun stringReplace(str: String): String? {

    return str.replace("\"", "")

    }
    // 获取当前连接的wifi 信息
    private fun getConnectedWifiInfo( wifiManager: WifiManager): WifiInfo? { val info: WifiInfo = wifiManager.connectionInfo return if ("0x" == info.ssid) { null } else info}

    写在最后  问题   
    如果绑定后不解绑   断开该wifi 之后    即便连接了网络也无法访问网络  拿到  Ip  
    connectivityManager?.bindProcessToNetwork(network)

    列如:  直接获取不到   

    fun getLocalIp(): String {
     

    var ipAddress =""

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

    try {

    val manager =

    getContext().getSystemService(Context.CONNECTIVITY_SERVICE)as ConnectivityManager

    val networkInfo = manager.activeNetwork

                val prop = manager.getLinkProperties(networkInfo)

    val iface = NetworkInterface.getByName(prop?.interfaceName)

    AppLog.getInstance().e("getLocalIp error iface: ${iface}")

    AppLog.getInstance().e("getLocalIp error iface.inetAddresses: ${iface.inetAddresses}")

    val net: Enumeration = iface.inetAddresses

                // 遍历每一个接口绑定的所有ip

                while (net.hasMoreElements()) {

    var ip: InetAddress = net.nextElement()

    if (!ip.isLoopbackAddress && ipis Inet4Address &&ip.isSiteLocalAddress) {

    ipAddress =ip.hostAddress

                        AppLog.getInstance().i("ProjetionLog  networkName = ${NetworkUtils.getNetName()} ; getLocalIp = $ipAddress")

    return ipAddress

    }

    }

    }catch (e: Exception) {

    AppLog.getInstance().e("getLocalIp error : ${e.message}")

    }

    return ipAddress

    }else return ipAddress

    }

    解绑 推荐使用在 网络广播  
    // 网络变化监听
    intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE")


    /**

    val intentFilter: IntentFilter = IntentFilter()

    * 网络监听

    */

    val mNetWorkReceiver =object : BroadcastReceiver() {

    @RequiresApi(Build.VERSION_CODES.M)

    override fun onReceive(context: Context?, intent: Intent?) {

    var    connectivityManager =

    context?.getSystemService(AppCompatActivity.CONNECTIVITY_SERVICE)as ConnectivityManager

    connectivityManager?.bindProcessToNetwork(null)   //在这里进行解绑

    netWorkChange?.invoke()

    }

    }

    registerReceiver(netWorkBroadcast.mNetWorkReceiver, netWorkBroadcast.intentFilter)

    关于解绑 : connectivityManager?.bindProcessToNetwork(it) 该方法是绑定应用只走该通道 

     换绑:

    var connectivityManager =

    context?.getSystemService(AppCompatActivity.CONNECTIVITY_SERVICE)as ConnectivityManager

    connectivityManager?.bindProcessToNetwork(null)

    connectivityManager.allNetworks.forEach {

        if (connectivityManager.getNetworkInfo(it)?.isConnected ==true) {

    connectivityManager?.bindProcessToNetwork(it)

    AppLog.getInstance().i("bindProcessToNetwork ${connectivityManager.getNetworkInfo(it)}")

    }

    }

    有系统签名权限   可以直接用这种连接方式 

    连接WIFI

    TestConnect.connectWifi(wifiManager , TestConnect.createWifiInfo( SSID ,  pwd, false ,ScanResult.capabilities))}")

    断开WIFI


    TestConnect.disConnect(wifiManager , WifiConfiguration.networkId)

    工具类:

    /**

    * @author as752497576@gmail.com

    * @description

    * @time 2023/8/23

    */

    public class TestConnect {

    /**

        * 连接wifi

    *

        * @param manager      WifiManager

        * @param configuration Wifi配置

        * @return 是否连接成功

        */

        public static boolean connectWifi(WifiManager manager, WifiConfiguration configuration) {

    int id = manager.addNetwork(configuration);

            WifiInfo connectionInfo = manager.getConnectionInfo();

            manager.disableNetwork(connectionInfo.getNetworkId());

            boolean b = manager.enableNetwork(id, true);

            Log.d("WifiManagerUtils", "connectWifi: 连接状态=" + b);

            if (b) {

    manager.saveConfiguration();

            }else {

    Log.d("WifiManagerUtils", configuration.toString());

            }

    return b;

        }

    /**

        * 创建Wifi配置

        *

        * @param SSID        wifi名称

        * @param password    wifi密码

        * @param hidden      网络是否隐藏(该方法与添加隐藏网络通用)

        * @param capabilities 网络安全协议

        * @return 配置好的wifi

    */

        public static WifiConfigurationcreateWifiInfo(String SSID, String password, boolean hidden, String capabilities) {

    WifiConfiguration configuration =new WifiConfiguration();

            configuration.SSID ="\"" + SSID +"\"";

            if (hidden) {

    configuration.hiddenSSID =true;

            }

    Log.d("WifiManagerUtils", "createWifiInfo: " + capabilities);

            if (capabilities.contains("SAE") && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {

    Log.d("WifiManagerUtils", "createWifiInfo SAE "  );

                setWPA3(configuration, password);

            }else if (capabilities.contains("WPA-PSK") || capabilities.contains("WPA2-PSK")) {

    Log.d("WifiManagerUtils", "createWifiInfo WPA-PSK "  );

                setWPA(configuration, password);

            }else if (capabilities.contains("WEP")) {

    Log.d("WifiManagerUtils", "createWifiInfo WEP "  );

                setWEP(configuration, password);

            }else {

    setESS(configuration);

            }

    return configuration;

        }

    /**

        * 设置wpa3协议

        *

        * @param configuration 配置

        * @param password      密码

        */

        public static void setWPA3(WifiConfiguration configuration, String password) {

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {

    configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SAE);

            }

    configuration.preSharedKey ="\"" + password +"\"";

        }

    /**

        * WPA协议

        *

        * @param configuration 配置

        * @param password      密码

        */

        public static void setWPA(WifiConfiguration configuration, String password) {

    configuration.preSharedKey ="\"" + password +"\"";

            //公认的IEEE 802.11验证算法。

            configuration.allowedAuthAlgorithms.clear();

            configuration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);

            //公认的的公共组密码。

            configuration.allowedGroupCiphers.clear();

            configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);

            configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);

            //公认的密钥管理方案。

            configuration.allowedKeyManagement.clear();

            configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);

            //密码为WPA。

            configuration.allowedPairwiseCiphers.clear();

            configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);

            configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);

            //公认的安全协议。

            configuration.allowedProtocols.clear();

            configuration.allowedProtocols.set(WifiConfiguration.Protocol.RSN);

        }

    /**

        * WEP协议

        *

        * @param configuration 配置

        * @param password      密码

        */

        public static void setWEP(WifiConfiguration configuration, String password) {

    configuration.wepKeys[0] ="\"" + password +"\"";

            configuration.wepTxKeyIndex =0;

            configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);

            configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);

        }

    /**

        *  断开WIFI

    */

        public static void disConnect(WifiManager wifiManager,  int networkId) {

    boolean    disableNetwork = wifiManager.disableNetwork(networkId);

            boolean removeNetwork = wifiManager.removeNetwork(networkId);

            //  如上面无法断开 则wifiManager.disconnect()

        }

    /**

        * 无密码

        *

        * @param configuration 配置

        */

        public static void setESS(WifiConfiguration configuration) {

    configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);

        }

    }

    相关文章

      网友评论

          本文标题:Android Q WIFI连接问题 汇总

          本文链接:https://www.haomeiwen.com/subject/osanpdtx.html