Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

call broadcast receiver random times when wi-fi state change in android 4.2.2

Tags:

android

My goal is print log when change wi-fi state.

I use below code.

MainActivity.java (Main Activity)

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        startService(new Intent(this,WiFiService.class));
    }
    @Override
    protected void onStart() 
    {
        super.onStart();
        Log.d("Start Service", "Start Service");;
        startService(new Intent(this,WiFiService.class));
    }
}

WiFiService.java (Service)

public class WiFiService extends Service
{

    WiFiBroadCasetReceiver brod;
    @Override
    public IBinder onBind(Intent intent) 
    {
        return null;
    }
    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        brod=new WiFiBroadCasetReceiver();
        this.registerReceiver(brod, new IntentFilter(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION));
    }

    @Override
    public void onDestroy() 
    {
        super.onDestroy();
    }
}

WiFiBroadCasetReceiver.java (BroadcastReceiver)

public class WiFiBroadCasetReceiver extends BroadcastReceiver
{

    @Override
    public void onReceive(Context arg0, Intent arg1) 
    {
        Log.d("on receiver", "receiver");
    }

}

AndroidManifest.xml

<application>
        ........
        ........

        <receiver android:name=".WiFiBroadCasetReceiver" >
            <intent-filter>
                <action android:name="android.net.wifi.supplicant.STATE_CHANGE" />
            </intent-filter>
        </receiver>
</application>

Problem :

Above code is working fine in android 4.0 and lower versions. When I change state of wi-fi, broadcast receiver is call random times. So, log is print random times. I need only one time. It work fine all android version remains android 4.1.0. or higher version(Jelly Bean). I use android.net.wifi.WIFI_STATE_CHANGED. But still same error occur.

like image 390
kels Avatar asked Jan 12 '23 17:01

kels


2 Answers

Several points should be addressed in your question.

First, you might be confusing the state of "android.net.wifi.supplicant.STATE_CHANGE" and "android.net.wifi.WIFI_STATE_CHANGED". And I think what you really want is the later one. See the comment from the source code.

/**
 * 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";

and

/**
 * Broadcast intent action indicating that a connection to the supplicant has
 * been established (and it is now possible
 * to perform Wi-Fi operations) or the connection to the supplicant has been
 * lost. One extra provides the connection state as a boolean, where {@code true}
 * means CONNECTED.
 * @see #EXTRA_SUPPLICANT_CONNECTED
 */
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String SUPPLICANT_CONNECTION_CHANGE_ACTION =
    "android.net.wifi.supplicant.CONNECTION_CHANGE";

Second, why you got multiple broadcast callbacks? And the number of times is random? I think you might need to check your code carefully:

1. You start the service twice, once in Activity.onCreate() and once in Activity.onStart()
2. You register your broadcast receiver twice, once in AndroidManifest.xml and once in Service.onStart()
3. The most important thing is that you will create a new instance of your broadcast receiver instance in your Service.onStart(). That is to say, whenever your service is start, a new receiver will be created and registered. And looking back on 1, you see every time you bring you Activity back will call the service to start again.

So the random times of callback is because your bad code. Please just remove all the broadcast registers, left only the one in the AndroidManifest.xml

Finally, why you cannot make it work on JellyBean later? I think this is because you haven't specified the correct action. Please try "android.net.wifi.WIFI_STATE_CHANGED" instead of "android.net.wifi.supplicant.STATE_CHANGE" and try again.

like image 56
Robin Avatar answered Apr 08 '23 00:04

Robin


The broadcast is received whenever the supplicant state of the wifi changes. Since over the course of establishing a connection this will change multiple times, multiple broadcasts are expected. (I remember having seen this on 2.3 devices also but I mostly use the connectivity change broadcast to check connectivity change so I might be incorrect).

The workaround you can do is, in your broadcast receiver check the extras include in the intent which indicates the SupplicantState. If the supplicant state in the extra is equal to SupplicantState.COMPLETED (wifi is connected and authenticated) then only implement your app logic otherwise ignore the broadcast.

like image 42
Srikant Sahay Avatar answered Apr 08 '23 00:04

Srikant Sahay