Tuesday, September 25, 2018

ConnectionManager not giving network callbacks when using `TRANSPORT_CELLULAR`

Leave a Comment

I'm trying to receive callbacks whenever the phone's cellular data connection changes. I essentially need to know when it turns off and when it turns on.

I used to do this with the TelephonyManager and PhoneStateListener.LISTEN_SERVICE_STATE, but now I want to use the ConnectionManager with registerNetworkCallback.

The following code sample has been tried on an Android Emulator (API 28), A HUAWEI P20 Lite (API 26), an HTC One M8 (API 23), and a Motorola G6 (API 26). None of them call any callbacks when I switch mobile data on/off, or activate airplane mode.

People say this should work.

    NetworkRequest.Builder builder = new NetworkRequest.Builder();      builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);     builder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);      connManager.registerNetworkCallback(builder.build(), new ConnectivityManager.NetworkCallback() {         @Override         public void onAvailable(Network network) {             Log.d("Conman Test", "onAvailable");         }          @Override         public void onLost(Network network) {             Log.d("Conman Test", "onLost");         }          @Override         public void onUnavailable() {             Log.d("Conman Test", "onUnavailable");         }          @Override         public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {             Log.d("Conman Test", "onCapabilitiesChanged");         }          @Override         public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {             Log.d("Conman Test", "onLinkPropertiesChanged");         }     }); 

I have tried NetworkCapabilities.TRANSPORT_WIFI, and it works fine on all the devices. So why not NetworkCapabilities.TRANSPORT_CELLULAR?

1 Answers

Answers 1

I haven't tried to solve this problem using NetworkCapabilities , but I used an alternative approach to determine whether my device is connected via cellular or wifi.

I just registered a receiver

  <receiver android:name=".NetworkChangeReceiver" >             <intent-filter>                 <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />             </intent-filter>   </receiver> 

I added the permission

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> 

And then I did the following

public class NetworkChangeReceiver extends BroadcastReceiver {     @Override     public void onReceive(Context context, Intent intent) {         ConnectivityManager cm =                 (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);          NetworkInfo activeNetwork = cm.getActiveNetworkInfo();         boolean isConnected = activeNetwork != null &&                 activeNetwork.isConnectedOrConnecting();          if(activeNetwork ==null){             Log.d("Connectivity","Not connected");             return;         }          boolean isWiFi = activeNetwork.getType() == ConnectivityManager.TYPE_WIFI;          if(isConnected  && isWiFi){             Log.d("Connectivity","WIFI");         }else{             Log.d("Connectivity","CELLULAR");         }     } } 

For Oreo device you may need to register receiver in activity or service rather than manifest

As an example

public class MainActivity extends Activity {      IntentFilter filter1;      @Override     public void onCreate() {         filter1 = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");         registerReceiver(myReceiver, filter1);     }      //The BroadcastReceiver that listens for network change     private final BroadcastReceiver myReceiver = new BroadcastReceiver() {         @Override         public void onReceive(Context context, Intent intent) {             if(intent.getAction().equalsIgnoreCase("android.net.conn.CONNECTIVITY_CHANGE")) {                 Log.d(TAG,"connectivity change");               ConnectivityManager cm =             (ConnectivityManager)this.getSystemService(Context.CONNECTIVITY_SERVICE);          NetworkInfo activeNetwork = cm.getActiveNetworkInfo();         boolean isConnected = activeNetwork != null &&                 activeNetwork.isConnectedOrConnecting();          if(activeNetwork ==null){             Log.d("Connectivity","Not connected");             return;         }          boolean isWiFi = activeNetwork.getType() == ConnectivityManager.TYPE_WIFI;          if(isConnected  && isWiFi){             Log.d("Connectivity","WIFI");         }else{             Log.d("Connectivity","CELLULAR");         }             }         }     };      @Override     public void onDestroy() {         unregisterReceiver(myReceiver);     } } 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment