我正在开发一个应用程序,其主要目的是创建一个WiFi接口,并尝试设备连接到它.
为了实现这一点,我使用了MVVM模式,这样做:
MainActivity.kt
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
private val viewModel: SharedViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setUI()
processWifiConfiguration(applicationContext)
}
private fun processWifiConfiguration(context: Context) {
try {
viewModel.launchWifiConfiguration(context = context)
}catch (e:NullPointerException){
Log.d("es.paytef", "configuredNetworks esta a null")
e.printStackTrace()
}
}
private fun setUI() {
setContent {
val viewModel: SharedViewModel = hiltViewModel()
val isLoading by viewModel.isLoading.collectAsState()
val context = LocalContext.current
WifiCepsaManagerTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
if(isLoading){
CenterLoadingText(applicationContext.getString(R.string.wait))
}else{
//Finnish activity
context.startActivity(Intent(Settings.ACTION_WIFI_SETTINGS))
this.finish()
}
}
}
}
}
}
@Composable
fun CenterLoadingText(name: String) {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier.fillMaxSize()
) {
CircularProgressIndicator()
Text(
text = name,
textAlign = TextAlign.Center
)
}
}
字符串
关于接口的逻辑在我的viewmdel中:
SharedViewModel.kt
@HiltViewModel
class SharedViewModel @Inject constructor(@ApplicationContext context: Context) : ViewModel() {
private val wifiManager: WifiManager =
context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
private val _isLoading: MutableStateFlow<Boolean> = MutableStateFlow(false)
val isLoading: StateFlow<Boolean> = _isLoading.asStateFlow()
fun launchWifiConfiguration(context: Context) {
viewModelScope.launch(Dispatchers.IO) {
_isLoading.emit(true)
if (!wifiManager.isWifiEnabled) {
wifiManager.isWifiEnabled = true
}
if (ActivityCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return@launch
}
val wifiConfiguration = createWifiConfiguration()
try {
connectWifi(
context = context,
wifiConfiguration = wifiConfiguration
).also {
_isLoading.emit(false)
}
} catch (e: Exception) {
_isLoading.emit(false)
}
}
}
private fun createWifiConfiguration(): WifiConfiguration {
/**
* Set the following wifi params:
* Seguridad: 802.1x EAP
* Método EAP: EAP PEAP
* Autenticación fase 2: MSCHAPv2
* Certificado CA: Sin certificado
* Identidad: ***********
* Identidad anónima: Nada
* Contraseña: ******
*
*/
val wifiEnterpriseConfig = WifiEnterpriseConfig()
val wifiConfiguration = WifiConfiguration()
wifiConfiguration.status = WifiConfiguration.Status.ENABLED
wifiEnterpriseConfig.eapMethod = WifiEnterpriseConfig.Eap.PEAP
wifiEnterpriseConfig.phase2Method = WifiEnterpriseConfig.Phase2.MSCHAPV2
wifiEnterpriseConfig.caCertificate = null
wifiEnterpriseConfig.anonymousIdentity = null
wifiEnterpriseConfig.identity = "\""+BuildConfig.WIFI_USER +"\""
wifiEnterpriseConfig.password = "\""+BuildConfig.WIFI_PASS +"\""
wifiConfiguration.enterpriseConfig = wifiEnterpriseConfig
wifiConfiguration.SSID = "\""+BuildConfig.WIFI_SSID +"\""
wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP)
wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X)
wifiConfiguration.preSharedKey ="\""+BuildConfig.WIFI_PASS+"\""
wifiConfiguration.allowedProtocols.set(WifiConfiguration.Protocol.RSN)
wifiConfiguration.allowedProtocols.set(WifiConfiguration.Protocol.WPA)
wifiConfiguration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP)
wifiConfiguration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP)
wifiConfiguration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40)
wifiConfiguration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104)
wifiConfiguration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP)
wifiConfiguration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP)
return wifiConfiguration
}
private fun connectWifi(
context: Context,
wifiConfiguration: WifiConfiguration,
) {
if (ActivityCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return
}
//add the network
val ssid = wifiManager.addNetwork(
wifiConfiguration
)
//Enable all the interface
wifiManager.configuredNetworks.map {
it.status = WifiConfiguration.Status.ENABLED
}
wifiManager.disconnect()
wifiManager.enableNetwork(ssid, true) // this initiates the connection
wifiManager.isWifiEnabled = true
wifiManager.reconnect()
}
fun getNetworkId(context: Context, ssid: String): Int {
if (ActivityCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return -1
}
val configurations = wifiManager.configuredNetworks
for (config in configurations) {
if (config.SSID != null && config.SSID.equals(ssid, true)) {
return config.networkId
}
}
return -1
}
}
型
当前的工作流程是,当我在A920 Pro设备(API 25)中启动应用程序时,自定义网络将添加到记住的网络中,但如果我在IM 30设备(API 27)中启动应用程序,则不会添加网络。
我知道WifiConfiguration类已被弃用,但另一种方法,即使用WifiSuggestion,在29级API设备下不可用,因此它不是一个选项。
你有类似的事件吗?如果是这样,我错过了什么?
提前致谢!
[编辑]
在登录一个A920设备后,它与IM 30设备具有相同的API,我看到addNetwork()方法在A920中返回-1,所以在IM 30中我假设它必须是相同的。
我添加日志,添加我的自定义网络后,和设备的记住的网络,在那里你可以检查我的自定义网络没有被添加:消息“Conecta el wifi:ssid:“和“Habilita el wifi:“参考addNetwork方法
Añade la configuración: ID: -1 SSID: "MYCUSTOMNETWORK" PROVIDER-NAME: null BSSID: null FQDN: null PRIO: 0 HIDDEN: false
NetworkSelectionStatus NETWORK_SELECTION_ENABLED
hasEverConnected: false
KeyMgmt: WPA_EAP IEEE8021X Protocols: WPA RSN
AuthAlgorithms: LEAP
PairwiseCiphers: TKIP CCMP
GroupCiphers:
PSK: *
sim_num
Enterprise config:
anonymous_identity NULL
password <removed>
identity ""carwash""
proactive_key_caching 1
IP config:
IP assignment: UNASSIGNED
Proxy settings: UNASSIGNED
cuid=-1 luid=-1 lcuid=0 userApproved=USER_UNSPECIFIED noInternetAccessExpected=false isCarrierNetwork=false roamingFailureBlackListTimeMilli: 1000
triggeredLow: 0 triggeredBad: 0 triggeredNotHigh: 0
ticksLow: 0 ticksBad: 0 ticksNotHigh: 0
triggeredJoin: 0
2023-11-03 15:09:29.577 17790-17831 Tras añadir a la config: [* ID: 0 SSID: "************" PROVIDER-NAME: null BSSID: null FQDN: null PRIO: 22 HIDDEN: false
NetworkSelectionStatus NETWORK_SELECTION_ENABLED
hasEverConnected: true
numAssociation 59
validatedInternetAccess
KeyMgmt: WPA_PSK Protocols: WPA RSN
AuthAlgorithms:
PairwiseCiphers: TKIP CCMP
GroupCiphers: TKIP CCMP
PSK: *
sim_num *
Enterprise config:
altsubject_match NULL
password <removed>
ca_path NULL
subject_match NULL
engine 0
client_cert NULL
anonymous_identity NULL
ca_cert NULL
identity NULL
domain_suffix_match NULL
key_id NULL
engine_id NULL
IP config:
IP assignment: DHCP
Proxy settings: NONE
networkSelectionBSSID=any cuid=1000 cname=android.uid.system:1000 luid=1000 lname=android.uid.system:1000 lcuid=-1 userApproved=USER_APPROVED noInternetAccessExpected=false isCarrierNetwork=false roamingFailureBlackListTimeMilli: 1000
triggeredLow: 0 triggeredBad: 0 triggeredNotHigh: 0
ticksLow: 0 ticksBad: 0 ticksNotHigh: 0
triggeredJoin: 0
, - DSBLE ID: 1 SSID: "**************" PROVIDER-NAME: null BSSID: null FQDN: null PRIO: 0 HIDDEN: true
NetworkSelectionStatus NETWORK_SELECTION_ENABLED
hasEverConnected: false
KeyMgmt: WPA_PSK Protocols: WPA RSN
AuthAlgorithms: OPEN
PairwiseCiphers: TKIP CCMP
GroupCiphers: TKIP CCMP
PSK: *
sim_num *
Enterprise config:
altsubject_match NULL
password <removed>
ca_path NULL
subject_match NULL
engine 0
client_cert NULL
anonymous_identity NULL
ca_cert NULL
identity NULL
domain_suffix_match NULL
key_id NULL
engine_id NULL
IP config:
IP assignment: DHCP
Proxy settings: NONE
cuid=10038 cname=com.diusframi.pax luid=10038 lname=com.diusframi.pax lcuid=10038 userApproved=USER_UNSPECIFIED noInternetAccessExpected=false isCarrierNetwork=false roamingFailureBlackListTimeMilli: 1000
triggeredLow: 0 triggeredBad: 0 triggeredNotHigh: 0
ticksLow: 0 ticksBad: 0 ticksNotHigh: 0
triggeredJoin: 0
]
2023-11-03 15:09:29.582 17790-17831 Habilita el status de: ssid:"****************" status: 2
2023-11-03 15:09:29.582 17790-17831 Habilita el status de: ssid:"**************" status: 2
2023-11-03 15:09:29.588 17790-17831 Habilita el wifi: -1
2023-11-03 15:09:29.697 17790-17831 Conecta el wifi: ssid:-1
型
所以我知道这是由于WiFi接口中的配置错误,这使得与Android不兼容7设备.
这里是我的当前配置:
wifiConfiguration.status = WifiConfiguration.Status.ENABLED
wifiEnterpriseConfig.eapMethod = WifiEnterpriseConfig.Eap.PEAP
wifiEnterpriseConfig.phase2Method = WifiEnterpriseConfig.Phase2.MSCHAPV2
wifiEnterpriseConfig.caCertificate = null
wifiEnterpriseConfig.anonymousIdentity = null
wifiEnterpriseConfig.identity = "\""+BuildConfig.WIFI_USER +"\""
wifiEnterpriseConfig.password = "\""+BuildConfig.WIFI_PASS +"\""
wifiConfiguration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.LEAP)
wifiConfiguration.enterpriseConfig = wifiEnterpriseConfig
wifiConfiguration.SSID = "\""+BuildConfig.WIFI_SSID +"\""
wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP)
wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X)
wifiConfiguration.preSharedKey ="\""+BuildConfig.WIFI_PASS+"\""
wifiConfiguration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP)
wifiConfiguration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP)
wifiConfiguration.allowedProtocols.set(WifiConfiguration.Protocol.RSN)
wifiConfiguration.allowedProtocols.set(WifiConfiguration.Protocol.WPA)
型
有线索吗?
[编辑]
我添加我在清单文件中已经拥有的所有权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
型
1条答案
按热度按时间vsnjm48y1#
Android 6.0(API级别23),与Wi-Fi处理相关的某些权限需要CHANGE_WIFI_STATE权限,该权限允许应用更改Wi-Fi连接状态。
字符串
此外,请确保您的应用具有必要的运行时权限,尤其是ACCESS_FINE_LOCATION,因为它是与Wi-Fi设置交互的关键权限。