Как выбрать/принудительно использовать мобильные данные (или Wi-Fi) для сетевых вызовов на Android?

У меня есть сумасшедший пользовательский случай, когда требуется вызывать некоторые службы REST только через мобильные данные (SIM). Мы хотели бы отправить остальные данные через Wi-Fi.

Возможно ли на Android принудительно указать, через какую сеть отправлять данные?

Возможно ли в том же приложении и в том же сеансе отправлять одни данные по мобильным данным, а другие через Wi-Fi?

Кроме того, как лучше всего проверить, отправляются ли звонки через правильный тип сети?


person daneejela    schedule 04.07.2019    source источник


Ответы (2)


Мое использование:

@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()
    }
}

Использование сети в 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()
            }
person JKXY    schedule 05.07.2019

Вы можете проверить, какой тип сети доступен, с помощью ConnectivityManager, если Wi-Fi подключен, вызовите ваш API, иначе отобразите диалоговое окно для пользователя, чтобы сообщить ему, что для этого API требуется открытый Wi-Fi или наоборот.

Вы можете использовать класс Connectivity для проверки сети

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

}

Проверьте, какой тип сети доступен

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