Bạn có thể sử dụng chức năng vị trí Wi-Fi do API Tin nhắn theo thời gian thực (RTT) của Wi-Fi để đo khoảng cách đến các điểm truy cập Wi-Fi ngang hàng và các điểm truy cập Wi-Fi hỗ trợ RTT lân cận Thiết bị nhận biết Wi-Fi.
Nếu bạn đo khoảng cách đến ba điểm truy cập trở lên, bạn có thể sử dụng thuật toán đa phương để ước tính vị trí thiết bị phù hợp nhất với thiết bị đo lường. Kết quả thường chính xác trong vòng 1-2 mét.
Với độ chính xác này, bạn có thể phát triển các dịch vụ dựa trên vị trí chi tiết, chẳng hạn như như điều hướng trong nhà, điều khiển bằng giọng nói riêng biệt (ví dụ: "Bật cái này nhẹ") và thông tin dựa trên vị trí (ví dụ: "Có ưu đãi đặc biệt không" cho sản phẩm này không?").
Thiết bị yêu cầu không cần kết nối với các điểm truy cập để đo khoảng cách bằng tính năng Tin nhắn theo thời gian thực (RTT) của Wi-Fi. Để duy trì quyền riêng tư, chỉ thiết bị yêu cầu mới có thể để xác định khoảng cách đến điểm truy cập; các điểm truy cập này không có thông tin này. Không giới hạn được thao tác Tin nhắn theo thời gian thực (RTT) của Wi-Fi cho các ứng dụng trên nền trước, nhưng được điều tiết đối với các ứng dụng nền.
Tin nhắn theo thời gian thực (RTT) của Wi-Fi và các chức năng Đo lường thời gian tinh tế (FTM) có liên quan theo tiêu chuẩn IEEE 802.11-2016. Tin nhắn theo thời gian thực (RTT) của Wi-Fi cần có thời gian chính xác phép đo được cung cấp bởi FTM vì công cụ này tính khoảng cách giữa hai thiết bị bằng cách đo thời gian một gói thực hiện một chuyến đi khứ hồi giữa rồi nhân thời gian đó với tốc độ ánh sáng.
Android 15 (API cấp 35) ra mắt tính năng hỗ trợ cho chuẩn không kích hoạt IEEE 802.11az (NTB).
Sự khác biệt về cách triển khai dựa trên phiên bản Android
Tin nhắn theo thời gian thực (RTT) của Wi-Fi đã được ra mắt trong Android 9 (API cấp 28). Khi sử dụng giao thức này để xác định vị trí của một thiết bị bằng tính năng đa phương với các thiết bị đang chạy Android 9, bạn cần có quyền truy cập vào các vị trí của điểm truy cập (AP) được xác định trước trong ứng dụng của bạn. Bạn là người quyết định cách lưu trữ và truy xuất dữ liệu này.
Trên các thiết bị chạy Android 10 (API cấp 29) trở lên, dữ liệu vị trí của điểm truy cập có thể được
được biểu thị dưới dạng
ResponderLocation
bao gồm vĩ độ, kinh độ và độ cao. Đối với các AP RTT Wi-Fi
hỗ trợ Thông tin cấu hình vị trí/Báo cáo công dân vị trí (dữ liệu LCI/LCR),
giao thức sẽ trả về đối tượng ResponderLocation
trong quá trình
quy trình khác nhau.
Tính năng này cho phép ứng dụng truy vấn các AP để trực tiếp hỏi vị trí của các AP đó thay vì phải lưu trữ trước thông tin. Nhờ vậy, ứng dụng của bạn có thể tìm AP và xác định vị trí của chúng ngay cả khi trước đó AP chưa từng biết đến, chẳng hạn như khi người dùng bước vào một toà nhà mới.
Hỗ trợ phạm vi NTB của IEEE 802.11az hiện có trên các thiết bị chạy Android 15
(API cấp 35) trở lên. Điều đó có nghĩa là nếu thiết bị hỗ trợ IEEE 802.11az
Chế độ trả lời NTB (biểu thị bằng
WifiRttManager.CHARACTERISTICS_KEY_BOOLEAN_STA_RESPONDER
),
ứng dụng của bạn có thể tìm thấy cả các AP có hỗ trợ IEEE 802.11mc và IEEE 802.11az với một AP
dải ô yêu cầu. API RangingResult
đã được mở rộng để cung cấp thông tin
về giá trị nhỏ nhất và lớn nhất có thể dùng cho khoảng thời gian giữa
các phép đo khác nhau, để khoảng thời gian chính xác trong tầm kiểm soát ứng dụng của bạn.
Yêu cầu
- Phần cứng của thiết bị thực hiện yêu cầu phạm vi phải triển khai 802.11-2016 FTM tiêu chuẩn hoặc tiêu chuẩn 802.11az (phạm vi không kích hoạt).
- Thiết bị đưa ra yêu cầu về khoảng không phải chạy Android 9 (cấp độ API) 28) trở lên. Phạm vi dựa trên không kích hoạt IEEE 802.11az được bật trên các thiết bị chạy Android 15 (API cấp 35) trở lên.
- Thiết bị thực hiện yêu cầu phạm vi phải được bật dịch vụ vị trí và bật tính năng quét tìm Wi-Fi (trong Cài đặt > Vị trí).
- Nếu ứng dụng đang thực hiện mục tiêu yêu cầu phạm vi
Android 13 (API cấp 33) trở lên, ứng dụng này phải có
NEARBY_WIFI_DEVICES
quyền. Nếu một ứng dụng như vậy nhắm mục tiêu đến một phiên bản Android cũ hơn, thì ứng dụng đó phải cóACCESS_FINE_LOCATION
thay thế. - Ứng dụng phải truy vấn phạm vi điểm truy cập trong khi ứng dụng đang hiển thị hoặc ở một dịch vụ trên nền trước. Ứng dụng không thể truy cập vào thông tin vị trí trên màu nền.
- Điểm truy cập phải triển khai theo tiêu chuẩn FTM IEEE 802.11-2016 hoặc IEEE Tiêu chuẩn 802.11az (phạm vi dựa trên không kích hoạt).
Thiết lập
Để thiết lập ứng dụng dùng tính năng Tin nhắn theo thời gian thực (RTT) của Wi-Fi, hãy thực hiện các bước sau.
1. Yêu cầu cấp quyền
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" />
<!-- 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" />
Các quyền NEARBY_WIFI_DEVICES
và ACCESS_FINE_LOCATION
là nguy hiểm
nên bạn cần yêu cầu các quyền đó trong thời gian chạy mỗi khi người dùng muốn
thực hiện thao tác quét RTT. Ứng dụng của bạn sẽ cần yêu cầu thông tin
nếu quyền chưa được cấp. Thông tin khác
về quyền khi bắt đầu chạy, hãy xem
Yêu cầu quyền cho ứng dụng.
2. Kiểm tra xem thiết bị có hỗ trợ tin nhắn theo thời gian thực (RTT) của Wi-Fi hay không
Để kiểm tra xem thiết bị có hỗ trợ RTT qua Wi-Fi hay không, hãy sử dụng
API PackageManager
:
Kotlin
context.packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_RTT)
Java
context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_RTT);
3. Kiểm tra xem có dùng được RTT Wi-Fi hay không
Tin nhắn theo thời gian thực (RTT) của Wi-Fi có thể tồn tại trên thiết bị, nhưng có thể không hoạt động do người dùng
đã tắt Wi-Fi. Tuỳ thuộc vào khả năng của phần cứng và chương trình cơ sở, một số
các thiết bị có thể không hỗ trợ RTT qua Wi-Fi nếu bạn đang sử dụng SoftAP hoặc tính năng chia sẻ Internet. Để kiểm tra
liệu có dùng được RTT qua Wi-Fi hay không, hãy gọi
isAvailable()
.
Khả năng sử dụng Tin nhắn theo thời gian thực (RTT) qua Wi-Fi có thể thay đổi bất cứ lúc nào. Ứng dụng của bạn cần đăng ký một
BroadcastReceiver
để nhận
ACTION_WIFI_RTT_STATE_CHANGED
!
nội dung này được gửi khi tình trạng rảnh/bận thay đổi. Khi ứng dụng của bạn nhận được thông báo truyền tin
ý định, ứng dụng sẽ kiểm tra trạng thái sẵn có hiện tại và điều chỉnh
cho phù hợp.
Ví dụ:
Kotlin
val filter = IntentFilter(WifiRttManager.ACTION_WIFI_RTT_STATE_CHANGED) val myReceiver = object: BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { if (wifiRttManager.isAvailable) { … } else { … } } } context.registerReceiver(myReceiver, filter)
Java
IntentFilter filter = new IntentFilter(WifiRttManager.ACTION_WIFI_RTT_STATE_CHANGED); BroadcastReceiver myReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (wifiRttManager.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.
Tạo yêu cầu phạm vi
Yêu cầu phạm vi
(RangingRequest
) đã được tạo
bằng cách chỉ định một danh sách các AP hoặc các mạng ngang hàng nhận biết Wi-Fi mà phạm vi
được yêu cầu. Bạn có thể chỉ định nhiều điểm truy cập hoặc thiết bị ngang hàng trong tính năng Nhận biết Wi-Fi trong một
yêu cầu một phạm vi; đo và trả về khoảng cách đến tất cả các thiết bị.
Ví dụ: một yêu cầu có thể sử dụng phương thức
addAccessPoint()
để chỉ định một điểm truy cập cần đo khoảng cách:
Kotlin
val req: RangingRequest = RangingRequest.Builder().run { addAccessPoint(ap1ScanResult) addAccessPoint(ap2ScanResult) build() }
Java
RangingRequest.Builder builder = new RangingRequest.Builder(); builder.addAccessPoint(ap1ScanResult); builder.addAccessPoint(ap2ScanResult); RangingRequest req = builder.build();
Điểm truy cập được xác định bằng
ScanResult
có thể là
có được bằng cách gọi
WifiManager.getScanResults()
.
Bạn có thể sử dụng
addAccessPoints(List<ScanResult>)
để thêm nhiều điểm truy cập trong một lô.
Các đối tượng ScanResult
có thể chứa cả IEEE 802.11mc (is80211mcResponder()
) và
Hỗ trợ phạm vi dựa trên không kích hoạt IEEE 802.11az (is80211azNtbResponder()
)
Điểm truy cập. Các thiết bị hỗ trợ chuẩn NTB IEEE 802.11az thực hiện theo chuẩn 802.11mc hoặc
802.11az thay đổi tuỳ thuộc vào khả năng của AP, mặc định là 802.11az khi
AP hỗ trợ cả hai. Các thiết bị không hỗ trợ IEEE 802.11az sẽ thực hiện tất cả
sử dụng giao thức IEEE 802.11mc.
Tương tự, yêu cầu phạm vi có thể thêm ứng dụng ngang hàng Nhận biết Wi-Fi bằng MAC
hoặc PeerHandle
của địa chỉ đó, sử dụng
thời gian
addWifiAwarePeer(MacAddress peer)
và addWifiAwarePeer(PeerHandle peer)
tương ứng. Để biết thêm thông tin về cách khám phá các thiết bị ngang hàng hỗ trợ tính năng Nhận biết Wi-Fi,
hãy xem tài liệu về tính năng Nhận biết Wi-Fi.
Yêu cầu phạm vi
Một ứng dụng đưa ra yêu cầu theo khoảng bằng cách sử dụng
WifiRttManager.startRanging()
và cung cấp các thành phần sau: a
RangingRequest
để chỉ định
hoạt động, Executor
để chỉ định
ngữ cảnh gọi lại và
RangingResultCallback
để nhận kết quả.
Ví dụ:
Kotlin
val mgr = context.getSystemService(Context.WIFI_RTT_RANGING_SERVICE) as WifiRttManager val request: RangingRequest = myRequest mgr.startRanging(request, executor, object : RangingResultCallback() { override fun onRangingResults(results: List<RangingResult>) { … } override fun onRangingFailure(code: Int) { … } })
Java
WifiRttManager mgr = (WifiRttManager) Context.getSystemService(Context.WIFI_RTT_RANGING_SERVICE); RangingRequest request ...; mgr.startRanging(request, executor, new RangingResultCallback() { @Override public void onRangingFailure(int code) { … } @Override public void onRangingResults(List<RangingResult> results) { … } });
Thao tác phạm vi được thực hiện không đồng bộ và kết quả sắp xếp
đã trả về trong một trong các lệnh gọi lại của
RangingResultCallback
:
- Nếu toàn bộ thao tác phạm vi không thành công, giá trị
onRangingFailure
lệnh gọi lại được kích hoạt bằng mã trạng thái được mô tả trongRangingResultCallback
. Lỗi này có thể xảy ra nếu dịch vụ không thể thực thi thao tác dải vào thời điểm đó--ví dụ: do Wi-Fi bị tắt, vì ứng dụng đã yêu cầu quá nhiều hoạt động khác nhau và bị điều tiết hoặc do có vấn đề về quyền. - Khi thao tác phạm vi hoàn tất,
onRangingResults
được kích hoạt với một danh sách kết quả khớp với danh sách các yêu cầu—một kết quả cho mỗi yêu cầu. Thứ tự của các kết quả không nhất thiết phải khớp với thứ tự của các yêu cầu. Lưu ý rằng phép toán phạm vi có thể nhưng mỗi kết quả vẫn có thể cho thấy một lỗi của đo lường.
Diễn giải phạm vi kết quả
Mỗi kết quả được trả về bởi
onRangingResults
lệnh gọi lại được chỉ định bởi RangingResult
. Đối với mỗi yêu cầu, hãy làm như sau.
1. Xác định yêu cầu
Xác định yêu cầu dựa trên thông tin được cung cấp khi tạo
RangingRequest
:
địa chỉ MAC được cung cấp trong ScanResult
thường xác định quyền truy cập
điểm. Địa chỉ MAC có thể lấy từ kết quả phạm vi bằng cách sử dụng
getMacAddress()
.
Danh sách các kết quả trong phạm vi có thể theo thứ tự khác với các kết quả ngang hàng (quyền truy cập điểm) được chỉ định trong yêu cầu phạm vi, vì vậy bạn nên sử dụng địa chỉ MAC để xác định ứng dụng ngang hàng chứ không phải thứ tự kết quả.
2. Xác định xem mỗi phép đo có thành công hay không
Để xác định xem một phép đo có thành công hay không, hãy sử dụng
getStatus()
. Bất kỳ giá trị nào khác với
STATUS_SUCCESS
chỉ báo lỗi. Nếu không thành công, thì tất cả các trường khác của kết quả này
(ngoại trừ thông tin nhận dạng yêu cầu ở trên) không hợp lệ và thông số tương ứng
Phương thức get*
sẽ không thành công với
IllegalStateException
ngoại lệ.
3. Nhận kết quả cho mỗi lần đo lường thành công
Đối với mỗi lần đo lường thành công (RangingResult
), bạn có thể truy xuất kết quả
bằng các phương thức get
tương ứng:
Khoảng cách, tính bằng mm và độ lệch chuẩn của phép đo:
RSSI của các gói dùng để đo lường:
Thời gian tính bằng mili giây khi đo (biểu thị thời gian) kể từ khi khởi động):
Số lần đo đã thử và số lần đo đã thành công (và dựa trên cơ sở để đo khoảng cách):
Thời gian tối thiểu và tối đa mà thiết bị khách phải đợi trong khoảng từ 11 az NTB đo lường:
getMinTimeBetweenNtbMeasurementsMicros()
vàgetMaxTimeBetweenNtbMeasurementsMicros()
trả về thời gian tối thiểu và tối đa. Nếu phép đo phạm vi tiếp theo là được yêu cầu trước khi thời gian tối thiểu đã trôi qua thì API sẽ trả về kết quả trong phạm vi đã lưu vào bộ nhớ đệm. Nếu phạm vi tiếp theo được yêu cầu sau thời gian tối đa đã trôi qua thì API chấm dứt sự kiện không kích hoạt sắp xếp phiên hoạt động và thương lượng một phiên hoạt động mới với nhóm phản hồi đài phát thanh. Bạn nên tránh yêu cầu một phiên khoảng thời gian mới, vì nó thêm cho khoảng thời gian đo lường. Để khai thác tối đa chuẩn 802.11az hiệu quả dựa trên phạm vi không kích hoạt, kích hoạt yêu cầu phạm vi tiếp theo từ thời gian đo tối thiểu đến tối đa nêu trênRangingResult
đo lường.Trường hợp lặp lại của Trường huấn luyện dài (LTF) mà người trả lời và người khởi tạo được sử dụng trong phần mở đầu cho kết quả NTB của IEEE 802.11az:
Số luồng truyền và nhận luồng thời gian không gian (STS) mà trình khởi tạo trạm được sử dụng cho kết quả NTB của IEEE 802.11az:
Các thiết bị Android hỗ trợ Wi-Fi-RTT
Các bảng sau đây liệt kê một số điện thoại, điểm truy cập và thiết bị bán lẻ, kho hàng và trung tâm phân phối có hỗ trợ Wi-Fi-RTT. Các chỉ số này chưa hoàn chỉnh. Bạn nên liên hệ với chúng tôi để liệt kê các sản phẩm hỗ trợ tính năng RTT tại đây.
Điểm truy cập
Nhà sản xuất và kiểu máy | Ngày hỗ trợ |
---|---|
Nest Wifi Pro (Wi-Fi 6E) | Có thể làm |
Compulab WILD AP | Có thể làm |
Wi-Fi của Google | Có thể làm |
Bộ định tuyến Wi-Fi của Google Nest | Có thể làm |
Điểm phát Wi-Fi Google Nest | Có thể làm |
Aruba AP-635 | Có thể làm |
Cisco 9130 | Có thể làm |
Cisco 9136 | Có thể làm |
Cisco 9166 | Có thể làm |
Cisco 9164 | Có thể làm |
Aruba AP-505 | Có thể làm |
Aruba AP-515 | Có thể làm |
Aruba AP-575 | Có thể làm |
Aruba AP-518 | Có thể làm |
Aruba AP-505H | Có thể làm |
Aruba AP-565 | Có thể làm |
Aruba AP-535 | Có thể làm |
Điện thoại
Nhà sản xuất và kiểu máy | Phiên bản Android |
---|---|
Pixel 6 | 9 trở lên |
Pixel 6 Pro | 9 trở lên |
Pixel 5 | 9 trở lên |
Pixel 5a | 9 trở lên |
Pixel 5a (5G) | 9 trở lên |
Xiaomi Mi 10 Pro | 9 trở lên |
Xiaomi Mi 10 | 9 trở lên |
Xiaomi Redmi Mi 9T Pro | 9 trở lên |
Xiaomi Mi 9T | 9 trở lên |
Xiaomi Mi 9 | 9 trở lên |
Xiaomi Mi Note 10 | 9 trở lên |
Xiaomi Mi Note 10 Lite | 9 trở lên |
Xiaomi Redmi Note 9S | 9 trở lên |
Xiaomi Redmi Note 9 Pro | 9 trở lên |
Xiaomi Redmi Note 8T | 9 trở lên |
Xiaomi Redmi Note 8 | 9 trở lên |
Xiaomi Redmi K30 Pro | 9 trở lên |
Xiaomi Redmi K20 Pro | 9 trở lên |
Xiaomi Redmi K20 | 9 trở lên |
Xiaomi Redmi Note 5 Pro | 9 trở lên |
Xiaomi Mi CC9 Pro | 9 trở lên |
LG G8X ThinQ | 9 trở lên |
LG V50S ThinQ | 9 trở lên |
LG V60 ThinQ | 9 trở lên |
LG V30 | 9 trở lên |
Samsung Galaxy Note 10+ 5G | 9 trở lên |
Samsung Galaxy S20+ 5G | 9 trở lên |
Samsung Galaxy S20 trở lên | 9 trở lên |
Samsung Galaxy S20 5G | 9 trở lên |
Samsung Galaxy S20 Ultra 5G | 9 trở lên |
Samsung Galaxy S20 | 9 trở lên |
Samsung Galaxy Note 10 trở lên | 9 trở lên |
Samsung Galaxy Note 10 5G | 9 trở lên |
Samsung Galaxy Note 10 | 9 trở lên |
Samsung A9 Pro | 9 trở lên |
Google Pixel 4 XL | 9 trở lên |
Google Pixel 4 | 9 trở lên |
Google Pixel 4a | 9 trở lên |
Google Pixel 3 XL | 9 trở lên |
Google Pixel 3 | 9 trở lên |
Google Pixel 3a XL | 9 trở lên |
Google Pixel 3a | 9 trở lên |
Google Pixel 2 XL | 9 trở lên |
Google Pixel 2 | 9 trở lên |
Google Pixel 1 XL | 9 trở lên |
Google Pixel 1 | 9 trở lên |
Poco X2 | 9 trở lên |
Sharp Aquos R3 SH-04L | 9 trở lên |
Thiết bị cho trung tâm bán lẻ, kho hàng và phân phối
Nhà sản xuất và kiểu máy | Phiên bản Android |
---|---|
Ngựa vằn PS20 | 10.0 trở lên |
Ngựa vằn TC52/TC52HC | 10.0 trở lên |
Ngựa vằn TC57 | 10.0 trở lên |
Ngựa vằn TC72 | 10.0 trở lên |
Ngựa vằn TC77 | 10.0 trở lên |
Ngựa vằn MC93 | 10.0 trở lên |
Ngựa vằn TC8300 | 10.0 trở lên |
Ngựa vằn VC8300 | 10.0 trở lên |
Ngựa vằn EC30 | 10.0 trở lên |
Ngựa vằn ET51 | 10.0 trở lên |
Ngựa vằn ET56 | 10.0 trở lên |
Ngựa vằn L10 | 10.0 trở lên |
Ngựa vằn CC600/CC6000 | 10.0 trở lên |
Ngựa vằn MC3300x | 10.0 trở lên |
Ngựa vằn MC330x | 10.0 trở lên |
Ngựa vằn TC52x | 10.0 trở lên |
Ngựa vằn TC57x | 10.0 trở lên |
Zebra EC50 (LAN và HC) | 10.0 trở lên |
Ngựa vằn EC55 (WAN) | 10.0 trở lên |
Ngựa vằn WT6300 | 10.0 trở lên |
Skorpio X5 | 10.0 trở lên |