package com.cellasoft.univrapp;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.telephony.TelephonyManager;
import android.util.Log;
import com.cellasoft.univrapp.service.SynchronizationService;
import java.io.IOException;
import static com.cellasoft.univrapp.utils.LogUtils.LOGD;
import static com.cellasoft.univrapp.utils.LogUtils.makeLogTag;
public class ConnectivityReceiver extends BroadcastReceiver {
private static final String TAG = makeLogTag(ConnectivityReceiver.class);
public static boolean hasGoodEnoughNetworkConnection() {
Context context = Application.getInstance();
NetworkInfo info = ((ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE))
.getActiveNetworkInfo();
return hasGoodEnoughNetworkConnection(info, context);
}
public static boolean hasGoodEnoughNetworkConnection(NetworkInfo info,
Context context) {
if (BuildConfig.DEBUG)
return true;
if (info == null)
return false;
// Only update if WiFi or 3G is connected and not roaming
int netType = info.getType();
int netSubtype = info.getSubtype();
if (netType == ConnectivityManager.TYPE_WIFI) {
if (info.isConnected()) {
return isOnline();
}
}
if (Settings.getWifiOnly())
return false;
if (isConnectionFast(netType, netSubtype)) {
TelephonyManager telephonyManager = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
if (!telephonyManager.isNetworkRoaming()) {
if (info.isConnected()) {
return isOnline();
}
}
}
return false;
}
public static boolean isOnline() {
try {
int r = pingHost("8.8.8.8", 0);
if (r == 0) {
return true;
}
} catch (Exception e) {
return false;
}
return false;
}
/**
* Ping a host and return an int value of 0 or 1 or 2 0=success, 1=fail,
* 2=error
* <p/>
* Does not work in Android emulator and also delay by '1' second if host
* not pingable In the Android emulator only ping to 127.0.0.1 works
*
* @param String host in dotted IP address format
* @return
* @throws IOException
* @throws InterruptedException
*/
public static int pingHost(String host, int timeout) throws IOException,
InterruptedException {
Runtime runtime = Runtime.getRuntime();
timeout /= 1000;
String cmd = "/system/bin/ping -c 1 -W " + timeout + " " + host;
Process proc = runtime.exec(cmd);
Log.d(TAG, cmd);
proc.waitFor();
int exit = proc.exitValue();
return exit;
}
/**
* 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 true; // ~ 50-100 kbps
case TelephonyManager.NETWORK_TYPE_CDMA:
return false; // ~ 14-64 kbps
case TelephonyManager.NETWORK_TYPE_EDGE:
return true; // ~ 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 true; // ~ 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;
}
}
@Override
public void onReceive(Context context, Intent intent) {
Intent updatingService = new Intent(context,
SynchronizationService.class);
@SuppressWarnings("deprecation")
NetworkInfo info = intent
.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
if (hasGoodEnoughNetworkConnection(info, context)) {
// should start background service to update
if (BuildConfig.DEBUG)
LOGD(TAG,
"Have WIFI or 3G connection, start background services...");
context.startService(updatingService);
} else {
if (BuildConfig.DEBUG)
LOGD(TAG,
"No WIFI or 3G connection, stop background services...");
context.stopService(updatingService);
}
}
}