package cm.android.net; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import android.annotation.TargetApi; import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.Build; import android.provider.Settings; import android.support.v4.net.ConnectivityManagerCompat; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; import cm.android.util.EnvironmentUtil; import cm.java.util.Reflect; public class NetworkUtil { private static final Logger logger = LoggerFactory.getLogger(NetworkUtil.class); /** * 取得网络类型 */ public static int getNetWorkType(Context context) { TelephonyManager tm = (TelephonyManager) context .getSystemService(Context.TELEPHONY_SERVICE); return tm.getNetworkType(); } /** * 对大数据传输时,需要调用该方法做出判断,如果流量敏感,应该提示用户 * * @return true表示流量敏感,false表示不敏感 */ public static boolean isActiveNetworkMetered(Context context) { ConnectivityManager cm = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); return ConnectivityManagerCompat.isActiveNetworkMetered(cm); } /** * 检查当前是否连接 * * @return true表示当前网络处于连接状态,否则返回false */ public static boolean isConnected(Context context) { ConnectivityManager cm = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo info = cm.getActiveNetworkInfo(); if (info != null && info.isConnected()) { return true; } return false; } /** * 判断WIFI网络是否可用 */ public static boolean isWifiConnected(Context context) { ConnectivityManager connMgr = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo info = connMgr.getActiveNetworkInfo(); if (info != null && info.isConnected()) { boolean wifiConnected = info.getType() == ConnectivityManager.TYPE_WIFI; return wifiConnected; } return false; // NetworkInfo networkInfo = connMgr // .getNetworkInfo(ConnectivityManager.TYPE_WIFI); // if (null != networkInfo) { // boolean isWifiConn = networkInfo.isConnected(); // return isWifiConn; // } // return false; } /** * 判断MOBILE网络是否可用 */ public static boolean isMobileConnected(Context context) { ConnectivityManager connMgr = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo info = connMgr.getActiveNetworkInfo(); if (info != null && info.isConnected()) { boolean mobileConnected = info.getType() == ConnectivityManager.TYPE_MOBILE; return mobileConnected; } return false; // NetworkInfo networkInfo = connMgr // .getNetworkInfo(ConnectivityManager.TYPE_MOBILE); // if (null != networkInfo) { // boolean isMobileConn = networkInfo.isConnected(); // return isMobileConn; // } // return false; } /** * 获取当前网络连接的类型信息 */ public static int getConnectedType(Context context) { if (context != null) { ConnectivityManager mConnectivityManager = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo mNetworkInfo = mConnectivityManager .getActiveNetworkInfo(); if (mNetworkInfo != null && mNetworkInfo.isAvailable()) { return mNetworkInfo.getType(); } } return -1; } /** * 获取当前的网络状态 -1:没有网络 1:WIFI网络2:wap 网络3:net网络 */ public static NetType getAPNType(Context context) { ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); if (networkInfo == null) { return NetType.NONE_NET; } int nType = networkInfo.getType(); if (nType == ConnectivityManager.TYPE_MOBILE) { if ("cmnet".equalsIgnoreCase(networkInfo.getExtraInfo())) { return NetType.CMNET; } else { return NetType.CMWAP; } } else if (nType == ConnectivityManager.TYPE_WIFI) { return NetType.WIFI; } return NetType.NONE_NET; } public static int getNetWorkAvailable(Context context) { ConnectivityManager connMgr = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); if (connMgr != null) { NetworkInfo mNetworkInfo = connMgr.getActiveNetworkInfo(); if (mNetworkInfo != null && mNetworkInfo.isAvailable()) { return mNetworkInfo.getType(); } } return -1000; } public static boolean isConnectedWap(Context context) { ConnectivityManager connMgr = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo netInfo = connMgr .getNetworkInfo(ConnectivityManager.TYPE_MOBILE); if (netInfo != null && netInfo.getExtraInfo() != null) { if (netInfo.getExtraInfo().trim().toLowerCase().contains("wap") && netInfo.isConnected()) { return true; } } return false; } public static boolean wifiConnected(Context context) { ConnectivityManager connMgr = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo info = connMgr.getActiveNetworkInfo(); if (info != null) { if (info.isConnected() && info.getType() == ConnectivityManager.TYPE_WIFI) { return true; } else { NetworkInfo info1 = connMgr .getNetworkInfo(ConnectivityManager.TYPE_WIFI); if (info1 != null && info1.isConnected()) { return true; } } } return false; } /** * 网络类型 */ public static enum NetType { WIFI, CMNET, CMWAP, NONE_NET } /** * 设置gprs状态 * <p/> * <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> * <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/> * <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/> * <uses-permission android:name="android.permission.WRITE_SETTINGS"/> * <uses-permission android:name="android.permission.MODIFY_PHONE_STATE"/> */ public static void setMobileDataEnabled(Context context, boolean enabled) { if (EnvironmentUtil.SdkUtil.has(21)) { } else { setMobileDataEnabledLow(context, enabled); } } private static void setMobileDataEnabledLow(Context context, boolean enabled) { final ConnectivityManager cm = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); try { Reflect.bind(cm).method("setMobileDataEnabled", boolean.class).call(enabled); } catch (Reflect.ReflectException e) { logger.error(e.getMessage(), e); } // ObjectProxy proxy = new ObjectProxy(cm); // Method setMobileDataEnabledMethod = proxy // .getMethod("setMobileDataEnabled", Boolean.TYPE); // if (setMobileDataEnabledMethod != null) { // proxy.doMethod(setMobileDataEnabledMethod, enabled); // } } private static boolean getMobileDataEnabledLow(Context context) { final ConnectivityManager cm = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); try { return Reflect.bind(cm).call("getMobileDataEnabled"); } catch (Reflect.ReflectException e) { return true; } // ObjectProxy proxy = new ObjectProxy(cm); // Method getMobileDataEnabledMethod = proxy.getMethod("getMobileDataEnabled"); // if (getMobileDataEnabledMethod != null) { // return proxy.doMethod(getMobileDataEnabledMethod); // } // return true; } public static boolean getMobileDataEnabled(Context context) { if (EnvironmentUtil.SdkUtil.has(21)) { return false; } else { return getMobileDataEnabledLow(context); } } /** * android.permission.MODIFY_PHONE_STATE (only system apps can use that) */ public static void setMobileDataEnabledCompat(Context context, boolean enabled) { if (context == null) { return; } if (!EnvironmentUtil.SdkUtil.hasLollipop()) { setMobileDataEnabled(context, enabled); } try { TelephonyManager telephonyService = (TelephonyManager) context .getSystemService(Context.TELEPHONY_SERVICE); Method setMobileDataEnabledMethod = telephonyService.getClass() .getDeclaredMethod("setDataEnabled", boolean.class); if (null != setMobileDataEnabledMethod) { setMobileDataEnabledMethod.invoke(telephonyService, enabled); } } catch (Exception ex) { logger.error("Error setting mobile data state", ex); } } public static boolean getMobileDataEnabledCompat(Context context) { if (!EnvironmentUtil.SdkUtil.hasLollipop()) { return getMobileDataEnabled(context); } try { TelephonyManager telephonyService = (TelephonyManager) context.getSystemService( Context.TELEPHONY_SERVICE); Method getMobileDataEnabledMethod = telephonyService.getClass() .getDeclaredMethod("getDataEnabled"); if (null != getMobileDataEnabledMethod) { boolean mobileDataEnabled = (Boolean) getMobileDataEnabledMethod .invoke(telephonyService); return mobileDataEnabled; } } catch (Exception ex) { logger.error("Error getting mobile data state", ex); } return false; } /** * need rooted devices */ public static void setMobileDataEnabledCompat1(Context context, boolean enabled) { if (context == null) { return; } if (!EnvironmentUtil.SdkUtil.hasLollipop()) { setMobileDataEnabled(context, enabled); return; } String command = null; int state = 0; try { // Get the current state of the mobile network. state = getMobileDataEnabledCompat1(context) ? 0 : 1; // Get the value of the "TRANSACTION_setDataEnabled" field. String transactionCode = getTransactionCode(context); // Android 5.1+ (API 22) and later. if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) { SubscriptionManager mSubscriptionManager = (SubscriptionManager) context .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE); // Loop through the subscription list i.e. SIM list. for (int i = 0; i < mSubscriptionManager.getActiveSubscriptionInfoCountMax(); i++) { if (transactionCode != null && transactionCode.length() > 0) { // Get the active subscription ID for a given SIM card. int subscriptionId = mSubscriptionManager.getActiveSubscriptionInfoList() .get(i).getSubscriptionId(); // Execute the command via `su` to turn off // mobile network for a subscription service. command = "service call phone " + transactionCode + " i32 " + subscriptionId + " i32 " + state; executeCommandViaSu("-c", command); } } } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) { // Android 5.0 (API 21) only. if (transactionCode != null && transactionCode.length() > 0) { // Execute the command via `su` to turn off mobile network. command = "service call phone " + transactionCode + " i32 " + state; executeCommandViaSu("-c", command); } } } catch (Exception e) { // Oops! Something went wrong, so we throw the exception here. throw e; } } @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) public static boolean getMobileDataEnabledCompat1(Context context) { if (!EnvironmentUtil.SdkUtil.hasLollipop()) { return getMobileDataEnabled(context); } return Settings.Global.getInt(context.getContentResolver(), "mobile_data", 0) == 1; } private static String getTransactionCode(Context context) { try { final TelephonyManager mTelephonyManager = (TelephonyManager) context .getSystemService(Context.TELEPHONY_SERVICE); final Class<?> mTelephonyClass = Class.forName(mTelephonyManager.getClass().getName()); final Method mTelephonyMethod = mTelephonyClass.getDeclaredMethod("getITelephony"); mTelephonyMethod.setAccessible(true); final Object mTelephonyStub = mTelephonyMethod.invoke(mTelephonyManager); final Class<?> mTelephonyStubClass = Class.forName(mTelephonyStub.getClass().getName()); final Class<?> mClass = mTelephonyStubClass.getDeclaringClass(); final Field field = mClass.getDeclaredField("TRANSACTION_setDataEnabled"); field.setAccessible(true); return String.valueOf(field.getInt(null)); } catch (Exception e) { // The "TRANSACTION_setDataEnabled" field is not available, // or named differently in the current API level, so we throw // an exception and inform users that the method is not available. logger.error("The TRANSACTION_setDataEnabled field is not available : ", e); } return null; } private static void executeCommandViaSu(String option, String command) { boolean success = false; String su = "su"; for (int i = 0; i < 3; i++) { // Default "su" command executed successfully, then quit. if (success) { break; } // Else, execute other "su" commands. if (i == 1) { su = "/system/xbin/su"; } else if (i == 2) { su = "/system/bin/su"; } try { // Execute command as "su". Runtime.getRuntime().exec(new String[]{su, option, command}); } catch (IOException e) { success = false; // Oops! Cannot execute `su` for some reason. // Log error here. } finally { success = true; } } } }