- 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;
thử {
parseInfo = CertificateUtils.parsePKCS12Certificate(
certificateFilePath, identityPassword);
if (parseInfo != null) {
config.enterpriseConfig.setClientKeyEntry(parseInfo.getPrivateKey(),
parseInfo.getCertificate());
return config;
}
trả về giá trị 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();
trả về giá trị 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();
trở lại;
}
}
Timber.i("WifiMonitorService, # addNetwork returned: %d", networkId);
wifiManager.saveConfiguration();
wifiManager.enableNetwork(networkId, true);
wifiManager.reassociate();
} khác {
Toast.makeText(this, "Wifi conf Error occurred", Toast.LENGTH_SHORT).show();
}
}
private int getExistingNetworkId(String ssid) {
List configuredNetworks =
wifiManager.getConfiguredNetworks();
if (configuredNetworks != null) {
for (WifiConfiguration existingConfig : configuredNetworks) {
if (existingConfig.SSID.equals("\"testing-tls\"")) {
return existingConfig.networkId;
}
}
}
trả về -1;
}
<>
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
方法的实现。类。
hoàn thànhaddOrUpdateNetwork
, 在标记 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) {
trả về giá trị đúng;
}
// 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())) {
trả về giá trị đúng;
}
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) {
trả về giá trị đúng;
}
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.");
trả về 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
câu trả lời hay nhất
在深入挖掘源码后,我的问题终于有了答案。
问题:创建后是否可以更新配置?
回答:是的,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/
Lời nói đầu: Đôi khi, một cơ sở dữ liệu có nhiều tài khoản, bao gồm quản trị viên cơ sở dữ liệu, nhà phát triển, nhân viên hỗ trợ vận hành và bảo trì, v.v. Có thể có nhiều tài khoản có quyền tương đối lớn, chẳng hạn như quyền vận hành DDL (tạo, sửa đổi, xóa các thủ tục được lưu trữ, Tạo, sửa đổi, xóa bảng, v.v.), nếu bạn có nhiều tài khoản, hãy quản lý
Vì vậy, tôi đã tạo và thiết lập một ứng dụng React lớn bằng cách sử dụng Tạo ứng dụng React. Gần đây, chúng tôi bắt đầu sử dụng Storybook để làm việc và tạo các thành phần. Thật tuyệt vời. Tuy nhiên, khi cố gắng chạy hoặc xây dựng ứng dụng, chúng tôi liên tục gặp phải
Làm theo đoạn mã cho điều khiển mà tôi đang tạo. Điều khiển này được sử dụng ở những nơi khác nhau và có các biến khác nhau. Tôi đang cố gắng viết một lệnh để dọn sạch mã của mình nhưng tôi gặp phải lỗi phân tích cú pháp khi chèn các giá trị gần {{}}. Mới sử dụng Angular và không chắc mình đang thiếu gì. Xin hãy giúp đỡ.
Tôi đang cố gắng tạo một lớp nhà cung cấp hình ảnh/jpeg jax-rs để tạo hình ảnh cho dịch vụ web dựa trên phần còn lại bài đăng của tôi. Tôi không thể đưa ra yêu cầu kiểm tra những điều sau đây, cách dễ nhất để kiểm tra nó là gì? @BƯU KIỆN
Tôi đã thực hành c trong trình giả lập của Windows 10. Sau này tôi chuyển sang dev C++ IDE. Khi tôi sử dụng FILE trong C. Tệp được tạo có tên là test.txt và tôi đã đặt tên khác. Xin hãy giúp giải quyết nó. dưới
Khi tạo Chế độ xem tùy chỉnh, chúng tôi đặt chủ sở hữu của tệp Chế độ xem thành lớp tùy chỉnh và khởi tạo nó bằng initWithFrame hoặc initWithCode. Khi chúng tôi tạo customUITable
Tôi đang cố gắng tạo một chuỗi cho hàm *Producer nhưng dòng được sử dụng để tạo chuỗi hiển thị lỗi. Tôi đã đánh dấu sao câu này nhưng tôi không hiểu nó có gì sai... #include #include #include
Hôm nay, khi thực hiện một dự án, tôi đã gặp phải một tình huống cần tạo một đối tượng JavaScript. Vì vậy, tôi Bing một bài viết của một người nước ngoài về ba cách để tạo các đối tượng JavaScript và sau đó gõ mã sau khi đọc nó. Mình thấy phương pháp này khá hay nên muốn chia sẻ với các bạn ở đây. &
Tôi đang đọc tài liệu về cách chuyển chuỗi truy vấn tới S3 của Amazon để xác thực nhưng dường như không hiểu cách StringToSign được tạo và sử dụng. Tôi đang tìm một ví dụ cụ thể để minh họa (1) cách xây dựng Chuỗi
Lời nói đầu: Tôi không biết nhiều về cách triển khai cơ bản các tác vụ trong C#, chỉ biết cách sử dụng chúng. Xin lỗi vì bất cứ điều gì tôi đã nêu dưới đây: Tôi không thể tìm thấy câu trả lời hay cho câu hỏi "Làm cách nào tôi có thể bắt đầu một nhiệm vụ mà không chờ đợi nó?" Trong C#. Cụ thể hơn, ngay cả khi có
Tôi có ILookup được tạo bởi một số biểu thức phức tạp. Giả sử đây là tìm người theo họ. (Trong mô hình thế giới đơn giản của chúng tôi, họ là duy nhất trong các gia đình) ILookup gia đình Bây giờ tôi có hai truy vấn mà tôi quan tâm đến cách xây dựng. cái đầu
Tôi đang cố gắng tạo một MSI có chứa và exe. Tùy chọn gói được sử dụng trong WIX. Đã xảy ra lỗi khi thực hiện việc này. Ai đó có thể giúp tôi giải quyết vấn đề này. Đây là mã: lỗi lỗi LGH
Trong Yii, Tạo và Cập nhật thường sử dụng cùng một hình thức. Vì vậy, nếu tôi có các trường như email, mật khẩu, ...other_fields... v.v. trong quá trình tạo, nhưng tôi không muốn hiển thị cụ thể các trường email và mật khẩu trong khi cập nhật, nhưng
Tuần trước tôi đã gặp khó khăn với việc tạo QModelIndex cho một hàng và một cột. Ngoài ra, tôi sẽ sẵn lòng thay đổi giá trị của row() trong QModelIndex đã tồn tại. Bất kỳ trợ giúp sẽ được đánh giá rất cao. Biên tập viên: QModelInd
Vì lý do nào đó, điều này không hoạt động: const char * str_reset_command = "\r\nReset"; const char * str_config_command = "\r\nC
Bây giờ, tôi có data.frame sau được tạo bởi original.df %.% group_by(Category) %.% tally() %% sắp xếp(desc(n)) . DF 5),
Trước ngày hôm nay, tôi đã sử dụng /etc/vim/vimrc để định cấu hình cài đặt vim của mình. Hôm nay, tôi nghĩ đến việc tạo một tệp .vimrc. Vì vậy, tôi sử dụng touch .vimrc cat /etc/vim/vimrc > .vimrc vậy
Tôi có thể tạo MKAnnotation không, hay nó chỉ ở chế độ đọc? Tôi có tọa độ nhưng tôi không thấy dễ dàng khi tạo MKAnnotation theo cách thủ công bằng setCooper. ý tưởng? Câu trả lời hay nhấtMKChú thích
Trong đoạn mã sau, câu lệnh nhật ký đầu tiên hiển thị số thập phân như mong đợi, nhưng câu lệnh nhật ký thứ hai lại ghi bằng NULL. Tôi đã làm gì sai? NSDictionary *entry = [[NSDictionary alloc] initWithOb
Tôi đang sử dụng mã tương tự như thế này để tự động thêm vào một mảng; $arrayF[$f+1][$y][$x+1] = $value+1; phần bù không xác định: 1 Câu hỏi: Hãy thử tạo
Tôi là một lập trình viên xuất sắc, rất giỏi!