Yakındaki RTT özellikli kablosuz erişim noktalarına ve eş kablosuz bağlantı duyarlı cihazlara olan mesafeyi ölçmek için Kablosuz RTT (Gidiş Dönüş) API'si tarafından sağlanan kablosuz konum işlevini kullanabilirsiniz.
Üç veya daha fazla erişim noktasına olan mesafeyi ölçerseniz bu ölçümlere en uygun cihaz konumunu tahmin etmek için bir çarpımlama algoritması kullanabilirsiniz. Sonuç genellikle 1-2 metre içinde doğru sonuç verir.
Bu doğruluk sayesinde iç mekan navigasyonu, belirsizleştirilmiş sesli kontrol (örneğin, "Bu ışığı aç") ve konuma dayalı bilgiler (örneğin, "Bu ürün için özel teklifler var mı?") gibi konuma dayalı ayrıntılı hizmetler geliştirebilirsiniz.
İstekte bulunan cihazın, kablosuz RTT ile mesafeyi ölçmek için erişim noktalarına bağlanması gerekmez. Gizliliğin korunması amacıyla, erişim noktasına olan mesafeyi yalnızca istekte bulunan cihaz belirleyebilir. Erişim noktalarında bu bilgiler yoktur. Kablosuz RTT işlemleri, ön plan uygulamaları için sınırsızdır ancak arka plan uygulamaları için kısıtlanır.
Kablosuz RTT ve ilgili Fine-Time-Measurement (FTM) özellikleri, IEEE 802.11-2016 standardı tarafından belirlenmiştir. Wi-Fi RTT, bir paketin cihazlar arasında gidiş dönüş süresini ölçerek ve bu süreyi ışık hızıyla çarparak iki cihaz arasındaki mesafeyi hesaplar. Bu nedenle, FTM tarafından sağlanan doğru zaman ölçümünün yapılması gerekir.
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 cihazlarda çoklu katmanlandırmayı kullanarak bir cihazın konumunu belirlemek için bu protokolü kullandığınızda, uygulamanızda önceden belirlenmiş erişim noktası (AP) konum verilerine erişiminizin olması gerekir. Bu verilerin nasıl depolanacağına ve alınacağına karar vermek size bağlıdır.
Android 10 (API düzeyi 29) ve sonraki sürümleri çalıştıran cihazlarda AP konum verileri; enlem, boylam ve rakım gibi ResponderLocation
nesneleri olarak gösterilebilir. Konum Yapılandırma Bilgisi/Konum Civic Raporu'nu (LCI/LCR verileri) destekleyen kablosuz RTT AP'leri 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 konumlarını istemek için erişim noktalarını sorgulamasına olanak tanır. Bu sayede, uygulamanız daha önce bilinmese bile (örneğin, bir kullanıcı yeni bir binaya girdiğinde) erişim noktalarını bulup konumlarını belirleyebilir.
Gereksinimler
- Aralık isteğini gönderen 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 sürümleri çalıştırması gerekir.
- Aralık isteğinde bulunan cihazda konum hizmetleri etkinleştirilmiş ve kablosuz ağ taraması açık (Ayarlar > Konum altında) olmalıdır.
- Aralık isteğinde bulunan uygulama Android 13 (API düzeyi 33) veya sonraki sürümleri hedefliyorsa
NEARBY_WIFI_DEVICES
iznine sahip olması gerekir. Bu tür bir uygulama Android'in önceki bir sürümünü hedefliyorsa bunun yerineACCESS_FINE_LOCATION
iznine sahip olması gerekir. - Uygulama görünür durumdayken veya bir ön plan hizmetindeyken erişim noktaları aralığını sorgulamalıdır. Uygulama konum bilgilerine arka planda erişemez.
- Erişim noktası IEEE 802.11-2016 FTM standardını uygulamalıdır.
Kurulum
Uygulamanızı kablosuz RTT'yi 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 izinler olduğundan, kullanıcının RTT tarama işlemi yapmak istediği her seferde çalışma zamanında bu izinleri istemeniz gerekir. İzin verilmemişse uygulamanızın kullanıcının iznini istemesi gerekir. Çalışma zamanı izinleri hakkında daha fazla bilgi için Uygulama İzinleri İsteme konusuna 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'yi 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 olabilir, ancak kullanıcı kablosuz bağlantıyı devre dışı bıraktığından şu anda kullanılamıyor olabilir. Donanım ve donanım yazılımı özelliklerine bağlı olarak, SoftAP veya tethering kullanılıyorsa bazı cihazlar 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şebilir. Uygulamanız, müsaitlik durumu değiştiğinde gönderilen ACTION_WIFI_RTT_STATE_CHANGED öğesini almak için bir BroadcastReceiver kaydetmelidir. Uygulamanız yayın amacını aldığında, mevcut kullanılabilirlik durumunu kontrol etmeli ve davranışını buna göre ayarlamalıdır.
Örnek:
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 konusuna bakın.
Aralık isteği oluştur
Bir aralık istenen AP'lerin veya Wi-Fi Aware eşlerinin listesinin belirtilmesiyle bir aralık isteği (RangingRequest) oluşturulur. Tek bir aralıklı istekte birden çok erişim noktası veya Wi-Fi Aware eşi 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ı, ScanResult nesnesiyle tanımlanır. Bu nesne, WifiManager.getScanResults() çağrısı yapılarak elde edilebilir. Bir toplu işleme birden fazla erişim noktası eklemek için addAccessPoints(List
Benzer şekilde bir aralık isteği, sırasıyla addWifiAwarePeer(MacAddress peer) ve addWifiAwarePeer(PeerHandle peer) yöntemlerini kullanarak MAC adresini ya da PeerHandle'ı kullanarak bir Wi-Fi Aware eşi ekleyebilir. Wi-Fi Aware eşlerini bulma hakkında daha fazla bilgi edinmek için Wi-Fi Aware dokümanlarına bakın.
İstek aralığı
Bir uygulama, WifiRttManager.startRanging() yöntemini kullanarak ve şunları sağlayarak bir aralık isteği yayınlar: işlemi belirtmek için bir RangingRequest, geri çağırma bağlamını belirtmek için bir Executor ve sonuçları almak için bir RangingResultCallback.
Örnek:
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ğırmalarından birinde döndürülür:
- Aralık işleminin tamamı başarısız olursa onRangingFailure geri çağırması RangingResultCallback bölümünde açıklanan bir durum koduyla tetiklenir. Bu tür bir hata, hizmetin o sırada aralıklı bir işlemi yürütemaması; örneğin kablosuz bağlantının devre dışı bırakılması, uygulamanın çok fazla aralıklı işlem istemesi ve kısıtlanması veya bir izin sorunu nedeniyle ortaya çıkması olabilir.
- Aralık işlemi tamamlandığında, onRangingResults geri çağırması, istek listesiyle eşleşen sonuçların bir listesiyle (her istek için bir sonuç) tetiklenir. Sonuçların sırasının, isteklerin sıralamasıyla eşleşmemesi gerekir. Aralık işleminin tamamlanabileceğini ancak her sonucun yine de söz konusu ölçümde bir hata gösterebileceğini unutmayın.
Aralık sonuçlarını yorumlama
onRangingResults geri çağırması ile döndürülen sonuçların her biri, bir RangingResult nesnesiyle belirtilir. Her istekte aşağıdakileri yapın.
1. Talebi tanımlama
RangingRequest'i oluştururken sağlanan bilgilere dayanarak isteği tanımlayın. Bu çoğu zaman, ScanResult
içinde sağlanan, bir erişim noktasını tanımlayan MAC adresidir. 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, eşi tanımlamak için sonuçların sırasını değil, 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_FAILED dışındaki herhangi bir değer, bir hata olduğunu gösterir. Hata, bu sonucun (yukarıdaki istek tanımlaması hariç) diğer tüm alanlarının geçersiz olduğu ve ilgili get*
yönteminin InvalidStateException istisnasıyla başarısız olacağı anlamına gelir.
3. Her başarılı ölçüm için sonuç alın
Her başarılı ölçüm için sonuç değerlerini ilgili get
yöntemleriyle alabilirsiniz:
Milimetre 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 (başlatma işleminden bu yana geçen süreyi gösterir):
Denenen ölçümlerin sayısı ve başarılı olan ölçümlerin sayısı (ve mesafe ölçümlerinin dayandığı):
Kablosuz RTT'yi destekleyen Android cihazlar
Aşağıdaki tablolarda, kablosuz RTT'yi destekleyen bazı telefonlar, erişim noktaları ve perakende, depolama ve dağıtım merkezi cihazları listelenmiştir. Bu ölçümler fazla kapsamlı değildir. RTT özellikli ürünlerinizi burada listelemek için bize ulaşmanızı ö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 Wi-Fi 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 sonraki sürümler |
Pixel 6 Pro | 9.0 ve sonraki sürümler |
Pixel 5 | 9.0 ve sonraki sürümler |
Pixel 5a | 9.0 ve sonraki sürümler |
Pixel 5a (5G) | 9.0 ve sonraki sürümler |
Xiaomi Mi 10 Pro | 9.0 ve sonraki sürümler |
Xiaomi Mi 10 | 9.0 ve sonraki sürümler |
Xiaomi Redmi Mi 9T Pro | 9.0 ve sonraki sürümler |
Xiaomi Mi 9T | 9.0 ve sonraki sürümler |
Xiaomi Mi 9 | 9.0 ve sonraki sürümler |
Xiaomi Mi Not 10 | 9.0 ve sonraki sürümler |
Xiaomi Mi Not 10 Lite | 9.0 ve sonraki sürümler |
Xiaomi Redmi Note 9S | 9.0 ve sonraki sürümler |
Xiaomi Redmi Note 9 Pro | 9.0 ve sonraki sürümler |
Xiaomi Redmi Note 8T | 9.0 ve sonraki sürümler |
Xiaomi Redmi Note 8 | 9.0 ve sonraki sürümler |
Xiaomi Redmi K30 Pro | 9.0 ve sonraki sürümler |
Xiaomi Redmi K20 Pro | 9.0 ve sonraki sürümler |
Xiaomi Redmi K20 | 9.0 ve sonraki sürümler |
Xiaomi Redmi Note 5 Pro | 9.0 ve sonraki sürümler |
Xiaomi Mi CC9 Pro | 9.0 ve sonraki sürümler |
LG G8X İnce | 9.0 ve sonraki sürümler |
LG V50S İnce | 9.0 ve sonraki sürümler |
LG V60 İnce | 9.0 ve sonraki sürümler |
LG V30 | 9.0 ve sonraki sürümler |
Samsung Galaxy Note 10+ (5G) | 9.0 ve sonraki sürümler |
Samsung Galaxy S20+ (5G) | 9.0 ve sonraki sürümler |
Samsung Galaxy S20 ve sonraki modeller | 9.0 ve sonraki sürümler |
Samsung Galaxy S20 (5G) | 9.0 ve sonraki sürümler |
Samsung Galaxy S20 Ultra 5G | 9.0 ve sonraki sürümler |
Samsung Galaxy S20 | 9.0 ve sonraki sürümler |
Samsung Galaxy Note 10 ve sonraki modeller | 9.0 ve sonraki sürümler |
Samsung Galaxy Note 10 (5G) | 9.0 ve sonraki sürümler |
Samsung Galaxy Note 10 | 9.0 ve sonraki sürümler |
Samsung A9 Pro | 9.0 ve sonraki sürümler |
Google Pixel 4 XL | 9.0 ve sonraki sürümler |
Google Pixel 4 | 9.0 ve sonraki sürümler |
Google Pixel 4a | 9.0 ve sonraki sürümler |
Google Pixel 3 XL | 9.0 ve sonraki sürümler |
Google Pixel 3 | 9.0 ve sonraki sürümler |
Google Pixel 3a XL | 9.0 ve sonraki sürümler |
Google Pixel 3a | 9.0 ve sonraki sürümler |
Google Pixel 2 XL | 9.0 ve sonraki sürümler |
Google Pixel 2 | 9.0 ve sonraki sürümler |
Google Pixel 1 XL | 9.0 ve sonraki sürümler |
Google Pixel 1 | 9.0 ve sonraki sürümler |
Poco X2 | 9.0 ve sonraki sürümler |
Keskin Aquos R3 SH-04L | 9.0 ve sonraki sürümler |
Perakende, Depolama ve Dağıtım Merkezi Cihazları
Üretici ve Model | Android Sürümü |
---|---|
Zebra PS20 | 10.0 ve üzeri |
Zebra TC52/TC52HC | 10.0 ve üzeri |
Zebra TC57 | 10.0 ve üzeri |
Zebra TC72 | 10.0 ve üzeri |
Zebra TC77 | 10.0 ve üzeri |
Zebra MC93 | 10.0 ve üzeri |
Zebra TC8300 | 10.0 ve üzeri |
Zebra VC8300 | 10.0 ve üzeri |
Zebra EC30 | 10.0 ve üzeri |
Zebra ET51 | 10.0 ve üzeri |
Zebra ET56 | 10.0 ve üzeri |
Zebra L10 | 10.0 ve üzeri |
Zebra CC600/CC6000 | 10.0 ve üzeri |
Zebra MC3300x | 10.0 ve üzeri |
Zebra MC330x | 10.0 ve üzeri |
Zebra TC52x | 10.0 ve üzeri |
Zebra TC57x | 10.0 ve üzeri |
Zebra EC50 (LAN ve HC) | 10.0 ve üzeri |
Zebra EC55 (WAN) | 10.0 ve üzeri |
Zebra WT6300 | 10.0 ve üzeri |
Skorpio X5 | 10.0 ve üzeri |