Kablosuz konumu: RTT ile aralık

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ü hedefliyorsa ACCESS_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) öğesini kullanabilirsiniz.

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:

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