میتوانید از قابلیتهای اسکن Wi-Fi ارائهشده توسط WifiManager API برای دریافت فهرست نقاط دسترسی Wi-Fi که از دستگاه قابلمشاهده هستند استفاده کنید.
فرایند اسکن کردن Wi-Fi
فرایند اسکن کردن سه مرحله دارد:
ثبت شنونده همهفرستی برای
SCAN_RESULTS_AVAILABLE_ACTION، که وقتی درخواستهای اسکن تکمیل میشود فراخوانی میشود و وضعیت موفقیت/شکست آنها را ارائه میدهد. برای دستگاههایی که Android 10 (سطح میانای برنامهسازی کاربردی ۲۹) و بالاتر را اجرا میکنند، این همهفرستی برای هر اسکن کامل Wi-Fi که توسط پلاتفرم یا برنامههای دیگر در دستگاه انجام شود ارسال خواهد شد. برنامهها میتوانند بااستفاده از همهفرستی، بدون اینکه خودشان اسکن انجام دهند، بهطور غیرفعال به همه اسکنهای تکمیلشده در دستگاه گوش دهند.بااستفاده از
WifiManager.startScan()، درخواست اسکن کنید. حتماً وضعیت برگرداندن روش را بررسی کنید، زیرا ممکن است تماس بهدلیل هریک از موارد زیر ناموفق باشد:- ممکن است درخواستهای اسکن بهدلیل تعداد زیاد اسکن در مدت زمان کوتاه محدود شود.
- دستگاه در حالت آزاد است و اسکن غیرفعال است.
- سختافزار Wi-Fi خطای اسکن گزارش میکند.
دریافت نتایج اسکن بااستفاده از
WifiManager.getScanResults(). نتایج اسکن برگرداندهشده جدیدترین نتایج بهروزشده هستند که ممکن است مربوط به اسکن قبلی باشند، اگر اسکن فعلی شما تکمیل یا موفقیتآمیز نبوده باشد. یعنی اگر این روش را قبلاز دریافت همهفرستی موفقSCAN_RESULTS_AVAILABLE_ACTIONفراخوانی کنید، ممکن است نتایج اسکن قدیمیتری دریافت کنید.
کد زیر نمونهای از نحوه اجرای این مراحل را ارائه میدهد:
کاتلین
val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager val wifiScanReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { val success = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false) if (success) { scanSuccess() } else { scanFailure() } } } val intentFilter = IntentFilter() intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION) context.registerReceiver(wifiScanReceiver, intentFilter) val success = wifiManager.startScan() if (!success) { // scan failure handling scanFailure() } .... private fun scanSuccess() { val results = wifiManager.scanResults ... use new scan results ... } private fun scanFailure() { // handle failure: new scan did NOT succeed // consider using old scan results: these are the OLD results! val results = wifiManager.scanResults ... potentially use older scan results ... }
جاوا
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); BroadcastReceiver wifiScanReceiver = new BroadcastReceiver() { @Override public void onReceive(Context c, Intent intent) { boolean success = intent.getBooleanExtra( WifiManager.EXTRA_RESULTS_UPDATED, false); if (success) { scanSuccess(); } else { // scan failure handling scanFailure(); } } }; IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); context.registerReceiver(wifiScanReceiver, intentFilter); boolean success = wifiManager.startScan(); if (!success) { // scan failure handling scanFailure(); } .... private void scanSuccess() { List<ScanResult> results = wifiManager.getScanResults(); ... use new scan results ... } private void scanFailure() { // handle failure: new scan did NOT succeed // consider using old scan results: these are the OLD results! List<ScanResult> results = wifiManager.getScanResults(); ... potentially use older scan results ... }
محدودیتها
Android 8.0 (سطح میانای برنامهسازی کاربردی ۲۶) محدودیتهایی را درخصوص اجازهها و بسامد مجاز اسکنهای Wi-Fi معرفی کرد.
برای بهبود عملکرد شبکه، امنیت، و عمر باتری، Android 9 (سطح API ۲۸) الزامات اجازه را سختتر کرده است و دفعات اسکن Wi-Fi را بیشتر محدود کرده است.
اجازهها
Android 8.0 و Android 8.1:
فراخوانی موفق به
WifiManager.getScanResults()
به یکی از اجازههای زیر نیاز دارد:
اگر برنامه برقراری تماس هیچکدام از این اجازهها را نداشته باشد، تماس با
SecurityException ناموفق میشود.
همچنین، در دستگاههایی که Android نسخه ۸.۰ (سطح میانای برنامهسازی کاربردی ۲۶) و بالاتر دارند، میتوانید از
CompanionDeviceManager
استفاده کنید تا دستگاههای همپا در اطراف را ازطرف برنامهتان اسکن کنید، بدون اینکه به اجازه مکان نیاز داشته باشید. برای اطلاعات بیشتر درباره این گزینه،
جفتسازی دستگاه همپا را ببینید.
Android 9:
برای اینکه تماس با
WifiManager.startScan()
موفقیتآمیز باشد، باید همه شرایط زیر برآورده شود:
- برنامه شما اجازه
ACCESS_FINE_LOCATIONیاACCESS_COARSE_LOCATIONرا دارد. - برنامه شما اجازه
CHANGE_WIFI_STATEدارد. - خدمات مکان در دستگاه فعال باشد (در تنظیمات > مکان).
Android 10 (میانای برنامهسازی کاربردی سطح ۲۹) و بالاتر:
برای اینکه تماس با
WifiManager.startScan()
موفقیتآمیز باشد، باید همه شرایط زیر برآورده شود:
- اگر برنامه شما کیت توسعه نرمافزار Android 10 (سطح میانای برنامهسازی کاربردی ۲۹) یا بالاتر را هدف قرار میدهد، برنامه شما
اجازه
ACCESS_FINE_LOCATIONرا دارد. - اگر برنامه شما کیت توسعه نرمافزار پایینتر از Android 10 (سطح میانای برنامهسازی کاربردی ۲۹) را هدف قرار میدهد، برنامه شما
اجازه
ACCESS_COARSE_LOCATIONیاACCESS_FINE_LOCATIONرا دارد. - برنامه شما اجازه
CHANGE_WIFI_STATEرا دارد. - خدمات مکان در دستگاه فعال باشد (در تنظیمات > مکان).
برای تماس موفقیتآمیز با
WifiManager.getScanResults()،
مطمئن شوید همه شرایط زیر برآورده شده باشد:
- اگر برنامه شما کیت توسعه نرمافزار Android 10 (سطح میانای برنامهسازی کاربردی ۲۹) یا بالاتر را هدف قرار میدهد، برنامه شما
اجازه
ACCESS_FINE_LOCATIONرا دارد. - اگر برنامه شما کیت توسعه نرمافزار پایینتر از Android 10 (سطح میانای برنامهسازی کاربردی ۲۹) را هدفیابی میکند، برنامه شما
اجازه
ACCESS_COARSE_LOCATIONیاACCESS_FINE_LOCATIONرا دارد. - برنامه شما اجازه
ACCESS_WIFI_STATEدارد. - خدمات مکان در دستگاه فعال باشد (در تنظیمات > مکان).
اگر برنامه برقراری تماس همه این الزامات را برآورده نکند، تماس با
SecurityException ناموفق میشود.
محدود کردن
محدودیتهای زیر بر بسامد اسکنها بااستفاده از
WifiManager.startScan() اعمال میشود.
Android 8.0 و Android 8.1:
هر برنامه پسزمینه میتواند یکبار در یک دوره ۳۰ دقیقهای اسکن کند.
Android 9:
هر برنامه پیشزمینه میتواند چهار بار در یک دوره ۲ دقیقهای اسکن کند. این کار امکان اسکنهای متوالی در مدتزمان کوتاه را فراهم میکند.
همه برنامههای پسزمینه باهم میتوانند یکبار در یک دوره ۳۰ دقیقهای اسکن کنند.
Android 10 و بالاتر:
همان محدودیتهای کاهش سرعت Android 9 اعمال میشود. گزینه توسعهدهنده جدیدی برای روشن/خاموش کردن محدودسازی برای آزمایش محلی وجود دارد (در گزینههای توسعهدهنده > شبکه > محدودسازی اسکن Wi-Fi).