Android: Как определить скорость сети в Android программно

#java #android #kotlin-android-extensions

#java #Android #kotlin-android-расширения

Вопрос:

Как показать пользователю медленное подключение к Интернету при подключении к сети Примечание: Не тип сети (2G, 3G, 4G, WIFI)

Комментарии:

1. developer.android.com/training/basics/network-ops/managing.html

Ответ №1:

Определение скорости вашей сети — (медленная скорость Интернета)

Используя класс NetworkInfo, ConnectivityManager и TelephonyManager для определения типа вашей сети.

Загрузите любой файл из Интернета и подсчитайте, сколько времени это заняло, в зависимости от количества байтов в файле. (Единственный возможный способ определения проверки скорости)

Я попробовал приведенную ниже логику для своих проектов, вы также изучили это, надеюсь, это поможет вам.

 ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = cm.getActiveNetworkInfo();
    //should check null because in airplane mode it will be null
    NetworkCapabilities nc = cm.getNetworkCapabilities(cm.getActiveNetwork());
    int downSpeed = nc.getLinkDownstreamBandwidthKbps();
    int upSpeed = nc.getLinkUpstreamBandwidthKbps();
  

Комментарии:

1. Для этого требуется API уровня 21

2. для этого требуется API уровня 23

3. Getlink upstreambandwidthkbps и getLinkDownstreamBandwidthKbps в разных сетях всегда возвращают одно и то же значение. Почему?

4. Я тоже получил те же значения. Я думаю, что это не сработает, поскольку это может вернуть только максимальную пропускную способность, поддерживаемую сетью. В моем случае он возвращает 1048576, то есть 1 Гбит / с, что невозможно в сети, к которой я подключился. Во-вторых, название класса «NetworkCapabilities» само по себе говорит о возможностях сети, поэтому оно указывает на максимальные возможности этой сети.

5. Это не работает, как они сказали, это возвращает максимальную скорость загрузки в сети

Ответ №2:

Проверьте скорость Интернета для мобильной сети, чтобы использовать этот код

 ConnectivityManager connectivityManager = (ConnectivityManager)this.getSystemService(CONNECTIVITY_SERVICE);
NetworkCapabilities nc = connectivityManager.getNetworkCapabilities(connectivityManager.getActiveNetwork());
var downSpeed = nc.getLinkDownstreamBandwidthKbps();
var upSpeed = nc.getLinkUpstreamBandwidthKbps();
  

Если проверить скорость Интернета для сети Wi-Fi, чтобы использовать этот код

 public int getWifiLevel()
{
    WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    int linkSpeed = wifiManager.getConnectionInfo().getRssi();
    int level = WifiManager.calculateSignalLevel(linkSpeed, 5);
    return level;
}
  

И более подробную информацию смотрите по этой ссылке

https://android.jlelse.eu/designing-android-apps-to-handle-slow-network-speed-dedc04119aac

Я надеюсь, что это может вам помочь!

Спасибо.

Ответ №3:

Требуется минимум api: 21. Я использую ConnectivityManager в сочетании с NetworkCapabilities , чтобы получить как нисходящую, так и восходящую пропускную способность. Работает просто отлично. Вы можете решить, является ли скорость уровнем 2G, 3G или 4G, основываясь на скорости в кбит /с.

 ConnectivityManager cm = (ConnectivityManager)this.getSystemService(CONNECTIVITY_SERVICE);
NetworkCapabilities nc = cm.getNetworkCapabilities(cm.getActiveNetwork());
var downSpeed = nc.getLinkDownstreamBandwidthKbps();
var upSpeed = nc.getLinkUpstreamBandwidthKbps();
  
  • 2G GSM ~ 14,4 Кбит/с
  • G GPRS ~ 26,8 Кбит/с
  • E EDGE ~ 108,8 Кбит/с
  • 3G UMTS ~ 128 Кбит/с
  • H HSPA ~ 3,6 Мбит /с
  • H HSPA ~ 14,4 Мбит / с -23,0 Мбит /с
  • 4G LTE ~ 50 Мбит /с
  • 4G LTE-A ~ 500 Мбит /с

Загрузка файла — это чрезмерная разработка решения, потому что, в конце концов, вы не несете ответственности за подключение пользователей к Интернету — это они (или, скорее, их поставщик услуг)! Предоставления им информации на основе их текущего состояния более чем достаточно для большинства вариантов использования. Это дает вам быстрый способ проверки текущей скорости соединения перед выполнением операций.

Ответ №4:

ОБНОВЛЕНИЕ — УСТАРЕВШАЯ БИБЛИОТЕКА — больше не поддерживается

оригинальное сообщение:

Вы можете использовать класс сетевого подключения Facebook.

Его ConnectionClassStateChangeListener имеет вызываемый метод, onBandwidthStateChange который возвращает экземпляр класса ConnectionQuality:

 public interface ConnectionClassStateChangeListener {
  public void onBandwidthStateChange(ConnectionQuality bandwidthState);
}
  

Класс ConnectionQuality — это класс enum, определенный следующим образом:

 public enum ConnectionQuality {
  /**
   * Bandwidth under 150 kbps.
   */
  POOR,
  /**
   * Bandwidth between 150 and 550 kbps.
   */
  MODERATE,
  /**
   * Bandwidth between 550 and 2000 kbps.
   */
  GOOD,
  /**
   * EXCELLENT - Bandwidth over 2000 kbps.
   */
  EXCELLENT,
  /**
   * Placeholder for unknown bandwidth. This is the initial value and will stay at this value
   * if a bandwidth cannot be accurately found.
   */
  UNKNOWN
}
  

Комментарии:

1. Извините за отрицательный отзыв :(. Библиотека, на которую вы указали, не обновлялась с 2015 года и сообщала о проблемах с Android 9 . Я бы не советовал использовать эту библиотеку, если она не будет обновлена в будущем (если это когда-нибудь произойдет, я удалю свой downvote. Обещаю :))

2. я преобразовал этот репозиторий в kotlin, и он работает в Android 10. проверьте это здесь

3. @BhavinPatel репозиторий все еще там?

4. @tbfp извините : (Я не знаю, как и когда это было удалено.

Ответ №5:

Вы не можете проверить это напрямую.

Однако вы могли бы либо выполнить пинг сервера и посмотреть, занимает ли ответ очень много времени, либо вообще не возвращается.

Вы также могли бы выполнить speedtest. В большинстве приложений это не имело бы особого смысла, хотя, потому что это накладно на данные пользователя.

Комментарии:

1. У вас есть фрагмент кода о том, как это можно сделать?

2. Фрагмент кода для пинга? Или вы имеете в виду один для speedtest, чтобы затем рассчитать скорость загрузки кбит /с?

Ответ №6:

Самое основное, что вы можете сделать, это проверить URL, время безотказной работы которого составляет почти 100%, как, скажем, www.google.com . С момента запуска запроса и до его завершения вы можете просто измерить объем данных, загруженных вами для запроса. Итак, у вас есть данные (пространство) и затраченное время. Просто разделите пространство на время, чтобы получить скорость сети. Это несколько неточно, потому что это также зависит от URL, который вы просматриваете.

Ответ №7:

Кажется, что Android не позволяет этого напрямую. Вы можете попробовать загрузить какой-нибудь файл, чтобы определить скорость вашего интернета. Ниже приведен список свойств соединения:

  • ПЛОХАЯ / / пропускная способность менее 150 кбит / с.
  • УМЕРЕННАЯ / / Пропускная способность между 150 и 550 кбит /с.
  • ХОРОШАЯ // пропускная способность более 2000 кбит /с.
  • ОТЛИЧНО // Пропускная способность более 2000 кбит /с.
  • НЕИЗВЕСТНО // качество соединения не может быть найдено.

Вы можете подробно ознакомиться с этой статьейhttps://android.jlelse.eu/designing-android-apps-to-handle-slow-network-speed-dedc04119aac

Ответ №8:

Получить скорость сети и тип сети

 class NetworkUtils {

  companion object {

    // returns 102 Mbps
    fun getNetworkSpeed(context: Context): String {
        val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val nc = cm.getNetworkCapabilities(cm.activeNetwork)
            val downSpeed = (nc?.linkDownstreamBandwidthKbps)?.div(1000)
            "${downSpeed ?: 0} Mbps"
        } else {
            "-"
        }
    }

    // returns 2G,3G,4G,WIFI
    fun getNetworkClass(context: Context): String {
        val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val info = cm.activeNetworkInfo
        if (info == null || !info.isConnected) return "-" // not connected
        if (info.type == ConnectivityManager.TYPE_WIFI) return "WIFI"
        if (info.type == ConnectivityManager.TYPE_MOBILE) {
            return when (info.subtype) {
                TelephonyManager.NETWORK_TYPE_GPRS, TelephonyManager.NETWORK_TYPE_EDGE, TelephonyManager.NETWORK_TYPE_CDMA, TelephonyManager.NETWORK_TYPE_1xRTT, TelephonyManager.NETWORK_TYPE_IDEN, TelephonyManager.NETWORK_TYPE_GSM -> "2G"
                TelephonyManager.NETWORK_TYPE_UMTS, TelephonyManager.NETWORK_TYPE_EVDO_0, TelephonyManager.NETWORK_TYPE_EVDO_A, TelephonyManager.NETWORK_TYPE_HSDPA, TelephonyManager.NETWORK_TYPE_HSUPA, TelephonyManager.NETWORK_TYPE_HSPA, TelephonyManager.NETWORK_TYPE_EVDO_B, TelephonyManager.NETWORK_TYPE_EHRPD, TelephonyManager.NETWORK_TYPE_HSPAP, TelephonyManager.NETWORK_TYPE_TD_SCDMA -> "3G"
                TelephonyManager.NETWORK_TYPE_LTE, TelephonyManager.NETWORK_TYPE_IWLAN, 19 -> "4G"
                else -> "?"
            }
        }
        return "?"
    }

  }
}
  

Ответ №9:

Есть два способа решить эту проблему.

  1. Напишите код, чтобы программно проверить, сколько времени занимает загрузка небольшого файла, и определите вашу пропускную способность — я использовал это, и это довольно точно, учитывая местоположение сервера. Я, конечно, использовал Google image на сервере Google. Однако, чем больше файл, тем точнее результат.

  2. Используйте JSpeedTest — я не пробовал это, но это должно работать нормально. Обратите внимание, он использует файл размером 1 мб.

Для решения 1:

  public static float bandwidth( Context context) {
    int len;
    int size = 1024;
    byte[] buf;

    String imageurl = "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png";
    InputStream is = null;
    long start = System.currentTimeMillis();
    long end = 0L;
    float bandwidth=0.0f;
    try{
        Log.d("Network", imageurl);
        URL url = new URL(imageurl);
        URLConnection urlConn = url.openConnection();
        HttpURLConnection httpConn = (HttpURLConnection) urlConn;
        httpConn.connect();

        is = httpConn.getInputStream();
        if (is instanceof ByteArrayInputStream) {
            size = is.available();
            buf = new byte[size];
            len = is.read(buf, 0, size);
        } else {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            buf = new byte[size];
            while ((len = is.read(buf, 0, size)) != -1)
                bos.write(buf, 0, len);
            buf = bos.toByteArray();
        }

        Log.d("Network", "ImageSize:" buf.length);
        end = System.currentTimeMillis();
        Log.d("Network", "time:" end);

        // Bandwidth : size(B/1000)=KB
        //That is KiloBytes per secs
        float kilobytesDownloaded = buf.length/1000;

        //Get the duration, convert milliseconds to seconds
        float diff = end-start;
        float duration = (float)(diff/1000);
        Log.d("Network", "duration in secs:" duration);

        bandwidth = (float)kilobytesDownloaded / duration;

        Log.d("Network", "difference:" (end-start));
        Log.d("Network", "bandwidth:" bandwidth "kb/s");
    }catch (MalformedURLException e){
        e.printStackTrace();
    }catch (IOException e){
        e.printStackTrace();
    }

    return bandwidth;
}
  

Ваш примерный результат должен выглядеть примерно так:

  • Размер изображения: 5969 байт
  • разница во времени: 129 мс
  • длительность в секундах: 0,129с
  • пропускная способность: 38.759693 кб / с

Для решения 2: нажмите на ссылку, реализация находится на странице. С его помощью вы можете получить как скорость загрузки, так и выгрузки.