Anda dapat menggunakan fungsi lokasi Wi-Fi yang disediakan oleh Wi-Fi RTT (Round-Trip-Time) API untuk mengukur jarak ke titik akses Wi-Fi yang mendukung RTT di sekitar dan perangkat Wi-Fi Aware peer.
Jika Anda mengukur jarak ke tiga titik akses atau lebih, Anda dapat menggunakan algoritme multilaterasi untuk memperkirakan posisi perangkat yang paling sesuai dengan pengukuran tersebut. Hasilnya biasanya akurat dalam 1-2 meter.
Dengan keakuratan ini, Anda dapat mengembangkan layanan berdasarkan lokasi yang sangat akurat, seperti navigasi dalam ruangan, kontrol suara yang diperjelas (misalnya, "Nyalakan lampu ini"), dan informasi berdasarkan lokasi (misalnya, "Apakah ada penawaran spesial untuk produk ini?").
Perangkat yang melakukan permintaan tidak perlu terhubung ke titik akses untuk mengukur jarak dengan Wi-Fi RTT. Untuk menjaga privasi, hanya perangkat yang meminta yang dapat menentukan jarak ke titik akses; titik akses tidak memiliki informasi ini. Operasi Wi-Fi RTT tidak terbatas untuk aplikasi latar depan tetapi dibatasi untuk aplikasi latar belakang.
RTT Wi-Fi dan kemampuan Fine-Time-Measurement (FTM) terkait ditentukan oleh standar IEEE 802.11-2016. Wi-Fi RTT memerlukan pengukuran waktu yang tepat yang disediakan oleh FTM karena menghitung jarak antara dua perangkat dengan mengukur waktu yang dibutuhkan paket untuk melakukan perjalanan bolak-balik antara perangkat dan mengalikan waktu itu dengan kecepatan cahaya.
Android 15 (level API 35) memperkenalkan dukungan untuk pengukuran jarak berbasis non-pemicu (NTB) IEEE 802.11az.
Perbedaan implementasi berdasarkan versi Android
Wi-Fi RTT diperkenalkan di Android 9 (API level 28). Saat menggunakan protokol ini untuk menentukan posisi perangkat menggunakan multilaterasi dengan perangkat yang menjalankan Android 9, Anda harus memiliki akses ke data lokasi titik akses (AP) yang telah ditentukan sebelumnya di aplikasi. Anda bebas menentukan cara menyimpan dan mengambil data ini.
Pada perangkat yang menjalankan Android 10 (level API 29) dan yang lebih tinggi, data lokasi AP dapat
direpresentasikan sebagai objek ResponderLocation, yang mencakup lintang, bujur,
dan ketinggian. Untuk AP RTT Wi-Fi yang mendukung Informasi Konfigurasi Lokasi
atau Laporan Sipil Lokasi (data LCI atau LCR), protokol akan menampilkan
objek ResponderLocation selama proses pengukuran jarak.
Aplikasi dapat mengkueri AP secara langsung untuk mengetahui posisinya, bukan menyimpannya terlebih dahulu. Aplikasi Anda dapat menemukan AP dan menentukan posisinya meskipun sebelumnya tidak diketahui, seperti saat pengguna memasuki bangunan baru.
Dukungan pengukuran jarak NTB IEEE 802.11az tersedia di perangkat yang menjalankan Android 15
(level API 35) dan yang lebih tinggi. Artinya, jika perangkat mendukung mode inisiator NTB IEEE 802.11az (ditunjukkan dengan WifiRttManager.CHARACTERISTICS_KEY_BOOLEAN_NTB_INITIATOR), aplikasi Anda dapat menemukan AP yang mendukung IEEE 802.11mc dan IEEE 802.11az dengan satu permintaan rentang.
RangingResult API telah diperluas untuk memberikan informasi tentang
nilai minimum dan maksimum yang dapat digunakan untuk interval antara pengukuran
jarak, sehingga interval yang tepat berada dalam kontrol aplikasi Anda.
Persyaratan
- Hardware perangkat yang membuat permintaan pengukuran jarak harus menerapkan standar FTM 802.11-2016 atau standar 802.11az (pengukuran jarak berbasis non-pemicu).
- Perangkat yang membuat permintaan ranging harus menjalankan Android 9 (API level 28) atau yang lebih baru. Pengukuran jarak berbasis non-pemicu IEEE 802.11az diaktifkan di perangkat yang menjalankan Android 15 (level API 35) dan yang lebih tinggi.
- Perangkat yang membuat permintaan ranging harus mengaktifkan layanan lokasi dan pemindaian Wi-Fi (dalam Setelan > Lokasi).
- Jika aplikasi yang membuat permintaan pengukuran jarak menargetkan
Android 13 (API level 33) atau yang lebih tinggi, aplikasi tersebut harus memiliki izin
NEARBY_WIFI_DEVICES. Jika aplikasi tersebut menargetkan versi Android yang lebih rendah, aplikasi harus memiliki izinACCESS_FINE_LOCATION. - Aplikasi harus meminta rentang titik akses saat aplikasi terlihat atau ada di layanan latar depan. Aplikasi tidak dapat mengakses informasi lokasi dari latar belakang.
- Titik akses harus menerapkan standar FTM IEEE 802.11-2016 atau standar IEEE 802.11az (pengukuran jarak berbasis non-pemicu).
Penyiapan
Untuk menyiapkan aplikasi Anda menggunakan Wi-Fi RTT, lakukan langkah-langkah berikut.
1. Minta izin
Minta izin berikut dalam manifes aplikasi Anda:
<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" />
Izin NEARBY_WIFI_DEVICES dan ACCESS_FINE_LOCATION adalah izin berbahaya, jadi Anda harus memintanya saat runtime setiap kali pengguna ingin
melakukan operasi pemindaian RTT. Aplikasi Anda harus meminta izin pengguna jika izin belum diberikan. Untuk mengetahui informasi selengkapnya
tentang izin runtime, lihat Meminta Izin Aplikasi.
2. Periksa apakah perangkat mendukung Wi-Fi RTT
Untuk memeriksa apakah perangkat mendukung Wi-Fi RTT, gunakan PackageManager API:
Kotlin
context.packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_RTT)
Java
context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_RTT);
3. Periksa apakah Wi-Fi RTT tersedia
RTT Wi-Fi mungkin ada di perangkat, tetapi mungkin tidak tersedia karena pengguna
telah menonaktifkan Wi-Fi. Bergantung pada kemampuan hardware dan firmware-nya, beberapa
perangkat mungkin tidak mendukung Wi-Fi RTT jika SoftAP atau tethering sedang digunakan. Untuk memeriksa
apakah Wi-Fi RTT tersedia, panggil isAvailable().
Ketersediaan Wi-Fi RTT dapat berubah kapan saja. Aplikasi Anda harus mendaftarkan
BroadcastReceiver untuk menerima ACTION_WIFI_RTT_STATE_CHANGED, yang
dikirim saat ketersediaan berubah. Saat menerima intent siaran, aplikasi
harus memeriksa status ketersediaan saat ini dan menyesuaikan perilakunya.
Contoh:
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);
Untuk informasi selengkapnya, lihat Siaran.
Membuat permintaan ranging
Permintaan pengukuran jarak (RangingRequest) dibuat dengan menentukan daftar AP atau
peer Wi-Fi Aware yang jaraknya diminta. Beberapa titik akses atau peer Wi-Fi
Aware dapat ditentukan dalam satu permintaan pengukuran; jarak ke semua
perangkat diukur dan ditampilkan.
Misalnya, permintaan dapat menggunakan metode addAccessPoint() untuk menentukan
titik akses yang akan diukur jaraknya:
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();
Titik akses diidentifikasi oleh objek ScanResult, yang dapat
diperoleh dengan memanggil WifiManager.getScanResults(). Anda dapat menggunakan
addAccessPoints(List<ScanResult>) untuk menambahkan beberapa titik akses dalam satu batch.
Objek ScanResult dapat berisi AP yang didukung IEEE 802.11mc (is80211mcResponder()) dan
pengukuran jarak berbasis non-pemicu IEEE 802.11az (is80211azNtbResponder()). Perangkat yang mendukung pengukuran jarak NTB IEEE 802.11az melakukan pengukuran jarak 802.11mc atau
802.11az, bergantung pada kemampuan AP, dan secara default menggunakan 802.11az jika
AP mendukung keduanya. Perangkat yang tidak mendukung IEEE 802.11az melakukan semua
pengukuran jarak menggunakan protokol IEEE 802.11mc.
Demikian pula, permintaan pengukuran jarak dapat menambahkan peer Wi-Fi Aware menggunakan alamat MAC-nya
atau PeerHandle, menggunakan metode addWifiAwarePeer(MacAddress peer)
dan addWifiAwarePeer(PeerHandle peer). Untuk mengetahui informasi selengkapnya tentang cara menemukan peer Wi-Fi Aware, lihat dokumentasi Wi-Fi Aware.
Permintaan ranging
Aplikasi mengeluarkan permintaan pengukuran jarak menggunakan metode WifiRttManager.startRanging()
dan memberikan hal berikut: RangingRequest untuk menentukan
operasi, Executor untuk menentukan konteks callback, dan
RangingResultCallback untuk menerima hasil.
Contoh:
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) { … }
});
Operasi pengukuran jarak dilakukan secara asinkron, dan hasil pengukuran jarak ditampilkan di salah satu callback RangingResultCallback:
- Jika seluruh operasi pengukuran jarak gagal, callback
onRangingFailureakan dipicu dengan kode status yang dijelaskan dalamRangingResultCallback. Kegagalan tersebut mungkin terjadi jika layanan tidak dapat menjalankan operasi pengukuran jarak pada saat itu—misalnya, karena Wi-Fi dinonaktifkan, karena aplikasi telah meminta terlalu banyak operasi pengukuran jarak dan dibatasi, atau karena masalah izin. - Setelah operasi pengukuran jarak selesai, callback
onRangingResultsakan dipicu dengan daftar hasil yang cocok dengan daftar permintaan—satu hasil untuk setiap permintaan. Urutan hasil tidak selalu sama dengan urutan permintaan. Perhatikan bahwa operasi pengukuran jarak mungkin selesai, tetapi setiap hasil mungkin masih menunjukkan kegagalan pengukuran spesifik tersebut.
Menginterpretasikan hasil ranging
Setiap hasil yang ditampilkan oleh callback onRangingResults ditentukan oleh objek RangingResult. Pada setiap permintaan, lakukan hal berikut.
1. Identifikasi permintaan
Identifikasi permintaan berdasarkan informasi yang diberikan saat membuat
RangingRequest, paling sering alamat MAC yang diberikan di ScanResult
yang mengidentifikasi titik akses. Alamat MAC dapat diperoleh dari hasil pengukuran jarak menggunakan metode getMacAddress().
Daftar hasil pengukuran jarak mungkin dalam urutan yang berbeda dengan peer (titik akses) yang ditentukan dalam permintaan pengukuran jarak, jadi gunakan alamat MAC untuk mengidentifikasi peer, bukan urutan hasil.
2. Tentukan apakah setiap pengukuran berhasil
Untuk menentukan apakah pengukuran berhasil, gunakan metode getStatus(). Nilai selain STATUS_SUCCESS menunjukkan kegagalan. Kegagalan
berarti semua kolom lain dari hasil ini (kecuali identifikasi permintaan
pada langkah sebelumnya) tidak valid, dan metode get* yang sesuai akan gagal
dengan pengecualian IllegalStateException.
3. Dapatkan hasil untuk setiap pengukuran yang berhasil
Untuk setiap pengukuran yang berhasil (RangingResult), Anda dapat mengambil nilai
hasil dengan metode get masing-masing:
Jarak, dalam mm, dan standar deviasi pengukuran:
RSSI dari paket yang digunakan untuk pengukuran:
Waktu dalam milidetik saat pengukuran dilakukan (menunjukkan waktu sejak booting):
Jumlah pengukuran yang dicoba dan jumlah pengukuran yang berhasil (dan yang menjadi dasar pengukuran jarak):
Waktu minimum dan maksimum yang harus ditunggu perangkat klien di antara pengukuran NTB 11az:
getMinTimeBetweenNtbMeasurementsMicros()dangetMaxTimeBetweenNtbMeasurementsMicros()menampilkan waktu minimum dan maksimum. Jika pengukuran rentang berikutnya diminta sebelum waktu minimum berlalu, API akan menampilkan hasil rentang yang di-cache. Jika pengukuran ranging berikutnya diminta setelah waktu maksimum berlalu, API akan menghentikan sesi ranging non-pemicu dan menegosiasikan sesi ranging baru dengan stasiun yang merespons. Hindari meminta sesi rentang baru, karena akan menambah overhead pada waktu pengukuran rentang. Untuk memanfaatkan sepenuhnya efisiensi pengukuran jarak berbasis non-pemicu 802.11az, picu permintaan pengukuran jarak berikutnya antara waktu pengukuran minimum dan maksimum yang ditentukan dalam pengukuranRangingResultsebelumnya.Pengulangan Long Training Field (LTF) yang digunakan stasiun responder dan inisiator dalam preamble untuk hasil NTB IEEE 802.11az:
Jumlah aliran waktu spasial (STS) transmisi dan penerimaan yang digunakan stasiun inisiator untuk hasil NTB IEEE 802.11az:
Perangkat Android yang mendukung Wi-Fi RTT
Tabel berikut mencantumkan beberapa ponsel, titik akses, dan perangkat retail, pergudangan, dan pusat distribusi yang mendukung WiFi-RTT. Ini jauh dari komprehensif. Sebaiknya hubungi kami untuk mencantumkan produk yang mendukung RTT di sini.
Titik akses
| Produsen dan model | Tanggal dukungan | Protokol |
|---|---|---|
| Nest Wifi Pro (Wi-Fi 6E) | Didukung | mc |
| Compulab WILD AP | Didukung | mc |
| Google Wi-Fi | Didukung | mc |
| Router Wi-Fi Google Nest | Didukung | mc |
| Titik Google Nest Wi-Fi | Didukung | mc |
| Aruba AP-635 | Didukung | mc |
| Cisco 9130 | Didukung | mc |
| Cisco 9136 | Didukung | mc |
| Cisco 9166 | Didukung | mc |
| Cisco 9164 | Didukung | mc |
| Cisco CW9172I | Didukung | mc/az |
| Cisco CW9172H | Didukung | mc/az |
| Cisco CW9176I | Didukung | mc/az |
| Cisco CW9178I | Didukung | mc/az |
| Aruba AP-505 | Didukung | mc |
| Aruba AP-515 | Didukung | mc |
| Aruba AP-575 | Didukung | mc |
| Aruba AP-518 | Didukung | mc |
| Aruba AP-505H | Didukung | mc |
| Aruba AP-565 | Didukung | mc |
| Aruba AP-535 | Didukung | mc |
| Aruba AP567 | Didukung | mc |
| Aruba AP577 | Didukung | mc |
| Aruba AP555 | Didukung | mc |
| Aruba AP635 | Didukung | mc |
| Aruba AP655 | Didukung | mc |
| Aruba AP615 | Didukung | mc |
| Aruba AP734 | Didukung | mc/az |
| Aruba AP735 | Didukung | mc/az |
| Aruba AP754 | Didukung | mc/az |
| Aruba AP755 | Didukung | mc/az |
Ponsel
| Produsen dan model | Versi Android |
|---|---|
| Google Pixel 9 Pro XL | 14+ |
| Google Pixel 9 | 14+ |
| Google Pixel 9 Pro | 14+ |
| Google Pixel 9 Pro XL | 14+ |
| Google Pixel 7a | 14+ |
| Google Pixel 7 | 14+ |
| Google Pixel 8 | 14+ |
| Google Pixel 8 Pro | 14+ |
| Google Pixel 8a | 14+ |
| Samsung SM-S918B | 14+ |
| Samsung SM-A515F | 14+ |
| Google Pixel 9 Pro | 14+ |
| Samsung SM-A546E | 14+ |
| Samsung SM-S928B | 14+ |
| Samsung SM-A217F | 14+ |
| Samsung SM-A715F | 14+ |
| Samsung SM-A528B | 14+ |
| Samsung SM-A135F | 14+ |
| Samsung SM-S911B | 14+ |
| Xiaomi 21091116AI | 14+ |
| Google Pixel 9 | 14+ |
| Samsung SM-A127F | 14+ |
| Google Pixel 7 Pro | 14+ |
| Samsung SM-A556E | 14+ |
| Pixel 6 | 9.0+ |
| Pixel 6 Pro | 9.0+ |
| Pixel 5 | 9.0+ |
| Pixel 5a | 9.0+ |
| Pixel 5a (5G) | 9.0+ |
| Xiaomi Mi 10 Pro | 9.0+ |
| Xiaomi Mi 10 | 9.0+ |
| Xiaomi Redmi Mi 9T Pro | 9.0+ |
| Xiaomi Mi 9T | 9.0+ |
| Xiaomi Mi 9 | 9.0+ |
| Xiaomi Mi Note 10 | 9.0+ |
| Xiaomi Mi Note 10 Lite | 9.0+ |
| Xiaomi Redmi Note 9S | 9.0+ |
| Xiaomi Redmi Note 9 Pro | 9.0+ |
| Xiaomi Redmi Note 8T | 9.0+ |
| Xiaomi Redmi Note 8 | 9.0+ |
| Xiaomi Redmi K30 Pro | 9.0+ |
| Xiaomi Redmi K20 Pro | 9.0+ |
| Xiaomi Redmi K20 | 9.0+ |
| Xiaomi Redmi Note 5 Pro | 9.0+ |
| Xiaomi Mi CC9 Pro | 9.0+ |
| LG G8X ThinQ | 9.0+ |
| LG V50S ThinQ | 9.0+ |
| LG V60 ThinQ | 9.0+ |
| LG V30 | 9.0+ |
| Samsung Galaxy Note 10+ 5G | 9.0+ |
| Samsung Galaxy S20+ 5G | 9.0+ |
| Samsung Galaxy S20+ | 9.0+ |
| Samsung Galaxy S20 5G | 9.0+ |
| Samsung Galaxy S20 Ultra 5G | 9.0+ |
| Samsung Galaxy S20 | 9.0+ |
| Samsung Galaxy Note 10+ | 9.0+ |
| Samsung Galaxy Note 10 5G | 9.0+ |
| Samsung Galaxy Note 10 | 9.0+ |
| Samsung A9 Pro | 9.0+ |
| Google Pixel 4 XL | 9.0+ |
| Google Pixel 4 | 9.0+ |
| Google Pixel 4a | 9.0+ |
| Google Pixel 3 XL | 9.0+ |
| Google Pixel 3 | 9.0+ |
| Google Pixel 3a XL | 9.0+ |
| Google Pixel 3a | 9.0+ |
| Google Pixel 2 XL | 9.0+ |
| Google Pixel 2 | 9.0+ |
| Google Pixel 1 XL | 9.0+ |
| Google Pixel 1 | 9.0+ |
| Poco X2 | 9.0+ |
| Sharp Aquos R3 SH-04L | 9.0+ |
Perangkat retail, pergudangan, dan pusat distribusi
| Produsen dan model | Versi Android |
|---|---|
| Zebra PS20 | 10.0+ |
| Zebra TC52/TC52HC | 10.0+ |
| Zebra TC57 | 10.0+ |
| Zebra TC72 | 10.0+ |
| Zebra TC77 | 10.0+ |
| Zebra MC93 | 10.0+ |
| Zebra TC8300 | 10.0+ |
| Zebra VC8300 | 10.0+ |
| Zebra EC30 | 10.0+ |
| Zebra ET51 | 10.0+ |
| Zebra ET56 | 10.0+ |
| Zebra L10 | 10.0+ |
| Zebra CC600/CC6000 | 10.0+ |
| Zebra MC3300x | 10.0+ |
| Zebra MC330x | 10.0+ |
| Zebra TC52x | 10.0+ |
| Zebra TC57x | 10.0+ |
| Zebra EC50 (LAN dan HC) | 10.0+ |
| Zebra EC55 (WAN) | 10.0+ |
| Zebra WT6300 | 10.0+ |
| Skorpio X5 | 10.0+ |