0

It is possibile in Android to intercept switching between 3g and GPRS, LTE, EDGE with a broadcast receiver to call a method when mobile data connection changes?

Attention: the problem is not how can i get informations, but how can i INTERCEPT the EVENT!

Thank you.

Update: I accept answer with NDK ;) because, probably, is not possibile with SDK :(

Stefano Cappa
  • 575
  • 3
  • 17
  • These might help you http://stackoverflow.com/a/9703409/1979347 and http://stackoverflow.com/a/24191919/1979347 – Rohan Kandwal Dec 27 '14 at 14:35
  • One more for you http://stackoverflow.com/q/9283765/1979347 – Rohan Kandwal Dec 27 '14 at 14:41
  • The first method is not working. The problem is still open, like and-dev says in the last comment. The second one is not working, because i tried with the 3 event not in wifi package without success. – Stefano Cappa Dec 27 '14 at 15:00
  • The third solution is not an answer because i want to intercept THE EVENT and not to call a method to get the network type (this is very simple). – Stefano Cappa Dec 27 '14 at 15:05
  • You are making us confuse. What do you mean by 'i want to intercept'? Please clarify. – Rohan Kandwal Dec 27 '14 at 20:53
  • I mean the event. I want a system that automatically call a method when the mobile connectivity changes. I don't want to call anything. When the connection changes, a receiver starts and execute automatically some code. If i want to realize this between wifi and mobile data is extremely simple (like in the page that you posted), but between edge and 3G for example it's not working. – Stefano Cappa Dec 27 '14 at 23:51
  • Ok probably is not possibile to use this function. I read a huge amount of q&a on stackoverflow without success. If someone has other ideas please write ;) – Stefano Cappa Dec 29 '14 at 14:38

1 Answers1

1

You need to use ConnectivityManager

The primary responsibilities of this class are to:

  1. Monitor network connections (Wi-Fi, GPRS, UMTS, etc.)
  2. Send broadcast intents when network connectivity changes
  3. Attempt to "fail over" to another network when connectivity to a network is lost
  4. Provide an API that allows applications to query the coarse-grained or fine-grained state of the available networks
  5. Provide an API that allows applications to request and select networks for their data traffic

See training Determining and Monitoring the Connectivity Status

Update:

According answer Emil Davtyan

If the problem is to find whether the phone's network is connected and fast enough to meet your demands you have to handle all the network types returned by getSubType().

It took me an hour or two to research and write this class to do just exactly that, and I thought I would share it with others that might find it useful.

Here is a Gist of the class, so you can fork it and edited it.

package com.emil.android.util;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.telephony.TelephonyManager;

/**
 * Check device's network connectivity and speed 
 * @author emil https://stackoverflow.com/users/220710/emil
 *
 */
public class Connectivity {

  /**
   * Get the network info
   * @param context
   * @return
   */
  public static NetworkInfo getNetworkInfo(Context context){
      ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
      return cm.getActiveNetworkInfo();
  }

  /**
   * Check if there is any connectivity
   * @param context
   * @return
   */
  public static boolean isConnected(Context context){
      NetworkInfo info = Connectivity.getNetworkInfo(context);
      return (info != null && info.isConnected());
  }

  /**
   * Check if there is any connectivity to a Wifi network
   * @param context
   * @param type
   * @return
   */
  public static boolean isConnectedWifi(Context context){
      NetworkInfo info = Connectivity.getNetworkInfo(context);
      return (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_WIFI);
  }

  /**
   * Check if there is any connectivity to a mobile network
   * @param context
   * @param type
   * @return
   */
  public static boolean isConnectedMobile(Context context){
      NetworkInfo info = Connectivity.getNetworkInfo(context);
      return (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_MOBILE);
  }

  /**
   * Check if there is fast connectivity
   * @param context
   * @return
   */
  public static boolean isConnectedFast(Context context){
      NetworkInfo info = Connectivity.getNetworkInfo(context);
      return (info != null && info.isConnected() && Connectivity.isConnectionFast(info.getType(),info.getSubtype()));
  }

  /**
   * Check if the connection is fast
   * @param type
   * @param subType
   * @return
   */
  public static boolean isConnectionFast(int type, int subType){
      if(type==ConnectivityManager.TYPE_WIFI){
          return true;
      }else if(type==ConnectivityManager.TYPE_MOBILE){
          switch(subType){
          case TelephonyManager.NETWORK_TYPE_1xRTT:
              return false; // ~ 50-100 kbps
          case TelephonyManager.NETWORK_TYPE_CDMA:
              return false; // ~ 14-64 kbps
          case TelephonyManager.NETWORK_TYPE_EDGE:
              return false; // ~ 50-100 kbps
          case TelephonyManager.NETWORK_TYPE_EVDO_0:
              return true; // ~ 400-1000 kbps
          case TelephonyManager.NETWORK_TYPE_EVDO_A:
              return true; // ~ 600-1400 kbps
          case TelephonyManager.NETWORK_TYPE_GPRS:
              return false; // ~ 100 kbps
          case TelephonyManager.NETWORK_TYPE_HSDPA:
              return true; // ~ 2-14 Mbps
          case TelephonyManager.NETWORK_TYPE_HSPA:
              return true; // ~ 700-1700 kbps
          case TelephonyManager.NETWORK_TYPE_HSUPA:
              return true; // ~ 1-23 Mbps
          case TelephonyManager.NETWORK_TYPE_UMTS:
              return true; // ~ 400-7000 kbps
          /*
           * Above API level 7, make sure to set android:targetSdkVersion 
           * to appropriate level to use these
           */
          case TelephonyManager.NETWORK_TYPE_EHRPD: // API level 11 
              return true; // ~ 1-2 Mbps
          case TelephonyManager.NETWORK_TYPE_EVDO_B: // API level 9
              return true; // ~ 5 Mbps
          case TelephonyManager.NETWORK_TYPE_HSPAP: // API level 13
              return true; // ~ 10-20 Mbps
          case TelephonyManager.NETWORK_TYPE_IDEN: // API level 8
              return false; // ~25 kbps 
          case TelephonyManager.NETWORK_TYPE_LTE: // API level 11
              return true; // ~ 10+ Mbps
          // Unknown
          case TelephonyManager.NETWORK_TYPE_UNKNOWN:
          default:
              return false;
          }
      }else{
          return false;
      }
  }

}

Also make sure to add this permission to you AndroidManifest.xml

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

Sources for network speeds include wikipedia & http://3gstore.com/page/78_what_is_evdo_mobile_broadband.html

Community
  • 1
  • 1
gio
  • 4,950
  • 3
  • 32
  • 46
  • I tried with CONNECTIVITY_ACTION and other types of event without success. CONNECTIVITY_ACTION works only between wifi and mobile data. – Stefano Cappa Dec 27 '14 at 15:01
  • 1
    It should work between different mobile connections too (in fact it does, tested). When you receive the action, call `ConnectivityManager.getActiveNetworkInfo()` and then `NetworkInfo.getSubtype()`. [This answer](http://stackoverflow.com/a/8548926/2444099) should give you everything you need. – Eugen Pechanec Dec 27 '14 at 15:07
  • I'm using exactly this class for other purposes. But, my problem is the EVENT, not how call a method to get informations. – Stefano Cappa Dec 27 '14 at 15:18