美文网首页
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