WifiManager.getScanResult() возвращает нулевое значение

Я пытаюсь выполнить сканирование доступных сетей 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");
        }
    }
}
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
419
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Проблема в том, что вы предполагаете, что 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;

Другие вопросы по теме