搭载 Android 10(API 级别 29)及更高版本的设备允许您的应用添加网络
凭据。你可以提供
建议连接到哪个网络
WifiNetworkSuggestion
。
平台最终会根据
输入来自您的应用和其他应用的
在 Android 11(API 级别 30)及更高版本中:
- 预配
PasspointConfiguration
由建议 API 支持。在 Android 11 之前, 预配PasspointConfiguration
需要使用addOrUpdatePasspointConfiguration()
API。 - 该框架对基于 TLS 的企业强制执行安全要求
建议(EAP-TLS、EAP-TTLS 和 EAP-PEAP);向此类网络推荐
必须设置
Root CA certificate
和server domain name
。
- 该框架针对基于 EAP-SIM 的企业强制执行所有权要求 建议(EAP-SIM、EAP-AKA、EAP-AKA-PRIME);此类建议 仅限由运营商签名的应用使用。
- 对于由运营商签名的应用提供的建议,框架会自动 会为其分配与应用的 运营商签名。此类 如果取出相应 SIM 卡,系统会自动停用建议功能 。
在 Android 12(API 级别 31)及更高版本中:
可以通过非永久性随机分配 MAC 地址实现额外的隐私保护, 它会定期重新随机分配随机分配的 MAC 地址。 使用
setMacRandomizationSetting
指定网络的随机化级别。isPasspointTermsAndConditionsSupported()
:“条款及条件”是一项 Passpoint 功能,允许网络部署将不安全的强制门户(使用开放网络)替换为安全的 Passpoint 网络。当要求用户接受条款及条件时,系统会向用户显示一条通知。如果应用建议的 Passpoint 网络受条款及条件制约,应用必须先调用此 API,以确保设备支持该功能。如果设备不支持该功能,就不能连接到此网络,并且必须建议一个替代网络或旧网络。isDecoratedIdentitySupported()
:对带有前缀修饰的网络进行身份验证时,修饰的身份前缀允许网络运营商更新网络访问标识符 (NAI),以通过 AAA 网络内的多个代理执行显式路由(如需详细了解这一点,请参阅 RFC 7542)。Android 12 实现了此功能,以符合 PPS-MO 扩展的 WBA 规范。如果应用建议的 Passpoint 网络需要修饰的身份,应用必须先调用此 API,以确保设备支持该功能。如果设备不支持该功能,身份就不会进行修饰,并且对网络的身份验证可能会失败。
如需创建 Passpoint 建议,应用必须使用 PasspointConfiguration
、Credential
和 HomeSp
类。这些类描述了 Wi-Fi Alliance Passpoint 规范中定义的 Passpoint 配置文件。
以下代码示例展示了如何为两种类型的实例提供凭据: WPA2、一个 WPA3 网络和一个 Passpoint 网络:
Kotlin
val suggestion1 = WifiNetworkSuggestion.Builder() .setSsid("test111111") .setIsAppInteractionRequired(true) // Optional (Needs location permission) .build(); val suggestion2 = WifiNetworkSuggestion.Builder() .setSsid("test222222") .setWpa2Passphrase("test123456") .setIsAppInteractionRequired(true) // Optional (Needs location permission) .build(); val suggestion3 = WifiNetworkSuggestion.Builder() .setSsid("test333333") .setWpa3Passphrase("test6789") .setIsAppInteractionRequired(true) // Optional (Needs location permission) .build(); val passpointConfig = PasspointConfiguration(); // configure passpointConfig to include a valid Passpoint configuration val suggestion4 = WifiNetworkSuggestion.Builder() .setPasspointConfig(passpointConfig) .setIsAppInteractionRequired(true) // Optional (Needs location permission) .build(); val suggestionsList = listOf(suggestion1, suggestion2, suggestion3, suggestion4); val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager; val status = wifiManager.addNetworkSuggestions(suggestionsList); if (status != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) { // do error handling here } // Optional (Wait for post connection broadcast to one of your suggestions) val intentFilter = IntentFilter(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION); val broadcastReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { if (!intent.action.equals(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION)) { return; } // do post connect processing here } }; context.registerReceiver(broadcastReceiver, intentFilter);
Java
final WifiNetworkSuggestion suggestion1 = new WifiNetworkSuggestion.Builder() .setSsid("test111111") .setIsAppInteractionRequired(true) // Optional (Needs location permission) .build(); final WifiNetworkSuggestion suggestion2 = new WifiNetworkSuggestion.Builder() .setSsid("test222222") .setWpa2Passphrase("test123456") .setIsAppInteractionRequired(true) // Optional (Needs location permission) .build(); final WifiNetworkSuggestion suggestion3 = new WifiNetworkSuggestion.Builder() .setSsid("test333333") .setWpa3Passphrase("test6789") .setIsAppInteractionRequired(true) // Optional (Needs location permission) .build(); final PasspointConfiguration passpointConfig = new PasspointConfiguration(); // configure passpointConfig to include a valid Passpoint configuration final WifiNetworkSuggestion suggestion4 = new WifiNetworkSuggestion.Builder() .setPasspointConfig(passpointConfig) .setIsAppInteractionRequired(true) // Optional (Needs location permission) .build(); final List<WifiNetworkSuggestion> suggestionsList = new ArrayList<WifiNetworkSuggestion> {{ add(suggestion1); add(suggestion2); add(suggestion3); add(suggestion4); }}; final WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); final int status = wifiManager.addNetworkSuggestions(suggestionsList); if (status != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) { // do error handling here… } // Optional (Wait for post connection broadcast to one of your suggestions) final IntentFilter intentFilter = new IntentFilter(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION); final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (!intent.getAction().equals( WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION)) { return; } // do post connect processing here... } }; context.registerReceiver(broadcastReceiver, intentFilter);
在应用首次提出建议后,用户会立即 通知。通知类型取决于运行的 Android 版本 :
- 在 Android 11(API 级别 30)及更高版本中,如果应用 当应用在前台运行的情况下显示通知 背景。
- 在 Android 10(API 级别 29)中,无论用户选择哪个 确定应用是在前台运行还是在后台运行。
当平台连接到其中一个建议网络时,系统会显示设置 将网络连接归因于提出建议的相应应用的文本。
处理用户断开连接
如果用户使用 Wi-Fi 选择器明确断开与其中一个 Wi-Fi 网络的连接 系统会忽略该网络 仍在有效范围内在此期间,系统将不会考虑使用该广告网络 (即使应用移除并重新添加网络建议) 。如果用户使用 Wi-Fi 选择器明确指定 连接到之前断开的网络时,该网络将会被 考虑立即自动连接。
更改应用的批准状态
用户拒绝接收网络建议通知时,会删除
CHANGE_WIFI_STATE
权限。用户可以授予这项批准
稍后,您可以进入 Wi-Fi 控制菜单(设置 >
应用程序与通知 >特殊应用程序
访问权限 >Wi-Fi 控制 >App name)。