gpt4 book ai didi

java - 在 Android 中使用 application/vnd.wfa.wsc 创建 NDEF WiFi 记录

转载 作者:太空狗 更新时间:2023-10-29 22:54:56 26 4
gpt4 key购买 nike

从 Android 5.0.0 开始,您可以长按 WiFi 连接并将该连接写入标签(“写入 NFC 标签”)。您可以在此处找到该操作的来源:WriteWifiConfigToNfcDialog.java .采用 WiFi 连接并创建 NDEF 负载的相关行似乎位于此处:

String wpsNfcConfigurationToken = mWifiManager.getWpsNfcConfigurationToken(mAccessPoint.networkId);

mWifiManagerWifiManager 的实例,但是 getWpsNfcConfigurationToken 不是 API 的一部分。通过追踪这个方法,我们可以在这里找到它的提交:Add calls for NFC WSC token creation不幸的是,这没有帮助。 这是我的调查结束的地方。 编辑:我发现了以下调用堆栈:

WifiServiceImpl.java 调用 mWifiStateMachine.syncGetWpsNfcConfigurationToken(netId);

WifiStateMachine.java 调用 mWifiNative.getNfcWpsConfigurationToken(netId);

WifiNative.java终于有了方法

public String getNfcWpsConfigurationToken(int netId) {
返回 doStringCommand("WPS_NFC_CONFIG_TOKEN WPS"+ netId);
}

然后调用

String result = doStringCommandNative(mInterfacePrefix + command);

doStringCommandNative 进行系统调用的地方(在任何地方都找不到代码)。

调查到此结束。

希望有人可以介入并向我展示一种创建 NdefRecord 类型的方法 application/vnd.wfa.wsc 给定 SSID、密码、加密/授权类型。

当然,我已经检查了由 Android 创建的实际 application/vnd.wfa.wsc 记录的字节,但是使用字节手动重新创建此过程似乎可能非常不可靠并且非常乏味。

最佳答案

答案就在Wi-Fi联盟《Wi-Fi简单配置技术规范v2.0.5》(可供下载here)。 Android 使用这种标准格式来配置 WiFi 网络,我错误地认为它是专有的。

首先,我创建了一个 NFC 帮助程序类(恰本地命名为 NFCHelper.java ),它具有构造记录所需的所有字节常量。然后,我创建了一个 hacky 方法来创建所需的两个记录之一。该规范实际上在这里毫无用处,我所做的是检查了一些已通过 Android 操作系统成功配置的标签的有效负载。最后,您需要有一种机制来预先添加“切换选择记录(NFC WKT Hs)”(请参阅​​ WiFi 规范第 90 页)。我相信这条记录“告诉”Android 在以下 token 中注册网络。

如何创建交接记录:

ndefRecords = new NdefRecord[2];
byte[] version = new byte[] { (0x1 << 4) | (0x2)};
ndefRecords[0] = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_HANDOVER_REQUEST, new byte[0], version);
// and then obviously add the record you create with the method below.

创建配置 token 的方法:

private NdefRecord createWifiRecord(String[] data) {
String ssid = data[0];
String password = data[1];
String auth = data[2];
String crypt = data[3];
byte[] authByte = getAuthBytes(auth);
byte[] cryptByte = getCryptBytes(crypt);
byte[] ssidByte = ssid.getBytes();
byte[] passwordByte = password.getBytes();
byte[] ssidLength = {(byte)((int)Math.floor(ssid.length()/256)), (byte)(ssid.length()%256)};
byte[] passwordLength = {(byte)((int)Math.floor(password.length()/256)), (byte)(password.length()%256)};
byte[] cred = {0x00, 0x36};
byte[] idx = {0x00, 0x01, 0x01};
byte[] mac = {0x00, 0x06};
byte[] keypad = {0x00, 0x0B};

byte[] payload = concat(NFCHelper.CREDENTIAL, cred,
NFCHelper.NETWORK_IDX, idx,
NFCHelper.NETWORK_NAME, ssidLength, ssidByte,
NFCHelper.AUTH_TYPE, NFCHelper.AUTH_WPA_PERSONAL, authByte,
NFCHelper.CRYPT_TYPE, NFCHelper.CRYPT_WEP, NFCHelper.CRYPT_AES_TKIP,
NFCHelper.NETWORK_KEY, passwordLength, passwordByte);
// NFCHelper.MAC_ADDRESS, mac);
return NdefRecord.createMime(NFC_TOKEN_MIME_TYPE, payload);
}

许可证和要点 here .您可以在网上的任何地方找到 concat 方法的实现,或者自己编写。

注意:这是一个相当复杂的实现(正如您可能注意到的那样)。我包括了 AES 和 AES/TKIP 字节,因为我在测试它时发现它适用于在 Android 5 下使用不同加密/身份验证方法的各种网络。*请随时更改函数原型(prototype),String 数组与我所做的工作配合得很好。

使用上面第一个代码段中创建的两条记录,然后您应该将其传递到 NdefMessage 并将其写入您的标签。

很快有一天,我将写一篇文章和一个更好/更强大的带有图形和内容的解决方案,所以我会更新这个答案。

关于java - 在 Android 中使用 application/vnd.wfa.wsc 创建 NDEF WiFi 记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36758225/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com