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.
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); } }
0 comments:
Post a Comment