Yakındaki RTT özellikli kablosuz erişim noktalarına ve eş Wi-Fi Aware cihazlara olan mesafeyi ölçmek için Wi-Fi RTT (Gidiş Dönüş Süresi) API'si tarafından sağlanan kablosuz konum işlevini kullanabilirsiniz.
Üç veya daha fazla erişim noktasına olan mesafeyi ölçüyorsanız bu ölçümlere en iyi uyan cihaz konumunu tahmin etmek için bir çarpanlı algoritma kullanabilirsiniz. Sonuç genellikle 1-2 metre içinde doğru sonuç verir.
Bu doğruluk sayesinde iç mekan navigasyonu, netleştirilmiş sesli kontrol (ör. "Bu ışığı aç") ve konuma dayalı bilgiler (örneğin, "Bu ürün için özel teklifler var mı?") gibi ayrıntılı konuma dayalı hizmetler geliştirebilirsiniz.
İstekte bulunan cihazın, kablosuz RTT ile mesafeyi ölçmek için erişim noktalarına bağlanmasına gerek yoktur. Gizliliği korumak için, erişim noktasına uzaklığı yalnızca istekte bulunan cihaz belirleyebilir. Erişim noktalarında bu bilgiler bulunmaz. Kablosuz RTT işlemleri, ön plan uygulamaları için sınırsızdır ancak arka plan uygulamaları için sınırlandırılır.
Kablosuz RTT ve ilgili Hassas Zaman Ölçümü (FTM) özellikleri, IEEE 802.11-2016 standardı tarafından belirtilmiştir. Kablosuz RTT, FTM'nin sağladığı hassas süre ölçümünü gerektirir. Çünkü iki cihaz arasındaki mesafeyi, bir paketin cihazlar arasında gidip gelmek için gereken süreyi ölçüp bu süreyi ışık hızıyla çarparak hesaplar.
Android sürümüne göre uygulama farklılıkları
Kablosuz RTT, Android 9'da (API düzeyi 28) kullanıma sunulmuştur. Android 9 çalıştıran cihazlarla çoklu katılımı kullanarak bir cihazın konumunu belirlemek için bu protokolü kullandığınızda, uygulamanızda önceden belirlenmiş erişim noktası (AP) konumları verilerine erişiminizin olması gerekir. Bu verileri nasıl depolayacağınıza ve alacağınıza siz karar verirsiniz.
Android 10 (API düzeyi 29) ve sonraki sürümleri çalıştıran cihazlarda AP konum verileri enlem, boylam ve rakım bilgilerini içeren ResponderLocation
nesneleri olarak gösterilebilir. Konum Yapılandırma Bilgileri/Konum Şehir Raporu'nu (LCI/LCR verileri) destekleyen Wi-Fi RTT erişim noktaları için protokol, aralık işlemi sırasında bir ResponderLocation
nesnesi döndürür.
Bu özellik, uygulamaların bu bilgileri önceden depolamak yerine doğrudan erişim noktaları için sorgulama yapmalarını sağlar. Böylece, bir kullanıcı yeni bir binaya girdiğinde olduğu gibi, uygulamanız erişim noktalarını bulabilir ve konumlarını belirleyebilir.
Şartlar
- Aralık isteğinde bulunan cihazın donanımı, 802.11-2016 FTM standardını uygulamalıdır.
- Aralık isteğinde bulunan cihazın Android 9 (API düzeyi 28) veya sonraki bir sürümü çalıştırıyor olması gerekir.
- Aralık isteğinde bulunan cihazda konum hizmetleri etkinleştirilmiş ve kablosuz ağ taraması açık olmalıdır (Ayarlar > Konum altında).
- Aralık isteğini gönderen uygulama Android 13 (API düzeyi 33) veya sonraki sürümleri hedefliyorsa
NEARBY_WIFI_DEVICES
iznine sahip olmalıdır. Bu tür bir uygulama Android'in önceki bir sürümünü hedefliyorsaACCESS_FINE_LOCATION
iznine sahip olmalıdır. - Uygulama, görünür durumdayken veya bir ön plan hizmeti sırasında erişim noktaları aralığını sorgulamalıdır. Uygulama arka planda konum bilgilerine erişemez.
- Erişim noktası, IEEE 802.11-2016 FTM standardını uygulamalıdır.
Kurulum
Uygulamanızı Kablosuz RTT kullanacak şekilde ayarlamak için aşağıdaki adımları uygulayın.
1. İzin iste
Uygulamanızın manifest dosyasında aşağıdaki izinleri isteyin:
<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" />
NEARBY_WIFI_DEVICES
ve ACCESS_FINE_LOCATION
izinleri tehlikeli izinlerdir. Bu nedenle, kullanıcı her RTT tarama işlemi yapmak istediğinde bunları çalışma zamanında istemeniz gerekir. İlgili izin verilmediyse uygulamanızın kullanıcı iznini istemesi gerekir. Çalışma zamanı izinleri hakkında daha fazla bilgi için Uygulama İzinleri İsteme bölümüne bakın.
2. Cihazın kablosuz RTT'yi destekleyip desteklemediğini kontrol edin.
Cihazın kablosuz RTT'yi destekleyip desteklemediğini kontrol etmek için PackageManager API'sini kullanın:
Kotlin
context.packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_RTT)
Java
context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_RTT);
3. Kablosuz RTT'nin kullanılabilir olup olmadığını kontrol etme
Cihazda Kablosuz RTT mevcut olabilir, ancak kullanıcı kablosuz bağlantıyı devre dışı bıraktığı için şu anda kullanılamıyor olabilir. SoftAP veya tethering kullanılıyorsa bazı cihazlar, donanım ve donanım yazılımı özelliklerine bağlı olarak Kablosuz RTT'yi desteklemeyebilir. Kablosuz RTT'nin şu anda kullanılabilir olup olmadığını kontrol etmek için isAvailable() işlevini çağırın.
Kablosuz RTT'nin kullanılabilirliği herhangi bir zamanda değiştirilebilir. Uygulamanızın, kullanılabilirlik durumu değiştiğinde gönderilen ACTION_WIFI_RTT_STATE_CHANGED işlevini almak için bir BroadcastRecipientr'ı kaydetmesi gerekir. Uygulamanız yayın amacını aldığında, mevcut kullanılabilirlik durumunu kontrol etmeli ve davranışını buna göre ayarlamalıdır.
Örneğin:
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);
Daha fazla bilgi için Yayınlar başlıklı makaleye bakın.
Aralık isteği oluşturma
Aralık isteği (RangingRequest), bir aralığın istendiği erişim noktaları veya Wi-Fi Aware eşlerinin listesi belirtilerek oluşturulur. Tek bir aralıklı istekte birden fazla erişim noktası veya Wi-Fi duyarlı eşleme belirtilebilir. Tüm cihazlara olan mesafeler ölçülüp döndürülür.
Örneğin, bir istek, mesafenin ölçüleceği bir erişim noktası belirtmek için addAccessPoint() yöntemini kullanabilir:
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();
Bir erişim noktası, WifiManager.getScanResults() çağrısı yapılarak elde edilebilen ScanResult nesnesiyle tanımlanır. Toplu olarak birden fazla erişim noktası eklemek için addAccessPoints(List
Benzer şekilde, bir aralık isteği, sırasıyla MAC adresini veya PeerHandle yöntemini kullanarak, addWifiAwarePeer(MacAddress peer) ve addWifiAwarePeer(PeerHandle peer) yöntemlerini kullanarak bir Wi-Fi Aware eş ekleyebilir. Wi-Fi Aware eşlerini keşfetme hakkında daha fazla bilgi için Wi-Fi Aware belgelerine bakın.
İstek aralığı
Bir uygulama, WifiRttManager.startRanging() yöntemini kullanarak bir aralık isteği yayınlar ve şunları sağlar: işlemi belirtmek için bir RangingRequest, geri çağırma bağlamını belirtmek için bir Executor ve sonuçları almak için RangingResultCallback.
Örneğin:
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) { … } });
Aralık işlemi eşzamansız olarak gerçekleştirilir ve aralık sonuçları RangingResultCallback'in geri çağırma işlemlerinden birinde döndürülür:
- Tüm aralık işlemi başarısız olursa onRangingFailure geri çağırması, RangingResultCallback'te açıklanan bir durum koduyla tetiklenir. Hizmetin o sırada bir aralık işlemi gerçekleştirememesi, örneğin kablosuz bağlantının devre dışı bırakılması, uygulamanın çok fazla aralık işlemi istemesi ve kısıtlanması veya bir izin sorunu nedeniyle böyle bir hata meydana gelebilir.
- Aralık işlemi tamamlandığında, onRangingResults geri çağırması istek listesiyle eşleşen bir sonuç listesiyle tetiklenir ve her istek için bir sonuç gösterilir. Sonuçların sırası, isteklerin sırasına mutlaka uymaz. Aralık işlemi tamamlanabilir, ancak her sonuç yine de ilgili ölçümde bir hata olduğunu gösterebilir.
Aralık sonuçlarını yorumlama
onRangingResults geri çağırması tarafından döndürülen sonuçların her biri bir RangingResult nesnesi tarafından belirtilir. Her istekte aşağıdakileri yapın.
1. Talebi tespit edin
İsteği RangingRequest oluştururken sağlanan bilgilere göre tanımlayın: Çoğu zaman ScanResult
içinde bir erişim noktasını tanımlayan MAC adresi. MAC adresi, getMacAddress() yöntemi kullanılarak aralık sonucundan elde edilebilir.
Aralık sonuçlarının listesi, aralık isteğinde belirtilen eşlerden (erişim noktaları) farklı sırada olabilir. Bu nedenle, sonuçların sırasını değil, eşi tanımlamak için MAC adresini kullanmanız gerekir.
2. Her ölçümün başarılı olup olmadığını belirleme
Bir ölçümün başarılı olup olmadığını belirlemek için getStatus() yöntemini kullanın. STATUS_SUCCESS dışındaki herhangi bir değer hata olduğunu gösterir. Hata olması, bu sonucun diğer tüm alanlarının (yukarıdaki istek kimliği hariç) geçersiz olduğu ve karşılık gelen get*
yönteminin bir IllegalStateException istisnasıyla başarısız olacağı anlamına gelir.
3. Her başarılı ölçüm için sonuç alma
Her başarılı ölçüm için sonuç değerlerini ilgili get
yöntemleriyle alabilirsiniz:
Milisaniye cinsinden mesafe ve ölçümün standart sapması:
Ölçümler için kullanılan paketlerin RSSI'si:
Ölçümün yapıldığı milisaniye cinsinden süre (açılıştan bu yana geçen süreyi belirtir):
Yapılmaya çalışılan ve başarılı olan ölçümlerin sayısı (ve mesafe ölçümlerinin baz aldığı):
Kablosuz RTT'yi destekleyen Android cihazlar
Aşağıdaki tablolarda, WiFi-RTT'yi destekleyen bazı telefonlar, erişim noktaları ve perakende, depo ve dağıtım merkezi cihazları listelenmektedir. Bunların tümü kapsamlı olmaktan çok uzaktır. RTT özellikli ürünlerinizi burada listelemek için bizimle iletişime geçmenizi öneririz.
Erişim Noktaları
Üretici ve Model | Destek Tarihi |
---|---|
Nest Wifi Pro (Wi-Fi 6E) | Destekleniyor |
Compulab WILD AP | Destekleniyor |
Google Wi-Fi | Destekleniyor |
Google Nest kablosuz yönlendirici | Destekleniyor |
Google Nest Kablosuz Bağlantı Noktası | Destekleniyor |
Aruba AP-635 | Destekleniyor |
Cisco 9130 | Destekleniyor |
Cisco 9136 | Destekleniyor |
Cisco 9166 | Destekleniyor |
Cisco 9164 | Destekleniyor |
Aruba AP-505 | Destekleniyor |
Aruba AP-515 | Destekleniyor |
Aruba AP-575 | Destekleniyor |
Aruba AP-518 | Destekleniyor |
Aruba AP-505H | Destekleniyor |
Aruba AP-565 | Destekleniyor |
Aruba AP-535 | Destekleniyor |
Telefonlar
Üretici ve Model | Android Sürümü |
---|---|
Pixel 6 | 9,0 ve üzeri |
Pixel 6 Pro | 9,0 ve üzeri |
Pixel 5 | 9,0 ve üzeri |
Pixel 5a | 9,0 ve üzeri |
Pixel 5a (5G) | 9,0 ve üzeri |
Xiaomi Mi 10 Pro | 9,0 ve üzeri |
Xiaomi Mi 10 | 9,0 ve üzeri |
Xiaomi Redmi Mi 9T Pro | 9,0 ve üzeri |
Xiaomi Mi 9T | 9,0 ve üzeri |
Xiaomi Mi 9 | 9,0 ve üzeri |
Xiaomi Mi Not 10 | 9,0 ve üzeri |
Xiaomi Mi Note 10 Lite | 9,0 ve üzeri |
Xiaomi Redmi Note 9S | 9,0 ve üzeri |
Xiaomi Redmi Note 9 Pro | 9,0 ve üzeri |
Xiaomi Redmi Note 8T | 9,0 ve üzeri |
Xiaomi Redmi Not 8 | 9,0 ve üzeri |
Xiaomi Redmi K30 Pro | 9,0 ve üzeri |
Xiaomi Redmi K20 Pro | 9,0 ve üzeri |
Xiaomi Redmi K20 | 9,0 ve üzeri |
Xiaomi Redmi Note 5 Pro | 9,0 ve üzeri |
Xiaomi Mi CC9 Pro | 9,0 ve üzeri |
LG G8X ThinQ | 9,0 ve üzeri |
LG V50S ThinQ | 9,0 ve üzeri |
LG V60 ThinQ | 9,0 ve üzeri |
LG s30 | 9,0 ve üzeri |
Samsung Galaxy Note 10+ 5G | 9,0 ve üzeri |
Samsung Galaxy S20+ 5G | 9,0 ve üzeri |
Samsung Galaxy S20+ | 9,0 ve üzeri |
Samsung Galaxy S20 5G | 9,0 ve üzeri |
Samsung Galaxy S20 Ultra 5G | 9,0 ve üzeri |
Samsung Galaxy S20 | 9,0 ve üzeri |
Samsung Galaxy Note 10 ve sonraki modeller | 9,0 ve üzeri |
Samsung Galaxy Note 10 5G | 9,0 ve üzeri |
Samsung Galaxy Note 10 | 9,0 ve üzeri |
Samsung A9 Pro | 9,0 ve üzeri |
Google Pixel 4 XL | 9,0 ve üzeri |
Google Pixel 4 | 9,0 ve üzeri |
Google Pixel 4a | 9,0 ve üzeri |
Google Pixel 3 XL | 9,0 ve üzeri |
Google Pixel 3 | 9,0 ve üzeri |
Google Pixel 3a XL | 9,0 ve üzeri |
Google Pixel 3a | 9,0 ve üzeri |
Google Pixel 2 XL | 9,0 ve üzeri |
Google Pixel 2 | 9,0 ve üzeri |
Google Pixel 1 XL | 9,0 ve üzeri |
Google Pixel 1 | 9,0 ve üzeri |
Poco X2 | 9,0 ve üzeri |
Keskin Aquos R3 SH-04L | 9,0 ve üzeri |
Perakende, Depolama ve Dağıtım Merkezi Cihazları
Üretici ve Model | Android Sürümü |
---|---|
Zebra PS20 | 10 ve üzeri |
Zebra TC52/TC52HC | 10 ve üzeri |
Zebra TC57 | 10 ve üzeri |
Zebra TC72 | 10 ve üzeri |
Zebra TC77 | 10 ve üzeri |
Zebra MC93 | 10 ve üzeri |
TC8300 Zebra | 10 ve üzeri |
Zebra VC8300 | 10 ve üzeri |
Zebra EC30 | 10 ve üzeri |
Zebra ET51 | 10 ve üzeri |
Zebra ET56 | 10 ve üzeri |
Zebra L10 | 10 ve üzeri |
Zebra CC600/CC6000 | 10 ve üzeri |
Zebra MC3300x | 10 ve üzeri |
Zebra MC330x | 10 ve üzeri |
Zebra TC52x | 10 ve üzeri |
Zebra TC57x | 10 ve üzeri |
Zebra EC50 (LAN ve HC) | 10 ve üzeri |
Zebra EC55 (WAN) | 10 ve üzeri |
Zebra WT6300 | 10 ve üzeri |
Skorpio X5 | 10 ve üzeri |