Khả năng Nhận biết Wi-Fi cho phép các thiết bị chạy Android 8.0 (API cấp 26) và cao hơn để khám phá và kết nối trực tiếp với nhau mà không cần bất kỳ loại kết nối giữa chúng. Tính năng Nhận biết Wi-Fi còn được gọi là Nhận biết hàng xóm Kết nối mạng (NAN).
Kết nối mạng Nhận biết Wi-Fi hoạt động bằng cách hình thành các cụm với các thiết bị lân cận, hoặc bằng cách tạo một cụm mới nếu thiết bị là thiết bị đầu tiên trong một khu vực. Chiến dịch này hành vi phân cụm áp dụng cho toàn bộ thiết bị và do Wi-Fi quản lý Dịch vụ hệ thống nâng cao; không có quyền kiểm soát hành vi phân cụm. Các ứng dụng sử dụng API Nhận biết Wi-Fi để giao tiếp với dịch vụ hệ thống Nhận biết Wi-Fi. Dịch vụ này quản lý phần cứng Nhận biết Wi-Fi trên thiết bị.
API Nhận biết Wi-Fi cho phép ứng dụng thực hiện các thao tác sau:
Khám phá các thiết bị khác: API có cơ chế tìm các thiết bị khác các thiết bị ở gần. Quá trình này bắt đầu khi một thiết bị xuất bản một thiết bị hoặc các dịch vụ dễ phát hiện hơn. Sau đó, khi thiết bị đăng ký một hoặc nhiều và đi vào phạm vi Wi-Fi của nhà xuất bản, người đăng ký sẽ nhận được thông báo rằng đã tìm thấy nhà xuất bản phù hợp. Sau người đăng ký phát hiện ra một nhà xuất bản, thì người đăng ký có thể gửi cho họ hoặc thiết lập kết nối mạng với thiết bị được phát hiện. Thiết bị có thể đồng thời là nhà xuất bản và người đăng ký.
Tạo kết nối mạng: Sau khi phát hiện thấy 2 thiết bị khác, họ có thể tạo một kết nối mạng Nhận biết Wi-Fi hai chiều không có điểm truy cập.
Kết nối mạng Nhận biết Wi-Fi hỗ trợ tốc độ công suất cao hơn trong thời gian dài hơn khoảng cách so với Bluetooth kết nối. Những loại kết nối này rất hữu ích đối với các ứng dụng có dung lượng lớn lượng dữ liệu giữa người dùng, chẳng hạn như các ứng dụng chia sẻ ảnh.
Các tính năng nâng cao cho Android 13 (API cấp 33)
Trên các thiết bị chạy Android 13 (API cấp 33) trở lên có hỗ trợ phiên bản tức thì
chế độ giao tiếp, ứng dụng có thể sử dụng
PublishConfig.Builder.setInstantCommunicationModeEnabled()
và
Phương thức SubscribeConfig.Builder.setInstantCommunicationModeEnabled()
để
bật hoặc tắt chế độ liên lạc tức thì cho nhà xuất bản hoặc người đăng ký
trong phiên khám phá. Chế độ liên lạc tức thì giúp tăng tốc độ trao đổi tin nhắn,
khám phá dịch vụ và bất kỳ đường dẫn dữ liệu nào được thiết lập như một phần của nhà xuất bản hoặc người đăng ký
trong phiên khám phá. Để xác định xem thiết bị có hỗ trợ giao tiếp tức thì hay không
hãy sử dụng phương thức isInstantCommunicationModeSupported()
.
Các tính năng nâng cao cho Android 12 (API cấp 31)
Android 12 (API cấp 31) bổ sung một số tính năng nâng cao cho tính năng Nhận biết Wi-Fi:
- Trên thiết bị chạy Android 12 (API cấp 31) trở lên, bạn có thể dùng
onServiceLost()
lệnh gọi lại để được thông báo khi ứng dụng của bạn bị mất một dịch vụ được phát hiện do dịch vụ dừng hoặc di chuyển ra khỏi phạm vi. - Quy trình thiết lập đường dẫn dữ liệu Nhận biết Wi-Fi đã được đơn giản hoá. Các phiên bản cũ đã sử dụng thông báo L2 để cung cấp địa chỉ MAC của trình khởi tạo, độ trễ giới thiệu. Trên các thiết bị chạy Android 12 trở lên, trình trả lời (máy chủ) có thể được định cấu hình để chấp nhận bất kỳ ứng dụng ngang hàng nào—tức là không cần biết trước địa chỉ MAC của trình khởi tạo. Việc này giúp đẩy nhanh tốc độ đường dẫn dữ liệu mang lên và cho phép nhiều liên kết điểm này đến điểm chỉ với một mạng của bạn.
- Ứng dụng chạy trên Android 12 trở lên có thể sử dụng
WifiAwareManager.getAvailableAwareResources()
để biết số lượng đường dẫn dữ liệu hiện có sẵn, xuất bản phiên, và đăng ký các phiên sự kiện. Điều này có thể giúp ứng dụng xác định xem có đủ tài nguyên sẵn có để thực thi chức năng mong muốn của chúng.
Thiết lập ban đầu
Để thiết lập ứng dụng của bạn để sử dụng tính năng khám phá và kết nối mạng Wi-Fi, hãy thực hiện các bước sau:
Yêu cầu các quyền sau đây trong tệp kê khai của ứng dụng:
<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.INTERNET" /> <!-- If your app targets Android 13 (API level 33) or higher, you must declare the NEARBY_WIFI_DEVICES permission. --> <uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" <!-- If your app derives location information from Wi-Fi APIs, don't include the "usesPermissionFlags" attribute. --> android:usesPermissionFlags="neverForLocation" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" <!-- If any feature in your app relies on precise location information, don't include the "maxSdkVersion" attribute. --> android:maxSdkVersion="32" />
Kiểm tra xem thiết bị có hỗ trợ tính năng Nhận biết Wi-Fi hay không bằng
PackageManager
API, như minh hoạ dưới đây:Kotlin
context.packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE)
Java
context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE);
Kiểm tra xem tính năng Nhận biết Wi-Fi hiện có sẵn hay không. Tính năng Nhận biết Wi-Fi có thể tồn tại trên thiết bị, nhưng hiện có thể không có sẵn vì người dùng đã tắt Wi-Fi hoặc Vị trí. Tuỳ thuộc vào khả năng của phần cứng và chương trình cơ sở, một số thiết bị có thể không hỗ trợ tính năng Nhận biết Wi-Fi nếu Wi-Fi Direct, SoftAP hoặc tính năng chia sẻ Internet đang bật sử dụng. Để kiểm tra xem tính năng Nhận biết Wi-Fi hiện có sẵn hay không, hãy gọi
isAvailable()
.Phạm vi cung cấp tính năng Nhận biết Wi-Fi có thể thay đổi bất cứ lúc nào. Ứng dụng của bạn sẽ hãy đăng ký
BroadcastReceiver
để nhậnACTION_WIFI_AWARE_STATE_CHANGED
, Mã này sẽ được gửi bất cứ khi nào tình trạng rảnh/bận thay đổi. Khi ứng dụng của bạn nhận được ý định truyền tin, nó sẽ loại bỏ tất cả các phiên hiện có (giả sử rằng Dịch vụ Nhận biết Wi-Fi đã bị gián đoạn), sau đó hãy kiểm tra trạng thái hiện tại của phạm vi cung cấp và điều chỉnh hành vi của công cụ đó sao cho phù hợp. Ví dụ:Kotlin
val wifiAwareManager = context.getSystemService(Context.WIFI_AWARE_SERVICE) as WifiAwareManager? val filter = IntentFilter(WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED) val myReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { // discard current sessions if (wifiAwareManager?.isAvailable) { ... } else { ... } } } context.registerReceiver(myReceiver, filter)
Java
WifiAwareManager wifiAwareManager = (WifiAwareManager)context.getSystemService(Context.WIFI_AWARE_SERVICE) IntentFilter filter = new IntentFilter(WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED); BroadcastReceiver myReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // discard current sessions if (wifiAwareManager.isAvailable()) { ... } else { ... } } }; context.registerReceiver(myReceiver, filter);
Để biết thêm thông tin, hãy xem phần Chương trình phát sóng.
Nhận một phiên
Để bắt đầu sử dụng tính năng Nhận biết Wi-Fi, ứng dụng của bạn phải có
WifiAwareSession
bằng cách gọi
attach()
Phương thức này
sẽ thực hiện những việc sau:
- Bật phần cứng Nhận biết Wi-Fi.
- Kết nối hoặc tạo thành một cụm Nhận biết Wi-Fi.
- Tạo phiên Nhận biết Wi-Fi có một không gian tên duy nhất hoạt động như một vùng chứa cho tất cả các phiên khám phá được tạo trong đó.
Nếu ứng dụng đính kèm thành công, hệ thống sẽ thực thi
Lệnh gọi lại onAttached()
.
Lệnh gọi lại này cung cấp đối tượng WifiAwareSession
mà ứng dụng của bạn sẽ dùng cho tất cả các hoạt động tiếp theo trong phiên. Ứng dụng có thể sử dụng
để xuất bản một dịch vụ hoặc
đăng ký một dịch vụ.
Ứng dụng của bạn sẽ gọi
attach()
chỉ một lần. Nếu
ứng dụng của bạn gọi attach()
ứng dụng sẽ nhận được một phiên khác nhau cho mỗi cuộc gọi, mỗi lần có
không gian tên riêng của nó. Điều này có thể hữu ích trong các tình huống phức tạp, nhưng
thường có thể tránh được.
Xuất bản dịch vụ
Để giúp người dùng có thể tìm thấy một dịch vụ, hãy gọi
publish()
,
sẽ nhận các tham số sau:
PublishConfig
chỉ định tên của dịch vụ và các thuộc tính cấu hình khác, chẳng hạn như bộ lọc so khớp.DiscoverySessionCallback
chỉ định các hành động cần thực thi khi sự kiện xảy ra, chẳng hạn như khi người đăng ký nhận được một tin nhắn.
Ví dụ:
Kotlin
val config: PublishConfig = PublishConfig.Builder() .setServiceName(AWARE_FILE_SHARE_SERVICE_NAME) .build() awareSession.publish(config, object : DiscoverySessionCallback() { override fun onPublishStarted(session: PublishDiscoverySession) { ... } override fun onMessageReceived(peerHandle: PeerHandle, message: ByteArray) { ... } })
Java
PublishConfig config = new PublishConfig.Builder() .setServiceName(“Aware_File_Share_Service_Name”) .build(); awareSession.publish(config, new DiscoverySessionCallback() { @Override public void onPublishStarted(PublishDiscoverySession session) { ... } @Override public void onMessageReceived(PeerHandle peerHandle, byte[] message) { ... } }, null);
Nếu xuất bản thành công, thì
onPublishStarted()
sẽ được gọi.
Sau khi xuất bản, khi các thiết bị đang chạy ứng dụng phù hợp với người đăng ký sẽ chuyển sang
Phạm vi Wi-Fi của thiết bị phát hành, người đăng ký sẽ khám phá dịch vụ. Thời gian
người đăng ký phát hiện ra một nhà xuất bản, thì nhà xuất bản sẽ không nhận được
thông báo; nhưng nếu người đăng ký gửi thông báo cho nhà xuất bản, thì
nhà xuất bản sẽ nhận được thông báo. Khi điều đó xảy ra,
onMessageReceived()
sẽ được gọi. Bạn có thể sử dụng
Đối số PeerHandle
từ phương thức này đến
gửi tin nhắn lại cho người đăng ký hoặc
tạo kết nối với đó.
Để dừng xuất bản dịch vụ, hãy gọi
DiscoverySession.close()
.
Phiên khám phá được liên kết với cấp độ gốc
WifiAwareSession
. Nếu phiên gốc là
thì các phiên khám phá có liên quan cũng bị đóng. Trong khi loại bỏ
các đối tượng cũng bị đóng, hệ thống không đảm bảo khi nằm ngoài phạm vi
phiên hoạt động bị đóng, vì vậy bạn nên gọi close()
một cách rõ ràng
.
Đăng ký một dịch vụ
Để đăng ký một dịch vụ, hãy gọi
Phương thức subscribe()
,
nhận các tham số sau:
-
SubscribeConfig
chỉ định tên của dịch vụ đăng ký và các thuộc tính cấu hình khác, chẳng hạn như so khớp . DiscoverySessionCallback
chỉ định các hành động cần thực thi khi sự kiện xảy ra, chẳng hạn như khi phát hiện một nhà xuất bản.
Ví dụ:
Kotlin
val config: SubscribeConfig = SubscribeConfig.Builder() .setServiceName(AWARE_FILE_SHARE_SERVICE_NAME) .build() awareSession.subscribe(config, object : DiscoverySessionCallback() { override fun onSubscribeStarted(session: SubscribeDiscoverySession) { ... } override fun onServiceDiscovered( peerHandle: PeerHandle, serviceSpecificInfo: ByteArray, matchFilter: List<ByteArray> ) { ... } }, null)
Java
SubscribeConfig config = new SubscribeConfig.Builder() .setServiceName("Aware_File_Share_Service_Name") .build(); awareSession.subscribe(config, new DiscoverySessionCallback() { @Override public void onSubscribeStarted(SubscribeDiscoverySession session) { ... } @Override public void onServiceDiscovered(PeerHandle peerHandle, byte[] serviceSpecificInfo, List<byte[]> matchFilter) { ... } }, null);
Nếu thao tác đăng ký thành công, hệ thống sẽ gọi
onSubscribeStarted()
trong ứng dụng của bạn. Vì bạn có thể sử dụng
Đối số SubscribeDiscoverySession
trong
lệnh gọi lại để liên lạc với nhà xuất bản sau khi ứng dụng của bạn đã phát hiện ra một nhà xuất bản, bạn
nên lưu tham chiếu này. Bạn có thể cập nhật phiên đăng ký bất kỳ lúc nào bằng cách
đang gọi
updateSubscribe()
trong phiên khám phá.
Tại thời điểm này, gói thuê bao của bạn đang chờ các nhà xuất bản phù hợp tham gia
Phạm vi Wi-Fi. Khi điều này xảy ra, hệ thống sẽ thực thi
onServiceDiscovered()
phương thức gọi lại. Bạn có thể dùng PeerHandle
đối số từ lệnh gọi lại này để gửi tin nhắn hoặc
tạo kết nối với nhà xuất bản đó.
Để ngừng đăng ký một dịch vụ, hãy gọi
DiscoverySession.close()
.
Phiên khám phá được liên kết với cấp độ gốc
WifiAwareSession
. Nếu phiên gốc là
thì các phiên khám phá có liên quan cũng bị đóng. Trong khi loại bỏ
các đối tượng cũng bị đóng, hệ thống không đảm bảo khi nằm ngoài phạm vi
phiên hoạt động bị đóng, vì vậy bạn nên gọi close()
một cách rõ ràng
.
Gửi tin nhắn
Để gửi tin nhắn đến một thiết bị khác, bạn cần có các đối tượng sau:
DiscoverySession
. Đối tượng này cho phép bạn để gọisendMessage()
. Ứng dụng của bạn nhận đượcDiscoverySession
qua một trong hai xuất bản một dịch vụ hoặc đăng ký tối đa.PeerHandle
của thiết bị kia để định tuyến . Ứng dụng của bạn nhận đượcPeerHandle
theo một trong hai cách:- Ứng dụng của bạn sẽ xuất bản một dịch vụ và nhận tin nhắn từ người đăng ký.
Ứng dụng của bạn thu hút được
PeerHandle
trênonMessageReceived()
. - Ứng dụng của bạn đăng ký một dịch vụ. Sau đó, khi phát hiện thấy một kết quả phù hợp
nhà xuất bản, ứng dụng của bạn sẽ nhận được
PeerHandle
từonServiceDiscovered()
.
- Ứng dụng của bạn sẽ xuất bản một dịch vụ và nhận tin nhắn từ người đăng ký.
Ứng dụng của bạn thu hút được
Để gửi tin nhắn, hãy gọi
sendMessage()
. Chiến lược phát hành đĩa đơn
các lệnh gọi lại sau đây có thể xảy ra:
- Khi ứng dụng ngang hàng nhận được tin nhắn, hệ thống sẽ gọi
onMessageSendSucceeded()
lệnh gọi lại trong ứng dụng gửi. - Khi ứng dụng ngang hàng nhận được một tin nhắn, hệ thống sẽ gọi
onMessageReceived()
lệnh gọi lại trong ứng dụng nhận.
Mặc dù PeerHandle
là bắt buộc để giao tiếp với các ứng dụng ngang hàng, nhưng bạn không nên
dựa vào đó làm giá trị nhận dạng lâu dài của các ứng dụng ngang hàng. Giá trị nhận dạng cấp cao hơn có thể là
mà ứng dụng sử dụng-được nhúng vào chính dịch vụ khám phá hoặc trong
các tin nhắn tiếp theo. Bạn có thể nhúng giá trị nhận dạng vào dịch vụ khám phá bằng
thời gian
setMatchFilter()
hoặc
setServiceSpecificInfo()
của PublishConfig
hoặc
SubscribeConfig
. Chiến lược phát hành đĩa đơn
Phương thức setMatchFilter()
ảnh hưởng đến khả năng khám phá, trong khi phương thức
Phương thức setServiceSpecificInfo()
không ảnh hưởng đến khả năng khám phá.
Việc nhúng giá trị nhận dạng vào thông báo ngụ ý việc sửa đổi mảng byte thông báo để bao gồm một giá trị nhận dạng (ví dụ: vài byte đầu tiên).
Tạo kết nối
Tính năng Nhận biết Wi-Fi hỗ trợ kết nối mạng máy khách-máy chủ giữa hai thiết bị Nhận biết Wi-Fi.
Cách thiết lập kết nối máy khách-máy chủ:
Sử dụng tính năng khám phá Wi-Fi để xuất bản một dịch vụ (trên máy chủ) và đăng ký một dịch vụ (trên khách hàng).
Sau khi người đăng ký tìm thấy nhà xuất bản, gửi thông báo từ người đăng ký đến nhà xuất bản.
Bắt đầu một
ServerSocket
trên tài khoản nhà xuất bản thiết bị và đặt hoặc lấy cổng của thiết bị đó:Kotlin
val ss = ServerSocket(0) val port = ss.localPort
Java
ServerSocket ss = new ServerSocket(0); int port = ss.getLocalPort();
Sử dụng
ConnectivityManager
để yêu cầu mạng Nhận biết Wi-Fi trên nhà xuất bản bằngWifiAwareNetworkSpecifier
, chỉ định phiên khám phá vàPeerHandle
người đăng ký, mà bạn nhận được từ tin nhắn mà người đăng ký truyền đi:Kotlin
val networkSpecifier = WifiAwareNetworkSpecifier.Builder(discoverySession, peerHandle) .setPskPassphrase("somePassword") .setPort(port) .build() val myNetworkRequest = NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE) .setNetworkSpecifier(networkSpecifier) .build() val callback = object : ConnectivityManager.NetworkCallback() { override fun onAvailable(network: Network) { ... } override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) { ... } override fun onLost(network: Network) { ... } } connMgr.requestNetwork(myNetworkRequest, callback);
Java
NetworkSpecifier networkSpecifier = new WifiAwareNetworkSpecifier.Builder(discoverySession, peerHandle) .setPskPassphrase("somePassword") .setPort(port) .build(); NetworkRequest myNetworkRequest = new NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE) .setNetworkSpecifier(networkSpecifier) .build(); ConnectivityManager.NetworkCallback callback = new ConnectivityManager.NetworkCallback() { @Override public void onAvailable(Network network) { ... } @Override public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) { ... } @Override public void onLost(Network network) { ... } }; ConnectivityManager connMgr.requestNetwork(myNetworkRequest, callback);
Sau khi nhà xuất bản yêu cầu một mạng, mạng đó sẽ gửi tin nhắn cho người đăng ký.
Sau khi người đăng ký nhận được tin nhắn từ nhà xuất bản, hãy yêu cầu Wi-Fi Mạng nhận biết trên người đăng ký sử dụng cùng phương thức như trên nhà xuất bản. Hành động không chỉ định cổng khi tạo
NetworkSpecifier
. Chiến lược phát hành đĩa đơn phương thức gọi lại thích hợp được gọi khi kết nối mạng có sẵn, đã thay đổi hoặc bị mất.Sau khi phương thức
onAvailable()
được gọi trên người đăng ký, Đối tượngNetwork
khả dụng với Bạn có thể mở mộtSocket
để giao tiếp bằngServerSocket
trên nhà xuất bản, nhưng bạn cần biết Cổng và địa chỉ IPv6 củaServerSocket
. Bạn lấy những gợi ý này trên Đối tượngNetworkCapabilities
được cung cấp trong lệnh gọi lạionCapabilitiesChanged()
:Kotlin
val peerAwareInfo = networkCapabilities.transportInfo as WifiAwareNetworkInfo val peerIpv6 = peerAwareInfo.peerIpv6Addr val peerPort = peerAwareInfo.port ... val socket = network.getSocketFactory().createSocket(peerIpv6, peerPort)
Java
WifiAwareNetworkInfo peerAwareInfo = (WifiAwareNetworkInfo) networkCapabilities.getTransportInfo(); Inet6Address peerIpv6 = peerAwareInfo.getPeerIpv6Addr(); int peerPort = peerAwareInfo.getPort(); ... Socket socket = network.getSocketFactory().createSocket(peerIpv6, peerPort);
Khi bạn hoàn tất việc kết nối mạng, hãy gọi
unregisterNetworkCallback()
.
Đa dạng người dùng ngang hàng và khả năng khám phá theo vị trí
Một thiết bị có vị trí Tin nhắn theo thời gian thực (RTT) của Wi-Fi có thể trực tiếp đo lường khoảng cách tới các ứng dụng ngang hàng và sử dụng thông tin này để ràng buộc khám phá dịch vụ Nhận biết Wi-Fi.
API RTT của Wi-Fi cho phép kết nối trực tiếp với mạng ngang hàng nhận biết Wi-Fi bằng Địa chỉ MAC hoặc PeerHandle của địa chỉ đó.
Bạn có thể hạn chế khả năng khám phá Wi-Fi để chỉ khám phá các dịch vụ trong một
khoanh vùng địa lý cụ thể. Ví dụ: bạn có thể thiết lập khoanh vùng địa lý cho phép khám phá
của một thiết bị đang xuất bản một dịch vụ "Aware_File_Share_Service_Name"
không
gần hơn 3 mét (được quy định bằng 3.000 mm) và không quá 10 mét
(được chỉ định bằng 10.000 mm).
Để bật tính năng khoanh vùng địa lý, cả nhà xuất bản và người đăng ký đều phải thực hiện hành động:
Nhà xuất bản phải bật tuỳ chọn trên dịch vụ đã xuất bản bằng cách sử dụng setRangingEnabled(true).
Nếu nhà xuất bản không cho phép sắp xếp khoảng không quảng cáo, thì mọi quy tắc ràng buộc về khoanh vùng địa lý mà người đăng ký chỉ định sẽ bị bỏ qua và quá trình khám phá diễn ra bình thường, không quan tâm đến khoảng cách.
Người đăng ký phải chỉ định khoanh vùng địa lý bằng cách sử dụng một số tổ hợp setMinDistanceMm và setMaxDistanceMm.
Đối với một trong hai giá trị, khoảng cách không xác định nghĩa là không có giới hạn. Chỉ chỉ định khoảng cách tối đa cho biết khoảng cách tối thiểu bằng 0. Chỉ chỉ định khoảng cách tối thiểu nghĩa là không có giới hạn tối đa.
Khi phát hiện một dịch vụ ngang hàng trong khoanh vùng địa lý, onServiceđược phát hiện trong phạm vi lệnh gọi lại được kích hoạt để cung cấp khoảng cách đo được đến ứng dụng ngang hàng. Chiến lược phát hành đĩa đơn Sau đó, API RTT của Wi-Fi trực tiếp có thể được gọi khi cần thiết để đo khoảng cách ở những lần sau.