Kablosuz konumu: RTT ile aralık

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 yerine ACCESS_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) kullanabilirsiniz.

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:

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