Search code examples
androidandroid-intentbroadcastreceiverwifimanager

android.net.wifi.STATE_CHANGE not broadcasting when wifi get enabled and WifiManager.EXTRA_WIFI_STATE not available


Manifest:

<receiver android:name=".triggers.WifiTrigger">
        <intent-filter>
            <action android:name="android.net.wifi.STATE_CHANGE" />
        </intent-filter>
    </receiver>

Permissions :

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />

The receiver is executed when WiFi is disabled, connected or disconnected (didn't check for connecting/disabling/enabling) but it is not triggered when WiFi is enabled, in addition WifiManager.EXTRA_WIFI_STATE extra is not available in the intent, i am using this :

public class WifiTrigger extends BroadcastReceiver {
    ...
    @Override
public void onReceive(Context context, Intent intent) {
    SharedPreferences preferences= PreferenceManager.getDefaultSharedPreferences(context);

    int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN);
    int previousWifiState = intent.getIntExtra(WifiManager.EXTRA_PREVIOUS_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN);
    log("p"+previousWifiState);
    log("c"+wifiState);
    //log is a defined method used for logging (it just calls Log.d(...,...)
    }
    ...
}

and it keeps logging p4 c4 (4 for WifiManager.WIFI_STATE_UNKNOWN)



Solution

  • You're registering for the wrong Intent action. What you're really looking for is:

    /**
     * Broadcast intent action indicating that Wi-Fi has been enabled, disabled,
     * enabling, disabling, or unknown. One extra provides this state as an int.
     * Another extra provides the previous state, if available.
     *
     * @see #EXTRA_WIFI_STATE
     * @see #EXTRA_PREVIOUS_WIFI_STATE
     */
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String WIFI_STATE_CHANGED_ACTION =
        "android.net.wifi.WIFI_STATE_CHANGED";
    

    The action you're registering for is for network state changes, not adapter state changes:

    /**
     * Broadcast intent action indicating that the state of Wi-Fi connectivity
     * has changed. One extra provides the new state
     * in the form of a {@link android.net.NetworkInfo} object. If the new
     * state is CONNECTED, additional extras may provide the BSSID and WifiInfo of
     * the access point.
     * as a {@code String}.
     * @see #EXTRA_NETWORK_INFO
     * @see #EXTRA_BSSID
     * @see #EXTRA_WIFI_INFO
     */
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String NETWORK_STATE_CHANGED_ACTION = 
        "android.net.wifi.STATE_CHANGE";
    

    So just changing your receiver registration from:

    <receiver android:name=".triggers.WifiTrigger">
        <intent-filter>
            <action android:name="android.net.wifi.STATE_CHANGE" />
        </intent-filter>
    </receiver>
    

    to

    <receiver android:name=".triggers.WifiTrigger">
        <intent-filter>
            <action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
        </intent-filter>
    </receiver>
    

    will fix your issue.