简体   繁体   中英

How to choose/enforce using mobile data (or wifi) for network calls on Android?

I have a crazy user case where there is a requirement to call some REST services only through mobile data (SIM). We'd like to send rest of the data through wifi.

Is it possible on Android to enforce through which kind of network to send data?

Is it possible in the same app and in the same session to send some data over mobile data and other through wifi?

Also, what would be the best way to test if the calls are sent over the right network type?

My use:

@TargetApi(21)
private fun getMobileNetWork() {
    connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    val builder = NetworkRequest.Builder()
    builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
    builder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)//TRANSPORT_WIFI
    val build = builder.build()
    connectivityManager!!.requestNetwork(build, networkCallback)
}


val networkCallback = object : ConnectivityManager.NetworkCallback() {
    override fun onAvailable(network: Network) {
        super.onAvailable(network)
        //Use the network to do your thing
    }

    override fun onLost(network: Network?) {
        super.onLost(network)
    }
    override fun onUnavailable() {
        super.onUnavailable()
    }
}

Network usage in okhttp3:

    val builder = OkHttpClient.Builder()
            .connectTimeout(15L, TimeUnit.SECONDS)
            .readTimeout(20L, TimeUnit.SECONDS)
            .writeTimeout(15L, TimeUnit.SECONDS)
            .socketFactory(network.socketFactory)
            .dns {
                network.getAllByName(it).asList()
            }

You can check which network type is avalible by using ConnectivityManager, if wifi is connected call your api else show dialog to user to inform him that this api required open wifi or the reverse..

You can use Connectivity class to check the network

public class Connectivity {

public static NetworkInfo getNetworkInfo(Context context){
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    return cm.getActiveNetworkInfo();
}


public static boolean isConnected(Context context){
    NetworkInfo info = Connectivity.getNetworkInfo(context);
    return (info != null && info.isConnected());
}

public static boolean isConnectedWifi(Context context){
    NetworkInfo info = Connectivity.getNetworkInfo(context);
    return (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_WIFI);
}

public static boolean isConnectedMobile(Context context){
    NetworkInfo info = Connectivity.getNetworkInfo(context);
    return (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_MOBILE);
}

public static boolean isConnectedFast(Context context){
    NetworkInfo info = Connectivity.getNetworkInfo(context);
    return (info != null && info.isConnected() && Connectivity.isConnectionFast(info.getType(),info.getSubtype()));
}

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;
    }
}

}

Check which Network type is available

if (isConnectedWifi(ctx) {
        // Call api
    }else if (isConnectedMobile(ctx)){
       // Show dialog to user to inform him that this api required open wifi
    }else{
       //
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM