Я работаю над реализацией обнаружения низкой скорости Интернета в своем приложении. Однако он не работает должным образом — он сообщает о «низком интернете», даже если скорость интернета хорошая. Я хотел бы реализовать это без использования загрузки файлов, и я был бы очень признателен за ваши советы о том, как надежно обнаружить низкую скорость Интернета.
Найдите код, который я реализовал ниже.
Заранее спасибо.
public class NetworkQualityMonitor {
public interface NetworkQualityCallback {
void onQualityChecked(Quality quality, long latency, double jitter, double packetLoss);
}
public enum Quality {
GOOD, MODERATE, POOR
}
private final OkHttpClient client;
private final String pingUrl = "https://www.google.com";
private final int pingCount;
private final ExecutorService executor;
private final Handler mainHandler;
// --- Caching state ---
private long lastCheckTime = 0;
private Quality lastQuality = Quality.POOR;
private long lastLatency = -1;
private double lastJitter = -1;
private double lastPacketLoss = -1;
private static NetworkQualityMonitor networkQualityMonitor;
private static final long CACHE_DURATION_MS = 7000; // 5 sec
private boolean isChecking = false; // avoid parallel execution
private boolean isNavigatingToLowNetwork = false; // avoid multiple LowNetworkActivity launches
private NetworkQualityMonitor() {
this.client = new OkHttpClient.Builder().connectTimeout(3, TimeUnit.SECONDS).readTimeout(2, TimeUnit.SECONDS).build();
this.pingCount = 4;
this.executor = Executors.newSingleThreadExecutor();
this.mainHandler = new Handler(Looper.getMainLooper());
}
public synchronized static NetworkQualityMonitor getInstance() {
if (networkQualityMonitor == null) {
networkQualityMonitor = new NetworkQualityMonitor();
}
return networkQualityMonitor;
}
private boolean mapNetworkQuality(Quality quality, long latency, double jitter, double packetLoss) {
return quality == Quality.POOR;
}
public synchronized void checkQuality(Activity activity, boolean isFreshCheck, NetworkChecker.NetworkCheckCallback networkCheckCallback) {
long now = System.currentTimeMillis();
// --- If cached result is still valid, return immediately ---
if (now - lastCheckTime < CACHE_DURATION_MS && !isFreshCheck) {
mainHandler.post(() -> networkCheckCallback.onNetworkCheckCompleted(
lastQuality != Quality.POOR,
lastQuality == Quality.POOR,
0
));
if (lastQuality == Quality.POOR) {
retryCheck(activity, networkCheckCallback); // trigger retry
}
return;
}
runNetworkTest(activity, networkCheckCallback, false);
}
private void runNetworkTest(Activity activity, NetworkChecker.NetworkCheckCallback networkCheckCallback, boolean isRetry) {
executor.execute(() -> {
try {
Quality quality;
List rtts = new ArrayList();
int successCount = 0;
for (int i = 0; i < pingCount; i++) {
long start = System.currentTimeMillis();
Request request = new Request.Builder().url(pingUrl).tag("" + System.currentTimeMillis()).build();
try (Response response = client.newCall(request).execute()) {
if (response.isSuccessful()) {
successCount++;
long rtt = System.currentTimeMillis() - start;
rtts.add(rtt);
}
} catch (IOException ignored) {}
try { Thread.sleep(70); } catch (InterruptedException ignored) {}
}
// --- Latency ---
long avgLatency = rtts.isEmpty() ? -1 : rtts.stream().mapToLong(Long::longValue).sum() / rtts.size();
// --- Jitter ---
double jitter = 0;
for (int i = 1; i < rtts.size(); i++) {
jitter += Math.abs(rtts.get(i) - rtts.get(i - 1));
}
jitter = rtts.size() > 1 ? jitter / (rtts.size() - 1) : -1;
// --- Packet Loss ---
double packetLoss = 100.0 * (pingCount - successCount) / pingCount;
// --- Decide Quality ---
quality = decideQuality(avgLatency, jitter, packetLoss);
// --- Cache result ---
lastCheckTime = System.currentTimeMillis();
lastQuality = quality;
lastLatency = avgLatency;
lastJitter = jitter;
lastPacketLoss = packetLoss;
mainHandler.post(() -> {
if (quality == Quality.POOR) {
if (!isRetry) {
// First time poor → retry check
retryCheck(activity, networkCheckCallback);
} else {
// Second time also poor → navigate
networkCheckCallback.onNetworkCheckCompleted(false, true, 0);
navigateToLowNetworkActivity(activity);
}
} else {
networkCheckCallback.onNetworkCheckCompleted(true, false, 0);
}
});
} catch (Exception e) {
mainHandler.post(() -> networkCheckCallback.onNetworkCheckCompleted(true, false, 0));
}
});
}
private void retryCheck(Activity activity, NetworkChecker.NetworkCheckCallback networkCheckCallback) {
// Optional: Add a small delay before retry
mainHandler.postDelayed(() -> runNetworkTest(activity, networkCheckCallback, true), 1000);
}
public void navigateToLowNetworkActivity(Activity activity) {
if (!(activity instanceof SplashActivity) && !(activity instanceof LowNetworkActivity)) {
if (isNavigatingToLowNetwork) return; // already navigating
isNavigatingToLowNetwork = true;
Intent intent = new Intent(activity, LowNetworkActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(intent);
// Reset flag after a delay (so navigation can happen again later if needed)
mainHandler.postDelayed(() -> isNavigatingToLowNetwork = false, 5000);
}
}
private Quality decideQuality(long latency, double jitter, double packetLoss) {
if (latency == -1 || jitter == -1 || packetLoss == -1) {
return Quality.POOR;
}
boolean good = latency < 1800 && jitter < 1500 && packetLoss < 1;
boolean poor = latency > 1800 || jitter > 1500 || packetLoss > 5;
if (BuildConfig.DEBUG) {
Log.d("NetworkCheck", "Latency : " + latency + " Jitter : " + jitter + " PacketLoss : " + packetLoss);
}
if (good) return Quality.GOOD;
if (poor) return Quality.POOR;
return Quality.MODERATE;
}
}
NetworkQualityMonitor.getInstance().checkQuality(activity, isFreshCall, new NetworkCheckCallback() {
@Override
public void onNetworkCheckCompleted(boolean isConnected, boolean isLowSpeed, double speedKbps) {
handleResult(activity, isRunOnUIThread, isSendToNetworkActivity, isLowSpeed, downSpeed, false, listener);
}
});
Подробнее здесь: https://stackoverflow.com/questions/797 ... in-android
Внедрить обнаружение низкой скорости интернета в Android [закрыто] ⇐ Android
Форум для тех, кто программирует под Android
-
Anonymous
1761542793
Anonymous
Я работаю над реализацией обнаружения низкой скорости Интернета в своем приложении. Однако он не работает должным образом — он сообщает о «низком интернете», даже если скорость интернета хорошая. [b]Я хотел бы реализовать это без использования загрузки файлов[/b], и я был бы очень признателен за ваши советы о том, как надежно обнаружить низкую скорость Интернета.
Найдите код, который я реализовал ниже.
Заранее спасибо.
public class NetworkQualityMonitor {
public interface NetworkQualityCallback {
void onQualityChecked(Quality quality, long latency, double jitter, double packetLoss);
}
public enum Quality {
GOOD, MODERATE, POOR
}
private final OkHttpClient client;
private final String pingUrl = "https://www.google.com";
private final int pingCount;
private final ExecutorService executor;
private final Handler mainHandler;
// --- Caching state ---
private long lastCheckTime = 0;
private Quality lastQuality = Quality.POOR;
private long lastLatency = -1;
private double lastJitter = -1;
private double lastPacketLoss = -1;
private static NetworkQualityMonitor networkQualityMonitor;
private static final long CACHE_DURATION_MS = 7000; // 5 sec
private boolean isChecking = false; // avoid parallel execution
private boolean isNavigatingToLowNetwork = false; // avoid multiple LowNetworkActivity launches
private NetworkQualityMonitor() {
this.client = new OkHttpClient.Builder().connectTimeout(3, TimeUnit.SECONDS).readTimeout(2, TimeUnit.SECONDS).build();
this.pingCount = 4;
this.executor = Executors.newSingleThreadExecutor();
this.mainHandler = new Handler(Looper.getMainLooper());
}
public synchronized static NetworkQualityMonitor getInstance() {
if (networkQualityMonitor == null) {
networkQualityMonitor = new NetworkQualityMonitor();
}
return networkQualityMonitor;
}
private boolean mapNetworkQuality(Quality quality, long latency, double jitter, double packetLoss) {
return quality == Quality.POOR;
}
public synchronized void checkQuality(Activity activity, boolean isFreshCheck, NetworkChecker.NetworkCheckCallback networkCheckCallback) {
long now = System.currentTimeMillis();
// --- If cached result is still valid, return immediately ---
if (now - lastCheckTime < CACHE_DURATION_MS && !isFreshCheck) {
mainHandler.post(() -> networkCheckCallback.onNetworkCheckCompleted(
lastQuality != Quality.POOR,
lastQuality == Quality.POOR,
0
));
if (lastQuality == Quality.POOR) {
retryCheck(activity, networkCheckCallback); // trigger retry
}
return;
}
runNetworkTest(activity, networkCheckCallback, false);
}
private void runNetworkTest(Activity activity, NetworkChecker.NetworkCheckCallback networkCheckCallback, boolean isRetry) {
executor.execute(() -> {
try {
Quality quality;
List rtts = new ArrayList();
int successCount = 0;
for (int i = 0; i < pingCount; i++) {
long start = System.currentTimeMillis();
Request request = new Request.Builder().url(pingUrl).tag("" + System.currentTimeMillis()).build();
try (Response response = client.newCall(request).execute()) {
if (response.isSuccessful()) {
successCount++;
long rtt = System.currentTimeMillis() - start;
rtts.add(rtt);
}
} catch (IOException ignored) {}
try { Thread.sleep(70); } catch (InterruptedException ignored) {}
}
// --- Latency ---
long avgLatency = rtts.isEmpty() ? -1 : rtts.stream().mapToLong(Long::longValue).sum() / rtts.size();
// --- Jitter ---
double jitter = 0;
for (int i = 1; i < rtts.size(); i++) {
jitter += Math.abs(rtts.get(i) - rtts.get(i - 1));
}
jitter = rtts.size() > 1 ? jitter / (rtts.size() - 1) : -1;
// --- Packet Loss ---
double packetLoss = 100.0 * (pingCount - successCount) / pingCount;
// --- Decide Quality ---
quality = decideQuality(avgLatency, jitter, packetLoss);
// --- Cache result ---
lastCheckTime = System.currentTimeMillis();
lastQuality = quality;
lastLatency = avgLatency;
lastJitter = jitter;
lastPacketLoss = packetLoss;
mainHandler.post(() -> {
if (quality == Quality.POOR) {
if (!isRetry) {
// First time poor → retry check
retryCheck(activity, networkCheckCallback);
} else {
// Second time also poor → navigate
networkCheckCallback.onNetworkCheckCompleted(false, true, 0);
navigateToLowNetworkActivity(activity);
}
} else {
networkCheckCallback.onNetworkCheckCompleted(true, false, 0);
}
});
} catch (Exception e) {
mainHandler.post(() -> networkCheckCallback.onNetworkCheckCompleted(true, false, 0));
}
});
}
private void retryCheck(Activity activity, NetworkChecker.NetworkCheckCallback networkCheckCallback) {
// Optional: Add a small delay before retry
mainHandler.postDelayed(() -> runNetworkTest(activity, networkCheckCallback, true), 1000);
}
public void navigateToLowNetworkActivity(Activity activity) {
if (!(activity instanceof SplashActivity) && !(activity instanceof LowNetworkActivity)) {
if (isNavigatingToLowNetwork) return; // already navigating
isNavigatingToLowNetwork = true;
Intent intent = new Intent(activity, LowNetworkActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(intent);
// Reset flag after a delay (so navigation can happen again later if needed)
mainHandler.postDelayed(() -> isNavigatingToLowNetwork = false, 5000);
}
}
private Quality decideQuality(long latency, double jitter, double packetLoss) {
if (latency == -1 || jitter == -1 || packetLoss == -1) {
return Quality.POOR;
}
boolean good = latency < 1800 && jitter < 1500 && packetLoss < 1;
boolean poor = latency > 1800 || jitter > 1500 || packetLoss > 5;
if (BuildConfig.DEBUG) {
Log.d("NetworkCheck", "Latency : " + latency + " Jitter : " + jitter + " PacketLoss : " + packetLoss);
}
if (good) return Quality.GOOD;
if (poor) return Quality.POOR;
return Quality.MODERATE;
}
}
NetworkQualityMonitor.getInstance().checkQuality(activity, isFreshCall, new NetworkCheckCallback() {
@Override
public void onNetworkCheckCompleted(boolean isConnected, boolean isLowSpeed, double speedKbps) {
handleResult(activity, isRunOnUIThread, isSendToNetworkActivity, isLowSpeed, downSpeed, false, listener);
}
});
Подробнее здесь: [url]https://stackoverflow.com/questions/79798799/implement-low-internet-speed-detection-in-android[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия