【问题标题】:SCAN_RESULTS_AVAILABLE_ACTION: BroadcastReceiver#onReceive not called on Android 7.0SCAN_RESULTS_AVAILABLE_ACTION:Android 7.0 上未调用 BroadcastReceiver#onReceive
【发布时间】:2017-09-16 22:01:58
【问题描述】:

我正在开发一款适用于 Android 的应用,我必须在其中扫描可用的 WiFi LAN。

我正在测试该应用程序,它可以在 Android 4.4 到 6.x 的设备上运行,但在 Nougat 上(实际上我已经在 2 种不同的设备上进行了测试,华为和 HTC,Android 7)@我的BroadcastReceiver 中的987654321@ 永远不会被调用。

如果我尝试使用 WIFI_STATE_CHANGED_ACTION,即使在 Android 7 上我也能收到此操作。

我查看了 Nougat 中的更改文档,但对此一无所获。为什么它不适用于牛轧糖?我必须添加/更改什么?

这是我的应用的精简版。

AndroidManifest.xml 我添加了:

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

MainActivity.java

public class MainActivity extends AppCompatActivity {
private ListView _listSSID;
private ArrayAdapter<String> _adapter;
private WiFiConnection _wifiConnection = null;

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

@Override
protected void onStart() {
    super.onStart();
    _wifiConnection = new WiFiConnection(this);
    _adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1,
            android.R.id.text1, _wifiConnection.getBestSSIDs());
    _listSSID = (ListView) findViewById(R.id.listSSID);
    _listSSID.setAdapter(_adapter);
    _listSSID.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            String ssid = _adapter.getItem(position);
            Log.d("OnClick", ssid);
        }
    });
    startScan();
}

@Override
protected void onStop() {
    super.onStop();

    _wifiConnection.stopScan();
    unregisterReceiver(_wifiScanReceiver);
}

void startScan() {
    checkPermission(this);

    registerReceiver(_wifiScanReceiver,
            new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
    Thread t = new Thread(_wifiConnection.getWifiScanner());
    t.start();
}

private final BroadcastReceiver _wifiScanReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context c, Intent intent) {
        if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
            if (_wifiConnection != null && _wifiConnection.isWifiEnabled()) {
                _wifiConnection.updateScanData("No WLANs found");
            }
            _adapter.notifyDataSetChanged();
        }
    }
};

static final int MY_PERMISSIONS_REQUEST = 1042;

private static final String PERMISSIONS_TAG = "PERMISSION";

@TargetApi(Build.VERSION_CODES.M)
public static boolean checkPermission(Activity activity) {
    boolean permission = true;
    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        permission = activity.checkSelfPermission(Manifest.permission.ACCESS_WIFI_STATE) == PackageManager.PERMISSION_GRANTED;
        Log.d(PERMISSIONS_TAG, "ACCESS_WIFI_STATE: " + permission);
        permission = activity.checkSelfPermission(Manifest.permission.CHANGE_WIFI_STATE) == PackageManager.PERMISSION_GRANTED;
        Log.d(PERMISSIONS_TAG, "CHANGE_WIFI_STATE: " + permission);
        permission = activity.checkSelfPermission(Manifest.permission.CHANGE_WIFI_MULTICAST_STATE) == PackageManager.PERMISSION_GRANTED;
        Log.d(PERMISSIONS_TAG, "CHANGE_WIFI_MULTICAST_STATE: " + permission);

        List<String> requiringList = new ArrayList<>();
        permission = activity.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
        Log.d(PERMISSIONS_TAG, "WRITE_EXTERNAL_STORAGE: " + permission);
        if (!permission) {
            requiringList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        }

        permission = activity.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED;
        Log.d(PERMISSIONS_TAG, "ACCESS_COARSE_LOCATION: " + permission);
        if (!permission) {
            requiringList.add(Manifest.permission.ACCESS_COARSE_LOCATION);
        }

        if (requiringList.size() > 0) {
            String[] stringArray = requiringList.toArray(new String[0]);
            activity.requestPermissions(stringArray, MY_PERMISSIONS_REQUEST);
        }
    }
    return permission;
}
}

WiFiConnection.java

class WiFiConnection
{
    private static final int SCAN_INTERVAL = 1200;

    final private List<String> _bestSSIDs = new ArrayList<>();

    private WifiManager _wifiManager;

    private final WiFiScanner _startScan = new WiFiScanner();

    WiFiConnection(Activity activity) {
        _wifiManager = (WifiManager) activity.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
    }

    List<String> getBestSSIDs() {return _bestSSIDs; }
    WiFiScanner getWifiScanner() { return _startScan; }
    void stopScan() { _startScan.stop(); }

    boolean isWifiEnabled() { return _wifiManager.isWifiEnabled(); }

    void updateScanData(final String noLansMsg) {
        if ((_wifiManager != null && _wifiManager.isWifiEnabled())) {
            List<ScanResult> scanResults = _wifiManager.getScanResults();
            Log.d("WiFi", "found nets: " + scanResults.size());

            // my sorting code
        }
    }

    private class WiFiScanner implements Runnable
    {
        private boolean _stop = false;
        public void stop() {_stop = true;}
        @Override
        public void run() {
            while (!_stop) {
                _wifiManager.startScan();
                try {
                    Thread.sleep(SCAN_INTERVAL);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

【问题讨论】:

    标签: android android-broadcastreceiver android-7.0-nougat


    【解决方案1】:

    在 Android 7.0 上似乎需要打开 GPS 才能接收 SCAN_RESULTS_AVAILABLE_ACTION。

    【讨论】:

      【解决方案2】:

      @TargetApi(Build.VERSION_CODES.M) 删除它,它只会为 Android M 执行,否则编写更大或等于 M 版本的代码。

      if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M){
          // Do something for M and above versions
      } else{
      

      【讨论】:

      • 我认为 TargetApi 注释仅用于 lint 工具的目的,在运行时没有结果。事实上,我已经收到了关于 Nougat 的许可请求。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多