Я пытаюсь выполнить сканирование доступных сетей Wi-Fi, но метод getScanResults() возвращает нулевой список.
Я включил все необходимые разрешения:
android.permission.ACCESS_COARSE_LOCATION
android.permission.CHANGE_WIFI_STATE
android.permission.ACCESS_FINE_LOCATION
android.permission.ACCESS_WIFI_STATE
Основной класс деятельности:
public class Home extends Activity {`
Context context;
WifiManager wifiManager = null;
WiFiReceiver wifiReceiver = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home);
context = this;
wifiManager = (WifiManager)
context.getSystemService(Context.WIFI_SERVICE);
wifiReceiver = new WiFiReceiver(wifiManager);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
registerReceiver(wifiReceiver, intentFilter);
wifiManager.startScan();
List<ScanResult> results = wifiReceiver.results;
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(wifiReceiver);
}
}
Широковещательный приемник:
public class WiFiReceiver extends BroadcastReceiver {`
public List<ScanResult> results;
private WifiManager wifiManager;
public WiFiReceiver(WifiManager wifiManager) {
this.wifiManager = wifiManager;
}
@Override
public void onReceive(Context context, Intent intent) {
boolean success = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false);
if (success) {
results = wifiManager.getScanResults();
Log.e("wiFi Manager", "Done");
} else {
Log.e("wiFi Manager", "Scan failure");
}
}
}
Проблема в том, что вы предполагаете, что startScan()
немедленно даст результат, но на самом деле он делает только то, что говорит, запуская сканирование. Вы получаете доступ к переменной results
до того, как onReceive
в вашем WiFiReceiver
сработает, поэтому она всегда будет нулевой (ваша регистрация должна подтвердить это).
Что вам нужно, так это использовать обратный вызов, чтобы получить результаты, когда они будут готовы, как это делает код здесь. Обратите внимание, что метод onReceive
вызывает scanSuccess()
, а доступ к результатам осуществляется только в scanSuccess()
, а не сразу после вызова startScan()
.
Также обратите внимание, как они проверяют, действительно ли запуск сканирования был успешным, проверяя логические значения startScan()
.
Начиная с уровня API 23 (Android 6.0 Marshmallow) нам нужно запрашивать разрешение во время выполнения со стороны пользователя. В частности, ACCESS_FINE_LOCATION. Вам нужно проверить, предоставлено ли разрешение перед wifiManager.startScan(), и если разрешение не предоставлено, вам нужно вызвать requestPermissions().
вот пример:
public void startScanningWifi(){if ( Build.VERSION.SDK_INT >= 23){
if (ActivityCompat.checkSelfPermission(context, Manifest.
permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(context,
Manifest.permission.ACCESS_COARSE_LOCATION) !=
PackageManager.PERMISSION_GRANTED ){
requestPermissions(new String[]{
Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_CODE_ASK_PERMISSIONS);
Log.i(TAG, "User location NOT ENABLED, waiting for permission");
}else{
//Start scanning for wifi
}}
Вам также нужно будет включить этот метод в активность
@Override
public void onRequestPermissionsResult(int requestCode,
String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_ASK_PERMISSIONS:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//start scanning
wifiManager.startScan();
} else {
// Permission for location Denied
Toast.makeText( this,"Well cant help you then!" ,
Toast.LENGTH_SHORT)
.show();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
Не забудьте также объявить об этом в своей деятельности.
private final int REQUEST_CODE_ASK_PERMISSIONS = 1;