می توانید از عملکرد مکان Wi-Fi ارائه شده توسط Wi-Fi RTT (Round-Trip-Time) API برای اندازه گیری فاصله تا نقاط دسترسی Wi-Fi با قابلیت RTT نزدیک و دستگاه های Wi-Fi Aware همتا استفاده کنید.
اگر فاصله سه یا چند نقطه دسترسی را اندازهگیری کنید، میتوانید از یک الگوریتم چندلایهای برای تخمین موقعیت دستگاهی که به بهترین وجه با این اندازهها منطبق است، استفاده کنید. نتیجه معمولاً در فاصله 1-2 متری دقیق است.
با این دقت، میتوانید سرویسهای مبتنی بر مکان دقیق، مانند ناوبری داخلی، کنترل صوتی مبهم (به عنوان مثال، «این چراغ را روشن کنید»)، و اطلاعات مبتنی بر مکان (بهعنوان مثال، «آیا پیشنهادهای ویژهای برای این محصول؟").
دستگاه درخواست کننده برای اندازه گیری فاصله با Wi-Fi RTT نیازی به اتصال به نقاط دسترسی ندارد. برای حفظ حریم خصوصی، فقط دستگاه درخواست کننده می تواند فاصله تا نقطه دسترسی را تعیین کند. نقاط دسترسی این اطلاعات را ندارند. عملیات RTT Wi-Fi برای برنامه های پیش زمینه نامحدود است اما برای برنامه های پس زمینه محدود می شود.
Wi-Fi RTT و قابلیت های Fine-Time-Measurement (FTM) مربوطه توسط استاندارد IEEE 802.11-2016 مشخص شده است. Wi-Fi RTT به اندازهگیری زمان دقیق ارائه شده توسط FTM نیاز دارد زیرا فاصله بین دو دستگاه را با اندازهگیری زمانی که یک بسته برای رفت و برگشت بین دستگاهها طول میکشد و ضرب آن زمان در سرعت نور محاسبه میکند.
تفاوت های پیاده سازی بر اساس نسخه اندروید
Wi-Fi RTT در اندروید 9 (سطح API 28) معرفی شد. هنگام استفاده از این پروتکل برای تعیین موقعیت دستگاه با استفاده از چندلایه بودن با دستگاه های دارای Android 9، باید به داده های مکان های نقطه دسترسی (AP) از پیش تعیین شده در برنامه خود دسترسی داشته باشید. این شما هستید که تصمیم می گیرید چگونه این داده ها را ذخیره و بازیابی کنید.
در دستگاههای دارای Android 10 (سطح API 29) و بالاتر، دادههای مکان AP را میتوان بهعنوان اشیاء ResponderLocation
نشان داد که شامل طول، طول و عرض جغرافیایی و ارتفاع میشود. برای APهای Wi-Fi RTT که اطلاعات پیکربندی موقعیت مکانی/گزارش مدنی موقعیت مکانی (دادههای LCI/LCR) را پشتیبانی میکنند، پروتکل یک شی ResponderLocation
را در طول فرآیند محدوده برمیگرداند.
این ویژگی به برنامهها اجازه میدهد به جای اینکه نیاز به ذخیره این اطلاعات از قبل داشته باشند، از APها درخواست کنند تا موقعیت خود را مستقیماً از آنها بپرسند. بنابراین، برنامه شما میتواند APها را پیدا کند و موقعیت آنها را تعیین کند، حتی اگر APها قبلاً شناخته شده نبودند، مانند زمانی که کاربر وارد یک ساختمان جدید میشود.
الزامات
- سخت افزار دستگاهی که درخواست محدوده را ارائه می دهد باید استاندارد 802.11-2016 FTM را اجرا کند.
- دستگاهی که درخواست محدوده را ارائه میکند باید دارای Android 9 (سطح API 28) یا بالاتر باشد.
- دستگاهی که درخواست محدوده را ارائه میکند باید خدمات مکان را فعال و اسکن Wi-Fi را روشن کند (در تنظیمات > مکان ).
- اگر برنامه ای که درخواست محدوده را ارائه می کند Android 13 (سطح API 33) یا بالاتر را هدف قرار می دهد، باید مجوز
NEARBY_WIFI_DEVICES
را داشته باشد. اگر چنین برنامهای نسخه قبلی Android را هدف قرار دهد، باید مجوزACCESS_FINE_LOCATION
را داشته باشد. - وقتی برنامه قابل مشاهده است یا در یک سرویس پیش زمینه است، برنامه باید محدوده نقاط دسترسی را جستجو کند. برنامه نمی تواند به اطلاعات مکان از پس زمینه دسترسی پیدا کند .
- نقطه دسترسی باید استاندارد IEEE 802.11-2016 FTM را پیاده سازی کند.
راه اندازی
برای تنظیم برنامه خود برای استفاده از Wi-Fi RTT، مراحل زیر را انجام دهید.
1. درخواست مجوز
مجوزهای زیر را در مانیفست برنامه خود درخواست کنید:
<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
و ACCESS_FINE_LOCATION
مجوزهای خطرناکی هستند، بنابراین باید هر بار که کاربر میخواهد عملیات اسکن RTT را انجام دهد، آنها را در زمان اجرا درخواست کنید. اگر مجوز قبلاً اعطا نشده باشد، برنامه شما باید مجوز کاربر را درخواست کند. برای اطلاعات بیشتر درباره مجوزهای زمان اجرا، به درخواست مجوزهای برنامه مراجعه کنید.
2. بررسی کنید که آیا دستگاه از Wi-Fi RTT پشتیبانی می کند یا خیر
برای بررسی اینکه آیا دستگاه از Wi-Fi RTT پشتیبانی میکند، از PackageManager API استفاده کنید:
کاتلین
context.packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_RTT)
جاوا
context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_RTT);
3. بررسی کنید که آیا Wi-Fi RTT در دسترس است یا خیر
Wi-Fi RTT ممکن است در دستگاه وجود داشته باشد، اما ممکن است در حال حاضر در دسترس نباشد زیرا کاربر Wi-Fi را غیرفعال کرده است. بسته به قابلیتهای سختافزار و میانافزار، ممکن است برخی از دستگاهها در صورت استفاده از SoftAP یا تترینگ از Wi-Fi RTT پشتیبانی نکنند. برای بررسی اینکه آیا Wi-Fi RTT در حال حاضر در دسترس است یا خیر، با isAvailable() تماس بگیرید.
در دسترس بودن Wi-Fi RTT می تواند در هر زمان تغییر کند. برنامه شما باید یک BroadcastReceiver برای دریافت ACTION_WIFI_RTT_STATE_CHANGED ثبت کند که در صورت تغییر در دسترس بودن ارسال می شود. وقتی برنامه شما هدف پخش را دریافت می کند، برنامه باید وضعیت فعلی در دسترس بودن را بررسی کند و رفتار خود را بر اساس آن تنظیم کند.
به عنوان مثال:
کاتلین
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)
جاوا
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);
برای اطلاعات بیشتر، به پخشها مراجعه کنید.
یک درخواست دامنه دار ایجاد کنید
یک درخواست محدوده ( RangingRequest ) با تعیین لیستی از AP یا همتایان Wi-Fi Aware که محدوده درخواست شده برای آنها ایجاد می شود. چندین نقطه دسترسی یا همتایان Wi-Fi Aware را می توان در یک درخواست محدوده مشخص کرد. فاصله تا همه دستگاه ها اندازه گیری و برگردانده می شود.
به عنوان مثال، یک درخواست می تواند از متد addAccessPoint() برای تعیین نقطه دسترسی برای اندازه گیری فاصله استفاده کند:
کاتلین
val req: RangingRequest = RangingRequest.Builder().run { addAccessPoint(ap1ScanResult) addAccessPoint(ap2ScanResult) build() }
جاوا
RangingRequest.Builder builder = new RangingRequest.Builder(); builder.addAccessPoint(ap1ScanResult); builder.addAccessPoint(ap2ScanResult); RangingRequest req = builder.build();
یک نقطه دسترسی با شیء ScanResult آن شناسایی میشود که با فراخوانی WifiManager.getScanResults() قابل دریافت است. می توانید از addAccessPoints(List
به طور مشابه، یک درخواست محدوده میتواند یک همتای Wi-Fi Aware را با استفاده از آدرس MAC یا PeerHandle خود، با استفاده از روشهای addWifiAwarePeer (همتا MacAddress) و addWifiAwarePeer (PeerHandle peer) اضافه کند. برای اطلاعات بیشتر درباره پیدا کردن همتایان Wi-Fi Aware، به مستندات Wi-Fi Aware مراجعه کنید.
محدوده درخواست
یک برنامه با استفاده از متد WifiRttManager.startRanging() درخواست محدوده ای را صادر می کند و موارد زیر را ارائه می دهد: RangingRequest برای مشخص کردن عملیات، Executor برای مشخص کردن زمینه پاسخگویی، و RangingResultCallback برای دریافت نتایج.
به عنوان مثال:
کاتلین
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) { … } })
جاوا
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) { … } });
عملیات محدوده به صورت ناهمزمان انجام می شود و نتایج دامنه در یکی از فراخوانی های RangingResultCallback برگردانده می شود:
- اگر کل عملیات محدوده ناموفق باشد، پاسخ به تماس onRangingFailure با کد وضعیتی که در RangingResultCallback توضیح داده شده است، راه اندازی می شود. اگر سرویس نتواند یک عملیات محدوده را در آن زمان اجرا کند، چنین شکستی ممکن است اتفاق بیفتد - برای مثال، به دلیل غیرفعال بودن Wi-Fi، به دلیل اینکه برنامه عملیات محدوده زیادی را درخواست کرده است و درنگ است، یا به دلیل یک مشکل مجوز.
- هنگامی که عملیات محدوده به پایان رسید، پاسخ به تماس onRangingResults با فهرستی از نتایج که با فهرست درخواستها مطابقت دارد راهاندازی میشود - یک نتیجه برای هر درخواست. ترتیب نتایج لزوماً با ترتیب درخواست ها مطابقت ندارد. توجه داشته باشید که عملیات محدوده ممکن است کامل شود اما هر نتیجه همچنان ممکن است نشان دهنده شکست آن اندازه گیری خاص باشد.
نتایج دامنه ای را تفسیر کنید
هر یک از نتایجی که با فراخوانی onRangingResults برگردانده می شود توسط یک شی RangingResult مشخص می شود. در مورد هر درخواست، موارد زیر را انجام دهید.
1. درخواست را شناسایی کنید
درخواست را بر اساس اطلاعات ارائه شده هنگام ایجاد RangingRequest شناسایی کنید: اغلب یک آدرس MAC ارائه شده در ScanResult
که یک نقطه دسترسی را شناسایی می کند. آدرس MAC را می توان با استفاده از متد ()getMacAddress از نتیجه محدوده بدست آورد.
فهرست نتایج محدوده ممکن است به ترتیب متفاوت با همتاها (نقاط دسترسی) مشخص شده در درخواست محدوده باشد، بنابراین باید از آدرس MAC برای شناسایی همتا استفاده کنید نه ترتیب نتایج.
2. تعیین کنید که آیا هر اندازه گیری موفقیت آمیز بوده است یا خیر
برای تعیین موفقیت آمیز بودن اندازه گیری، از متد getStatus() استفاده کنید. هر مقداری غیر از STATUS_SUCCESS نشان دهنده خرابی است. خطا به این معنی است که تمام فیلدهای دیگر این نتیجه (به جز شناسایی درخواست بالا) نامعتبر هستند و متد get*
مربوطه با یک استثناء IllegalStateException ناموفق خواهد بود.
3. برای هر اندازه گیری موفقیت آمیز نتیجه بگیرید
برای هر اندازه گیری موفق، می توانید مقادیر نتیجه را با روش های get
مربوطه بازیابی کنید:
فاصله، بر حسب میلی متر و انحراف استاندارد اندازه گیری:
RSSI بسته های مورد استفاده برای اندازه گیری:
زمان بر حسب میلی ثانیه که در آن اندازه گیری انجام شد (نشان دهنده زمان از زمان راه اندازی):
تعداد اندازهگیریهایی که انجام شد و تعداد اندازهگیریهایی که موفقیتآمیز شدند (و اندازهگیریهای فاصله بر آنها استوار است):
دستگاه های اندرویدی که از WiFi-RTT پشتیبانی می کنند
در جداول زیر برخی از تلفن ها ، نقاط دسترسی و دستگاه های خرده فروشی، انبارداری و توزیع که از WiFi-RTT پشتیبانی می کنند، فهرست شده است. اینها به دور از جامعیت هستند. ما شما را تشویق می کنیم که با ما تماس بگیرید تا محصولات با قابلیت RTT خود را در اینجا لیست کنید.
نقاط دسترسی
سازنده و مدل | تاریخ پشتیبانی |
---|---|
Nest Wifi Pro (Wi-Fi 6E) | پشتیبانی می شود |
Compulab WILD AP | پشتیبانی می شود |
گوگل وای فای | پشتیبانی می شود |
روتر Wi-Fi Google Nest | پشتیبانی می شود |
Google Nest Wi-Fi Point | پشتیبانی می شود |
آروبا AP-635 | پشتیبانی می شود |
سیسکو 9130 | پشتیبانی می شود |
سیسکو 9136 | پشتیبانی می شود |
سیسکو 9166 | پشتیبانی می شود |
سیسکو 9164 | پشتیبانی می شود |
آروبا AP-505 | پشتیبانی می شود |
آروبا AP-515 | پشتیبانی می شود |
آروبا AP-575 | پشتیبانی می شود |
آروبا AP-518 | پشتیبانی می شود |
آروبا AP-505H | پشتیبانی می شود |
آروبا AP-565 | پشتیبانی می شود |
آروبا AP-535 | پشتیبانی می شود |
تلفن ها
سازنده و مدل | نسخه اندروید |
---|---|
پیکسل 6 | 9.0+ |
پیکسل 6 پرو | 9.0+ |
پیکسل 5 | 9.0+ |
پیکسل 5a | 9.0+ |
Pixel 5a 5G | 9.0+ |
شیائومی می 10 پرو | 9.0+ |
شیائومی می 10 | 9.0+ |
شیائومی ردمی می 9 تی پرو | 9.0+ |
شیائومی می 9 تی | 9.0+ |
شیائومی می 9 | 9.0+ |
شیائومی می نوت 10 | 9.0+ |
شیائومی می نوت 10 لایت | 9.0+ |
شیائومی ردمی نوت 9 اس | 9.0+ |
شیائومی ردمی نوت 9 پرو | 9.0+ |
شیائومی ردمی نوت 8 تی | 9.0+ |
شیائومی ردمی نوت 8 | 9.0+ |
شیائومی ردمی K30 پرو | 9.0+ |
شیائومی ردمی K20 پرو | 9.0+ |
شیائومی ردمی K20 | 9.0+ |
شیائومی ردمی نوت 5 پرو | 9.0+ |
Xiaomi Mi CC9 Pro | 9.0+ |
LG G8X ThinQ | 9.0+ |
LG V50S ThinQ | 9.0+ |
LG V60 ThinQ | 9.0+ |
ال جی وی 30 | 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+ |
سامسونگ گلکسی اس 20 | 9.0+ |
سامسونگ گلکسی نوت 10 پلاس | 9.0+ |
سامسونگ گلکسی نوت 10 5G | 9.0+ |
سامسونگ گلکسی نوت 10 | 9.0+ |
سامسونگ A9 پرو | 9.0+ |
Google Pixel 4 XL | 9.0+ |
گوگل پیکسل 4 | 9.0+ |
گوگل پیکسل 4a | 9.0+ |
گوگل پیکسل 3 ایکس ال | 9.0+ |
گوگل پیکسل 3 | 9.0+ |
Google Pixel 3a XL | 9.0+ |
گوگل پیکسل 3a | 9.0+ |
Google Pixel 2 XL | 9.0+ |
گوگل پیکسل 2 | 9.0+ |
Google Pixel 1 XL | 9.0+ |
گوگل پیکسل 1 | 9.0+ |
پوکو ایکس 2 | 9.0+ |
شارپ Aquos R3 SH-04L | 9.0+ |
دستگاه های خرده فروشی، انبارداری و مرکز توزیع
سازنده و مدل | نسخه اندروید |
---|---|
Zebra PS20 | 10.0+ |
زبرا TC52/TC52HC | 10.0+ |
زبرا TC57 | 10.0+ |
زبرا TC72 | 10.0+ |
زبرا TC77 | 10.0+ |
زبرا MC93 | 10.0+ |
زبرا TC8300 | 10.0+ |
Zebra VC8300 | 10.0+ |
زبرا EC30 | 10.0+ |
زبرا ET51 | 10.0+ |
زبرا ET56 | 10.0+ |
زبرا L10 | 10.0+ |
زبرا CC600/CC6000 | 10.0+ |
Zebra MC3300x | 10.0+ |
زبرا MC330x | 10.0+ |
زبرا TC52x | 10.0+ |
زبرا TC57x | 10.0+ |
Zebra EC50 (LAN و HC) | 10.0+ |
Zebra EC55 (WAN) | 10.0+ |
زبرا WT6300 | 10.0+ |
Skorpio X5 | 10.0+ |