می توانید از قابلیت های اسکن Wi-Fi ارائه شده توسط WifiManager API برای دریافت لیستی از نقاط دسترسی Wi-Fi که از دستگاه قابل مشاهده هستند استفاده کنید.
فرآیند اسکن وای فای
برای فرآیند اسکن سه مرحله وجود دارد:
یک شنونده پخش را برای
SCAN_RESULTS_AVAILABLE_ACTION
ثبت کنید، که با تکمیل درخواستهای اسکن فراخوانی میشود و وضعیت موفقیت/شکست آنها را ارائه میکند. برای دستگاههای دارای Android 10 (سطح API 29) و بالاتر، این پخش برای هر اسکن کامل Wi-Fi که توسط پلتفرم یا سایر برنامهها روی دستگاه انجام میشود، ارسال میشود. برنامهها میتوانند با استفاده از پخش بدون انجام اسکن خود، به صورت غیرفعال به تمام مراحل اسکن روی دستگاه گوش دهند.درخواست اسکن با استفاده از
WifiManager.startScan()
. مطمئن شوید که وضعیت بازگشت متد را بررسی کرده اید، زیرا ممکن است به هر یک از دلایل زیر تماس برقرار نشود:- درخواست های اسکن ممکن است به دلیل اسکن های زیاد در مدت زمان کوتاهی کاهش یابد.
- دستگاه بیکار است و اسکن غیرفعال است.
- سخت افزار وای فای خرابی اسکن را گزارش می دهد.
نتایج اسکن را با استفاده از
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 (سطح API 26) محدودیتهایی را در مورد مجوزها و فرکانس مجاز اسکنهای Wi-Fi معرفی کرد.
برای بهبود عملکرد شبکه، امنیت و عمر باتری، Android 9 (سطح API 28) الزامات مجوز را سختتر کرد و تعداد اسکنهای Wi-Fi را بیشتر محدود کرد.
مجوزها
اندروید 8.0 و اندروید 8.1:
یک فراخوان موفق به WifiManager.getScanResults()
به یکی از مجوزهای زیر نیاز دارد:
اگر برنامه تماسگیرنده هیچ یک از این مجوزها را نداشته باشد، تماس با یک SecurityException
انجام نمیشود.
از طرف دیگر، در دستگاههای دارای Android 8.0 (سطح API 26) و بالاتر، میتوانید از CompanionDeviceManager
برای انجام اسکن دستگاههای همراه در نزدیکی از طرف برنامه خود بدون نیاز به مجوز مکان استفاده کنید. برای اطلاعات بیشتر در مورد این گزینه، به جفت شدن دستگاه همراه مراجعه کنید.
اندروید 9:
یک فراخوان موفق به WifiManager.startScan()
مستلزم رعایت همه شرایط زیر است:
- برنامه شما دارای مجوز
ACCESS_FINE_LOCATION
یاACCESS_COARSE_LOCATION
است. - برنامه شما دارای مجوز
CHANGE_WIFI_STATE
است. - سرویسهای مکان در دستگاه فعال میشوند (در زیر تنظیمات > مکان ).
Android 10 (سطح API 29) و بالاتر:
یک فراخوان موفق به WifiManager.startScan()
مستلزم رعایت همه شرایط زیر است:
- اگر برنامه شما Android 10 (سطح API 29) SDK یا بالاتر را هدف قرار میدهد، برنامه شما دارای مجوز
ACCESS_FINE_LOCATION
است. - اگر برنامه شما SDK کمتر از Android 10 (سطح API 29) را هدف قرار داده است، برنامه شما دارای مجوز
ACCESS_COARSE_LOCATION
یاACCESS_FINE_LOCATION
است. - برنامه شما دارای مجوز
CHANGE_WIFI_STATE
است. - سرویسهای مکان در دستگاه فعال میشوند (در زیر تنظیمات > مکان ).
برای فراخوانی موفقیت آمیز WifiManager.getScanResults()
، مطمئن شوید که همه شرایط زیر برآورده می شوند:
- اگر برنامه شما Android 10 (سطح API 29) SDK یا بالاتر را هدف قرار میدهد، برنامه شما دارای مجوز
ACCESS_FINE_LOCATION
است. - اگر برنامه شما SDK کمتر از Android 10 (سطح API 29) را هدف قرار داده است، برنامه شما دارای مجوز
ACCESS_COARSE_LOCATION
یاACCESS_FINE_LOCATION
است. - برنامه شما دارای مجوز
ACCESS_WIFI_STATE
است. - سرویسهای مکان در دستگاه فعال میشوند (در زیر تنظیمات > مکان ).
اگر برنامه تماسگیرنده همه این الزامات را برآورده نکند، تماس با یک SecurityException
انجام نمیشود.
گاز دادن
محدودیت های زیر برای دفعات اسکن با استفاده از WifiManager.startScan()
اعمال می شود.
اندروید 8.0 و اندروید 8.1:
هر برنامه پسزمینه میتواند یک بار در مدت 30 دقیقه اسکن کند.
اندروید 9:
هر برنامه پیش زمینه می تواند چهار بار در یک دوره 2 دقیقه ای اسکن کند. این اجازه می دهد تا یک اسکن پشت سر هم در مدت زمان کوتاهی انجام شود.
همه برنامههای پسزمینه ترکیبی میتوانند یک بار در مدت 30 دقیقه اسکن کنند.
اندروید 10 و بالاتر:
همان محدودیتهای فشار از اندروید 9 اعمال میشود. یک گزینه توسعهدهنده جدید برای خاموش کردن throttling برای آزمایش محلی وجود دارد (در زیر Developer Options > Networking > Wi-Fi scan throttling ).