androidandroid-emulatorbluestacksandroid-connectivitymanager

Callback for ConnectivityManager not working in BlueStacks 5 emulator


In order to get notified when the device connects/disconnects from internet, I took the following approach:

        ConnectivityManager connectivityManager = activity.getSystemService(ConnectivityManager.class);

        ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() {
            @Override
            public void onAvailable(@NonNull Network network) {
                super.onAvailable(network);
                try {
                    activity.runOnUiThread(() -> {
                        tvNoInternet.animate().alpha(0f).setListener(new AnimatorListenerAdapter() {
                            @Override
                            public void onAnimationEnd(Animator animation) {
                                super.onAnimationEnd(animation);
                                MiscellaneousUtils.hideView(tvNoInternet, View.GONE);
                            }
                        });
                        behaviour.onConnected();
                        // behaviour is an interface named NetworkConnectionBehaviour (check the following snippet for its implementation)
                    });
                } catch (IllegalStateException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onLost(@NonNull Network network) {
                super.onLost(network);
                try {
                    activity.runOnUiThread(() -> {
                        if (isInternetConnected(activity)) {
                            // check internet connection status because onLost() is called
                            // after onAvailable() when the device automatically switches
                            // internet connection from cellular to wifi
                            return;
                        }
                        tvNoInternet.animate().alpha(1f).setListener(new AnimatorListenerAdapter() {
                            @Override
                            public void onAnimationStart(Animator animation) {
                                super.onAnimationStart(animation);
                                MiscellaneousUtils.showView(tvNoInternet);
                            }
                        });
                        behaviour.onDisconnected();
                    });
                } catch (IllegalStateException e) {
                    e.printStackTrace();
                }
            }
        };

        try {
            NetworkRequest networkRequest = getNetworkRequest(); 
            // implementation of getNetworkRequest() is added in next snippet
            connectivityManager.registerNetworkCallback(networkRequest, networkCallback);
        } catch (Exception e) {
            Toast.makeText(activity, "Unexpected interruption! please try again later", Toast.LENGTH_SHORT).show();
        }

Interface NetowrkConnectionBehaviour:

    public interface NetworkConnectionBehaviour {
        void onConnected();

        void onDisconnected();
    }

Implementation of getNetworkRequest():

    public static NetworkRequest getNetworkRequest() {
        return new NetworkRequest.Builder()
                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
                .build();
    }

This approach is working in all physical devices and emulator of android studio.

However, if someone runs the app on Bluestacks 5 emulator, the callbacks of ConnectivityManager aren't called at all. And it does not produce any exception either.

Am I missing something here? Is there a different way to use ConnectivityManager for BlueStacks?

NOTE: It shows same behaviour for gameloop emulator too.


Solution

  • The solution is to remove transport types: TRANSPORT_WIFI and TRANSPORT_CELLULAR since the BlueStacks 5 Emulator does not recognize its connection to be one of those transport types.

    The capability NET_CAPABILITY_INTERNET will ensure that the connection is working and has access to the internet as per docs:

    Indicates that this network should be able to reach the internet.

    The code for the NetworkRequest now should be as follows:

    public static NetworkRequest getNetworkRequest() {
        return new NetworkRequest.Builder()
            .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
            .build();
    }