Android Wifi 扫描 - 未调用 SCAN_RESULTS_AVAILABLE_ACTION 的 BroadcastReceiver [英] Android Wifi Scan - BroadcastReceiver for SCAN_RESULTS_AVAILABLE_ACTION not getting called

查看:67
本文介绍了Android Wifi 扫描 - 未调用 SCAN_RESULTS_AVAILABLE_ACTION 的 BroadcastReceiver的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的代码:

public class FloatWifiManager implements IWifiManager {

    private WifiManager wifiManager;

    private BroadcastReceiver wifiScanReceiver;

    public FloatWifiManager(Context context) {
        ...
        wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);

        // Registering Wifi Receiver
        wifiScanReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context c, Intent intent) {
                if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
                    // not getting called, only after running app and manually going to the wifi settings in android
                }
            }
        };

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
        context.registerReceiver(wifiScanReceiver, intentFilter);
        wifiManager.startScan();
    }

我注册了 BroadcastReceiver,就像我在所有示例中看到的一样,并执行了 startScan.

I registered the BroadcastReceiver exactly like I saw in all the examples, and did startScan.

发生的情况是,wifi 列表 正在改变(当然,我测试过),但如果我只是留在应用程序中,则不会调用 onReceive.

What happens is, the wifi list is changing (for sure, I tested), but onReceive is not called if I just stay in the app.

是什么让 onReceive 最终被调用 - 是启动应用程序,让它运行,然后在安卓手机中进入设置 -> Wifi 设置.去那里时,突然列表正在更新并且 onReceive 被调用.

What makes onReceive finally to be called - is to launch the app, leave it running, and going in the android phone to Settings -> Wifi settings. when going there, all of the sudden the List is updating and onReceive is called.

这里有什么问题?

  1. wifiManager.startScan(); 是否只运行一次扫描?或者它是一个不断监听传入的扫描结果"的功能?

  1. Does wifiManager.startScan(); runs the scan only once? or it is a function that keeps listening to incoming "Scan Results"?

显然,为什么接收器没有被调用?

And obviously, why does the receiver doesn't get called?

推荐答案

是的,startScan() 只请求一次扫描.

Yes, startScan() requests only one single scan.

你可以去掉 if (intent.getAction().equals(..)) 条件.其他的好像没问题.

You can get rid of the if (intent.getAction().equals(..)) condition. Anything else seems to be ok.

只是为了说明 - 我的目标是拥有一个能够获得每次 Wifi 网络列表发生变化时调用,而无需单击开始扫描"按钮.

just to make it clear - my goal to have a receiver that will get called every time the Wifi networks list are changing, without having to click a "start scan" button.

AFAIK 在任何 wifi 网络发生变化时都无法收到通知.您只能使用 startScan 请求扫描 - 当然您可以使用线程或处理程序重复调用 startScan.

AFAIK it is not possible to get notified whenever any of the wifi networks change. You can only request a scan with startScan - and of course you can call startScan repeatedly using a Thread or Handler.

文档SCAN_RESULTS_AVAILABLE_ACTION接入点扫描已完成,结果可从请求方获得"时调用.如何以及何时进行扫描取决于请求者的实现.Elenkov 写道,Android 设备很少包含原始 wpa_supplicant 代码;所包含的实现经常被修改以更好地与底层 SoC 兼容".

The docs say that SCAN_RESULTS_AVAILABLE_ACTION is called when "an access point scan has completed, and results are available from the supplicant". How and when a scan is proceeded depends on the implemention of the supplicant. Elenkov writes, that "Android devices rarely include the original wpa_supplicant code; the included implementation is often modified for better compatibility with the underlying SoC".

扫描接入点

此示例扫描可用的接入点和自组织网络.btnScan 激活由 WifiManager.startScan() 方法启动的扫描.扫描完成后,WifiManager 调用 SCAN_RESULTS_AVAILABLE_ACTION 意图,WifiScanReceiver 类处理扫描结果.结果显示在 TextView 中.

This example scans for available access points and ad hoc networks. btnScan activates a scan initiated by the WifiManager.startScan() method. After the scan, WifiManager calls the SCAN_RESULTS_AVAILABLE_ACTION intent and the WifiScanReceiver class processes the scan result. The results are displayed in a TextView.

public class MainActivity extends AppCompatActivity {

    private final static String TAG = "MainActivity";

    TextView txtWifiInfo;
    WifiManager wifi;
    WifiScanReceiver wifiReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        wifi=(WifiManager)getSystemService(Context.WIFI_SERVICE);
        wifiReceiver = new WifiScanReceiver();

        txtWifiInfo = (TextView)findViewById(R.id.txtWifiInfo);
        Button btnScan = (Button)findViewById(R.id.btnScan);
        btnScan.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.i(TAG, "Start scan...");
                wifi.startScan();
            }
        });
    }

    protected void onPause() {
        unregisterReceiver(wifiReceiver);
        super.onPause();
    }

    protected void onResume() {
        registerReceiver(
            wifiReceiver, 
            new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)
        );
        super.onResume();
    }

    private class WifiScanReceiver extends BroadcastReceiver {
        public void onReceive(Context c, Intent intent) {
            List<ScanResult> wifiScanList = wifi.getScanResults();
            txtWifiInfo.setText("");
            for(int i = 0; i < wifiScanList.size(); i++){
                String info = ((wifiScanList.get(i)).toString());
                txtWifiInfo.append(info+"

");
            }
        }
    }
}

权限

需要在AndroidManifest.xml中定义以下权限:

The following permissions need to be defined in AndroidManifest.xml:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />

android.permission.ACCESS_WIFI_STATE 是调用 WifiManager.getScanResults() 所必需的.如果没有 android.permission.CHANGE_WIFI_STATE,您将无法使用 WifiManager.startScan() 启动扫描.

android.permission.ACCESS_WIFI_STATE is necessary for calling WifiManager.getScanResults(). Without android.permission.CHANGE_WIFI_STATE you cannot initiate a scan with WifiManager.startScan().

编译api level 23或更高(Android 6.0及以上)项目时,必须插入android.permission.ACCESS_FINE_LOCATIONandroid.permission.ACCESS_COARSE_LOCATION.此外,需要请求许可,例如在您的主要活动的 onCreate 方法中:

When compiling the project for api level 23 or greater (Android 6.0 and up), either android.permission.ACCESS_FINE_LOCATION or android.permission.ACCESS_COARSE_LOCATION must be inserted. Furthermore that permission needs to be requested, e.g. in the onCreate method of your main activity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    String[] PERMS_INITIAL={
            Manifest.permission.ACCESS_FINE_LOCATION,
    };
    ActivityCompat.requestPermissions(this, PERMS_INITIAL, 127);
}

这篇关于Android Wifi 扫描 - 未调用 SCAN_RESULTS_AVAILABLE_ACTION 的 BroadcastReceiver的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆