- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在开发一个管理 Wi-Fi 连接的应用程序。我的场景如下:假设整栋楼都有一个名为“testing-tls”的 Wi-Fi 网络。我的应用程序应该只能连接到选定的接入点(基于 BSSID 或 MAC ID)。我们使用TLS 身份验证 机制来验证用户(自定义 CA 证书)。
我可以通过应用程序建立连接,但是当我尝试连接到不同的接入点(不同的 BSSID)时失败了。即使我以编程方式创建 Wi-Fi 配置,我也无法在首次成功连接后更新配置。我已经在 Oreo 和 Marshmallow 中测试了我的应用程序。但是,我在奥利奥中遇到了问题(不确定牛轧糖)。我开始怀疑是否有可能在创建配置后对其进行更新。
private WifiConfiguration createWifiConfiguration() {
WifiConfiguration config = new WifiConfiguration();
config.SSID = "\"testing-tls\"";
config.priority = 1;
config.status = WifiConfiguration.Status.ENABLED;
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP;
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
config.enterpriseConfig.setIdentity(identityName);
config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
PKCS12ParseInfo parseInfo;
try {
parseInfo = CertificateUtils.parsePKCS12Certificate(
certificateFilePath, identityPassword);
if (parseInfo != null) {
config.enterpriseConfig.setClientKeyEntry(parseInfo.getPrivateKey(),
parseInfo.getCertificate());
return config;
}
return null;
} catch (KeyStoreException | NoSuchAlgorithmException | IOException |
CertificateException | UnrecoverableKeyException | KeyManagementException e1) {
Timber.e("WifiMonitorService, Fail to parse the input certificate: %s", e1.toString());
Toast.makeText(this, "Error occurred", Toast.LENGTH_SHORT).show();
return null;
}
}
private void establishWifiConnection(String result) {
Timber.d("WifiMonitorService, establishing WifiConnection");
WifiConfiguration configuration = createWifiConfiguration();
if (configuration != null) {
// result contains a mac id - 00:45:69:c5:34:f2
configuration.BSSID = result;
int networkId = wifiManager.addNetwork(configuration);
if (networkId == -1) {
networkId = getExistingNetworkId(wifiSsid);
// Add a new configuration to the db
if (networkId == -1) {
Timber.e("Couldn't add network with SSID");
Toast.makeText(this, "Wifi configuration error", Toast.LENGTH_SHORT).show();
return;
}
}
Timber.i("WifiMonitorService, # addNetwork returned: %d", networkId);
wifiManager.saveConfiguration();
wifiManager.enableNetwork(networkId, true);
wifiManager.reassociate();
} else {
Toast.makeText(this, "Wifi conf Error occurred", Toast.LENGTH_SHORT).show();
}
}
private int getExistingNetworkId(String ssid) {
List<WifiConfiguration> configuredNetworks =
wifiManager.getConfiguredNetworks();
if (configuredNetworks != null) {
for (WifiConfiguration existingConfig : configuredNetworks) {
if (existingConfig.SSID.equals("\"testing-tls\"")) {
return existingConfig.networkId;
}
}
}
return -1;
}
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_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.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.OVERRIDE_WIFI_CONFIG" />
<uses-permission android:name="android.permission.NETWORK_SETTINGS" />
<uses-feature android:name="android.hardware.wifi" />
<uses-feature android:name="android.hardware.camera" />
<permission
android:name="android.permission.INTERACT_ACROSS_USERS"
android:protectionLevel="signature" />
UID 10189 does not have permission to update configuration error
in Oreo2018-12-28 12:23:44.571 1320-1847/? E/WifiConfigManager: UID 10189 does not have permission to update configuration "testing-tls"WPA_EAP
2018-12-28 12:23:44.571 1320-1847/? I/WifiStateMachine: connectToUserSelectNetwork Allowing uid 10189 with insufficient permissions to connect=1
在深入研究源代码后,我在 WifiConfigManager 中找到了 addOrUpdateNetwork
方法的实现。类。
实现addOrUpdateNetwork
, 在标记 android_8.0.0_r21 (Build number OPD1.170816.010) 中如下:
AddOrUpdateNetwork
在内部调用一个名为 canModifyNetwork
的函数:
/**
* Checks if |uid| has permission to modify the provided configuration.
*
* @param config WifiConfiguration object corresponding to the network to be modified.
* @param uid UID of the app requesting the modification.
* @param ignoreLockdown Ignore the configuration lockdown checks for connection attempts.
*/
private boolean canModifyNetwork(WifiConfiguration config, int uid, boolean ignoreLockdown) {
// Passpoint configurations are generated and managed by PasspointManager. They can be
// added by either PasspointNetworkEvaluator (for auto connection) or Settings app
// (for manual connection), and need to be removed once the connection is completed.
// Since it is "owned" by us, so always allow us to modify them.
if (config.isPasspoint() && uid == Process.WIFI_UID) {
return true;
}
// EAP-SIM/AKA/AKA' network needs framework to update the anonymous identity provided
// by authenticator back to the WifiConfiguration object.
// Since it is "owned" by us, so always allow us to modify them.
if (config.enterpriseConfig != null
&& uid == Process.WIFI_UID
&& TelephonyUtil.isSimEapMethod(config.enterpriseConfig.getEapMethod())) {
return true;
}
final DevicePolicyManagerInternal dpmi = LocalServices.getService(
DevicePolicyManagerInternal.class);
final boolean isUidDeviceOwner = dpmi != null && dpmi.isActiveAdminWithPolicy(uid,
DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
// If |uid| corresponds to the device owner, allow all modifications.
if (isUidDeviceOwner) {
return true;
}
final boolean isCreator = (config.creatorUid == uid);
// Check if the |uid| holds the |NETWORK_SETTINGS| permission if the caller asks us to
// bypass the lockdown checks.
if (ignoreLockdown) {
return mWifiPermissionsUtil.checkNetworkSettingsPermission(uid);
}
// Check if device has DPM capability. If it has and |dpmi| is still null, then we
// treat this case with suspicion and bail out.
if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN)
&& dpmi == null) {
Log.w(TAG, "Error retrieving DPMI service.");
return false;
}
// WiFi config lockdown related logic. At this point we know uid is NOT a Device Owner.
final boolean isConfigEligibleForLockdown = dpmi != null && dpmi.isActiveAdminWithPolicy(
config.creatorUid, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
if (!isConfigEligibleForLockdown) {
return isCreator || mWifiPermissionsUtil.checkNetworkSettingsPermission(uid);
}
final ContentResolver resolver = mContext.getContentResolver();
final boolean isLockdownFeatureEnabled = Settings.Global.getInt(resolver,
Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, 0) != 0;
return !isLockdownFeatureEnabled
&& mWifiPermissionsUtil.checkNetworkSettingsPermission(uid);
}
据我所知,只有以下 uid 有权修改网络配置。
我在这两款手机中遇到了相同的行为。
此外,Samsung J8 总是显示此警告:
CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certificate path not found
最佳答案
在深入挖掘源码后,我的问题终于有了答案。
问题:创建后是否可以更新配置?
回答:是的,Android 操作系统允许您更新从您的应用程序创建的配置。当我调用 wifiManager.addNetwork() , 在日志窗口中打印了以下语句。
2019-01-04 12:23:16.168 1328-3114/? I/addOrUpdateNetwork: uid = 10190 SSID "testing-tls" nid=-1
2019-01-04 12:23:16.169 1328-1851/? V/WifiConfigManager: Adding/Updating network testing-tls
2019-01-04 12:23:16.193 1328-1851/? D/WifiConfigManager: addOrUpdateNetworkInternal: added/updated config. netId=6 configKey="testing-tls"WPA_EAP uid=10190 name=in.ac.iisc.wifimonitoring vendorAP=false hiddenSSID=false autoReconnect=1
2019-01-04 12:23:16.204 1328-1851/? D/WifiConfigStore: Writing to stores completed in 7 ms.
2019-01-04 12:23:16.205 1328-1851/? D/WifiIssueDetector: report htime=2019-01-04_12:23:16 time=1546584796205 rid=105 callBy=in.ac.iisc.wifimonitoring apiName=addOrUpdateNetwork netid=6 callUid=in.ac.iisc.wifimonitoring
2019-01-04 12:23:16.206 15873-15873/in.ac.iisc.wifimonitoring I/WifiMonitorService: WifiMonitorService, #addNetwork returned: 6
问题:Oreo 中“UID 10189 没有权限更新配置错误”是什么意思?
回答:更新配置后,我们必须调用wifimanager.enableNetwork()方法建立到所需接入点的连接。 EnableNetwork() 的工作流程如下。
WifiStateMachine是跟踪 Wifi 连接状态的核心类。所有事件处理和连接状态的所有更改都在此类中启动。
SyncEnableNetwork() 方法将 CMD_ENABLE_NETWORK 消息发送到 ConnectModeState class .
如果 disableOthers 为真,调用 connectToUserSelectNetwork()方法并传递 networkId,调用 UID 并强制重新连接 [始终为 false - 硬编码值] 作为参数。
如果应用不具备更新配置所需的所有权限 [使用 checkAndUpdateLastUid() WifiConfigManager class 中的方法- 仅对系统设置/sysui 应用程序返回 true] 或者如果启用网络失败,将打印以下语句。
2018-12-28 12:23:44.571 1320-1847/? E/WifiConfigManager: UID 10189 does not have permission to update configuration "testing-tls"WPA_EAP
2018-12-28 12:23:44.571 1320-1847/? I/WifiStateMachine: connectToUserSelectNetwork Allowing uid 10189 with insufficient permissions to connect=1
注意:checkAndUpdateLastUid() 方法已在 Android Pie 中重命名为 updateLastConnectUid()。他们也略微修改了它的功能。
更多信息,请引用下图【我不擅长画流程图。如果需要任何更改,请耐心等待或提出建议]。
问题三:更新或启用配置前是否必须断开wifi?
回答:操作系统会在以下条件下触发网络连接/重新连接:
由于开发者应用程序没有强制连接的能力,我们应该在更新配置后断开 wifi 连接/重新连接到网络。
希望这对其他人有帮助。
关于android - 如何更新已创建的 Wi-Fi 配置(或 "UID XXX does not have permission to update [Wi-Fi] configuration error")?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53956062/
除了智能手机、平板电脑和个人电脑等流行设备外,Wi-Fi 6还将嵌入其他设备中,包括无线摄像头、智能家居设备、游戏机、可穿戴设备和AR/VR耳机。 那么,Wi-Fi 6会取代5G,成为下一代无线网络
在 API 14 或更高版本 (ICS) 中,可以使用临时 Wi-Fi 网络。我目前拥有以下设备,我正在尝试弄清楚如何测试 Wi-Fi 直连功能,或者我是否需要购买另一台搭载 Android 4.0
我正在构建一个 Android 应用程序以允许在有限范围内的两个设备之间进行通信,但我找不到与 native 等效的插件 Android Wi-Fi peer-to-peer适用于 Phonegap/
我目前正在尝试通过 Wi-Fi Direct 连接两部知道彼此 MAC 地址的手机,但偶然发现了以下问题:我从 收到的 MAC 地址 WifiManager wifiMan = (WifiMa
在 iOS 设备内和支持 Wi-Fi Direct 的设备之间是否可以进行 Wi-Fi Direct 连接? 目标是在没有任何 Controller 的情况下实现 iOS 设备与另一台设备(不一定是另
我正在开发一个管理 Wi-Fi 连接的应用程序。我的场景如下:假设整栋楼都有一个名为“testing-tls”的 Wi-Fi 网络。我的应用程序应该只能连接到选定的接入点(基于 BSSID 或 MAC
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a softwar
考虑这张 map : 我需要了解Wi-Fi三角测量的基本原理。上图中描绘了该场景。为了实现Wi-Fi三角测量,我至少需要三个Wi-Fi热点及其位置。设置: 为简单起见,假设我有一个 1平方公里x 1平
(^.^)“你好再次抱歉我的英语不好如果有人喜欢纠正我的编辑我将不胜感激” 嗨,如果我可以用我的 iPhone 从 wi-fi 网络、任何源代码、Api、教程等捕获 IV,现在有没有人可以做到这一点谁
我正在考虑创建一个通过 Wi-Fi Direct 传输视频流的应用程序。我已经用谷歌搜索过(甚至在 Stackoverflow 中),但我没有找到指定支持设备的列表。 我的问题是:是否可以在 Sams
我有一个问题,我想获取我的移动 IP 是网络还是Wi-Fi 我也尝试过一些方法,但我不知道为什么我不能得到它 public class MainActivity extends Activity {
我正在开发开箱即用的体验应用程序。我必须连接 来 self 的自定义应用程序的 wi-fi,不使用设备 wifi 设置。 我已经完成了,从 wifi 管理器获取 wi-fi 网络列表。 你能指导我如何
我正在开发一个需要检查互联网连接的 Android 应用程序。当设备的 WI-FI 关闭时它工作得很好但是当我打开 Wi-Fi 但没有连接到可用网络时,它是强制关闭。可能是什么问题?请帮助 bool
我想通过 Wi-Fi Direct 在 2 台设备之间传输文件。 我想做与 WifiDirectDemo 中相同的事情,但我无法将数据从群组所有者传输到另一台设备,所以我尝试了这个:每次当其中一台设备
模拟器可以连wifi吗?由于我没有使用 eclipse 或任何 IDE...我正在尝试将独立的模拟器连接到 Wi-fi 最佳答案 目前,虽然您可以在模拟器中使用计算机的互联网连接,但用它来模拟 Wi-
我正在尝试为大学设置 Qt,但遇到了一些问题。我正在运行 Windows 8,我不确定是哪个版本的 Qt 或 QtCreator,但不是最新的 - 我们获得了版本安装程序,所以我们必须使用这个版本,尽
我有一个运行 Android 的小型电视盒设备。每当我调出 Wi-Fi 接口(interface)时,以太网接口(interface)就会断开连接。如果我随后调出以太网设备、Wi-Fi 接口(inte
我有一个几乎总是需要知道用户位置的应用程序。 当我需要访问某个位置时,我会这样做: final AlertDialog.Builder builder = new AlertDialog.Builde
我正在开发一个基于 WiFi Direct 技术(P2P)的安卓应用,所以我真的需要知道安卓 WiFi 直接性能的范围是多少米。基于 Android API 指南: you can discover
当您连接的 Wi-Fi 无法访问 Internet 时, Android Lollipop 似乎默认为移动数据。有人知道这是否在某处有正式记录吗? 我们有一个应用程序需要通过 Wi-Fi 连接到没有互
我是一名优秀的程序员,十分优秀!