Обнаружение изменений состояния с помощью BroadcastReceiver не работает - PullRequest
0 голосов
/ 17 мая 2018

Я пытаюсь обнаружить изменения состояния wifi, mobile data, bluetooth и location, используя broadcastreceiver. вот как я это делаю:

    StateChangeReceiver stateChangeReceiver = new StateChangeReceiver();

    WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
    ConnectivityManager conManager = (ConnectivityManager)getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
    LocationManager locationManager = (LocationManager)getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
    BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

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

    IntentFilter bluetooth = new IntentFilter(bluetoothAdapter.ACTION_STATE_CHANGED);
    IntentFilter wifi = new IntentFilter(wifiManager.WIFI_STATE_CHANGED_ACTION);
    IntentFilter gps = new IntentFilter(locationManager.PROVIDERS_CHANGED_ACTION);
    IntentFilter data = new IntentFilter(conManager.CONNECTIVITY_ACTION);
    registerReceiver(stateChangeReceiver, bluetooth);
    registerReceiver(stateChangeReceiver, wifi);
    registerReceiver(stateChangeReceiver , gps);
    registerReceiver(stateChangeReceiver , data);
}

@Override
protected void onStop() {
    super.onStop();
    unregisterReceiver(stateChangeReceiver);
}

 private class  StateChangeReceiver extends BroadcastReceiver  {
    @Override
    public void onReceive (Context context, Intent intent) {
        if (intent.getAction().equals(wifiManager.WIFI_STATE_CHANGED_ACTION)) {
            WifiStateChanged(intent);
        } else if(intent.getAction().equals(bluetoothAdapter.ACTION_STATE_CHANGED)) {
            BluetoothStateChanged(intent);
        } else if(intent.getAction().equals(locationManager.PROVIDERS_CHANGED_ACTION)) {
            GpsSwitchStateChanged(context , intent);
        }  else if(intent.getAction().equals(conManager.CONNECTIVITY_ACTION)) {
            DataStateChanged(intent);
        }
    }
};

private void WifiStateChanged (Intent intent){
     int wifiStateExtra = intent.getIntExtra(wifiManager.EXTRA_WIFI_STATE, wifiManager.WIFI_STATE_UNKNOWN);
     if (wifiStateExtra == wifiManager.WIFI_STATE_ENABLED)
            ((ImageView) launcher.findViewById(R.id.wifi_button)).setImageResource(R.drawable.ic_wifi_orange_24dp);
     else if (wifiStateExtra == wifiManager.WIFI_STATE_DISABLED)
            ((ImageView) launcher.findViewById(R.id.wifi_button)).setImageResource(R.drawable.ic_wifi_white_24dp);
};

private void DataStateChanged (Intent intent) {
    NetworkInfo netInfo = conManager.getActiveNetworkInfo();

    if (netInfo != null && netInfo.getType() == ConnectivityManager.TYPE_MOBILE)
        ((ImageView) launcher.findViewById(R.id.data_button)).setImageResource(R.drawable.ic_data_orange_24dp);
    else
        ((ImageView) launcher.findViewById(R.id.data_button)).setImageResource(R.drawable.ic_data_white_24dp);
};

private void BluetoothStateChanged (Intent intent){
    String action = intent.getAction();
    if (bluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
        if(intent.getIntExtra(bluetoothAdapter.EXTRA_STATE, -1) == bluetoothAdapter.STATE_ON)
            ((ImageView) launcher.findViewById(R.id.bluetooth_button)).setImageResource(R.drawable.ic_bluetooth_orange_24dp);
        else if(intent.getIntExtra(bluetoothAdapter.EXTRA_STATE, -1) == bluetoothAdapter.STATE_OFF)
            ((ImageView) launcher.findViewById(R.id.bluetooth_button)).setImageResource(R.drawable.ic_bluetooth_white_64dp);

    }
};

private void GpsSwitchStateChanged (Context context,Intent intent){
    int locationMode=0;
    try
    {
        locationMode = android.provider.Settings.Secure.getInt(context.getContentResolver(), android.provider.Settings.Secure.LOCATION_MODE);

    } catch (android.provider.Settings.SettingNotFoundException e)
    {
        e.printStackTrace();
    }

    if (locationMode == android.provider.Settings.Secure.LOCATION_MODE_SENSORS_ONLY
            || locationMode == android.provider.Settings.Secure.LOCATION_MODE_HIGH_ACCURACY
            ||locationMode == android.provider.Settings.Secure.LOCATION_MODE_BATTERY_SAVING )
        ((ImageView) launcher.findViewById(R.id.location_button)).setImageResource(R.drawable.ic_location_orange_24dp);
    else if (locationMode == android.provider.Settings.Secure.LOCATION_MODE_OFF) {
        ((ImageView) launcher.findViewById(R.id.location_button)).setImageResource(R.drawable.ic_location_white_24dp);
    }
};

Я также добавил разрешение, которое мне хотя и было необходимо:

<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_GPS" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION" />

Но отслеживаются только те изменения, которые wifi изменяют состояние, а остальные не запускают StateChangeReceiver. Я в замешательстве, почему это не работает?

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

Вы вызываете registerReceiver несколько раз, что приводит к выполнению только последней строки. Попробуйте использовать

IntentFilter intentFilter = new IntentFilter(); 
intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
intentFilter.addAction(LocationManager.PROVIDERS_CHANGED_ACTION);
intentFilter.addAction(ConnectionManager.CONNECTIVITY_ACTION);

registerReceiver(mReceiver, intentFilter); 

Вы можете прослушивать действия только в одном приемнике и извлекать их в соответствии с действием, например:

   private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();

            if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
               .....
            } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
               ...
            }
        }
    };
0 голосов
/ 17 мая 2018

Попробуйте зарегистрировать только один BroadcastReceiver с уникальным IntentFilter со всеми действиями.Например:

IntentFilter intentFilter = new IntentFilter(); 
intentFilter.addAction(bluetoothAdapter.ACTION_STATE_CHANGED);
intentFilter.addAction(wifiManager.WIFI_STATE_CHANGED_ACTION);
intentFilter.addAction(locationManager.PROVIDERS_CHANGED_ACTION);
intentFilter.addAction(conManager.CONNECTIVITY_ACTION);

registerReceiver(stateChangeReceiver, intentFilter); 

Таким образом, вы имитируете объявление BroadcastReceiver, как в Manifest:

    <receiver
        android:name="YourReceiver">
        <intent-filter>
            <action android:name="action1"/>
            <action android:name="action2"/>
        </intent-filter>
    </receiver>

Другое решение состоит в создании одного BroadcastReceiver для каждого действия, как я вижу, у вас естьодин метод для каждого действия, чтобы разобрать его.Не без ума от создания 4 BroadcastReceiver и выполнения логики каждого действия внутри его BroadcastReceiver.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...