首先是JAVA层:
直接使用Android自带的TelephonyManager 和 ConnectivityManager 都可以获取到 NetworksInfo 对象,可以通过 getType() 获取类型,判断是 “WIFI”还是 “MOBILE”,如果是MOBILE,可以通过 NetworksInfo 对象的 getSubType() 和 getSubTypeName() 可以获取到对于的网络类型和名字。
通过简单地查看Android API即可调用。安卓SDK19暂无对4G网络的强度判断方法。
先声明一些常量:
//网络状态强度 public static final int NETLEVEL_STRENGTH_NONE_OR_UNKNOWN = 0; public static final int NETLEVEL_STRENGTH_POOR = 1; public static final int NETLEVEL_STRENGTH_MODERATE = 2; public static final int NETLEVEL_STRENGTH_GOOD = 3; public static final int NETLEVEL_STRENGTH_GREAT = 4; //定义数组用于返回 static int[] netInfo = new int[2]; //信号监听 TelephonyManager Tel; MyPhoneStateListener MyListener; public static int singnalLevel; //Wifi监听 private static WifiInfo wifiInfo = null; private static WifiManager wifiManager = null; public static int wifiLevel;在onCreate()里添加注册监听:
//添加信号强度监听 MyListener = new MyPhoneStateListener(); Tel = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); Tel.listen(MyListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS); //添加wifi强度监听 wifiManager = (WifiManager)getSystemService(WIFI_SERVICE); }再调用方法public void onSignalStrengthsChanged(SignalStrength signalStrength) 就能得到信号强度了,注意下面代码中加了对4G信号强度的判断:
/** * 获取当前网络类型 */ static public String getNetworkType() { ConnectivityManager cOnnManager= (ConnectivityManager) _activity .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkinfo = connManager.getActiveNetworkInfo(); if (networkinfo != null) { return networkinfo.getTypeName(); } return "无"; } //netType -1: 没有网络 1: WIFI 2: 移动数据 //netLevel 1: None 2:poor 3:moderate 4:good 5:great public static int[] getNetInfo() { Log.d("getNetInfo", "enter the function getNetInfo ----- "); //根据Android的安全机制,在使用ConnectivityManager时,必须在AndroidManifest.xml中添加否则无法获得系统的许可。 ConnectivityManager cOnnMgr= (ConnectivityManager)_activity.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); if( null == networkInfo) return netInfo; int nType = networkInfo.getType(); if (nType == ConnectivityManager.TYPE_MOBILE) { netInfo[0] = 2; } else if (nType == ConnectivityManager.TYPE_WIFI) { netInfo[0] = 1; } Log.d("getNetInfo", "java ---- netType --- "+ netInfo[0]); //according to netType. set the value of netLevel switch (netInfo[0]) { case 1: netInfo[1] = getWifiLevel(); break; case 2: netInfo[1] = getSingnalLevel(); break; default: break; } Log.d("getNetInfo", "java ---- netLevel --- "+ netInfo[1]); return netInfo; } //信号强度等级 private class MyPhoneStateListener extends PhoneStateListener { @Override public void onSignalStrengthsChanged(SignalStrength signalStrength) { super.onSignalStrengthsChanged(signalStrength); int asu = signalStrength.getGsmSignalStrength(); //获取4G信号下的信号强度,可能存在部分手机机型导致的bug String signalInfo = signalStrength.toString(); String[] params = signalInfo.split(" "); // 17/8/14 注意,可能在不同机型上解析params得到的Itedbm值不同 if(Tel.getNetworkType() == TelephonyManager.NETWORK_TYPE_LTE){ //4G网络 最佳范围 >-90dBm 越大越好 int Itedbm = Integer.parseInt(params[9]); asu=asu+Itedbm; if (asu<=0 ||asu>=99) singnalLevel = NETLEVEL_STRENGTH_NONE_OR_UNKNOWN; //Log.d("Itedbm-----","Itedbm----->"+Itedbm); } //Log.d("asu----","java---asu---"+ asu); if (asu <= 2 || asu == 99) singnalLevel = NETLEVEL_STRENGTH_NONE_OR_UNKNOWN; else if (asu >= 12) singnalLevel = NETLEVEL_STRENGTH_GREAT; else if (asu >= 8) singnalLevel = NETLEVEL_STRENGTH_GOOD; else if (asu >= 5) singnalLevel = NETLEVEL_STRENGTH_MODERATE; else singnalLevel = NETLEVEL_STRENGTH_POOR; } };/* End of private Class */ //获取信号强度 public static int getSingnalLevel() { return singnalLevel; } //获取wifi强度 public static int getWifiLevel() { wifiInfo = wifiManager.getConnectionInfo(); int wifiStrength = wifiInfo.getRssi(); if (wifiStrength <= 0 && wifiStrength >= -50) { wifiLevel = NETLEVEL_STRENGTH_GREAT; } else if (wifiStrength <-50 && wifiStrength >= -70) { wifiLevel = NETLEVEL_STRENGTH_GOOD; } else if (wifiStrength <-70 && wifiStrength >= -80) { wifiLevel = NETLEVEL_STRENGTH_MODERATE; } else if (wifiStrength <-80 && wifiStrength >= -100) { wifiLevel = NETLEVEL_STRENGTH_POOR; } else { wifiLevel = NETLEVEL_STRENGTH_NONE_OR_UNKNOWN; } return wifiLevel; }
对于4G信号强度,目前我使用的安卓API里并没有提供获取强度功能,所以只能自己查了一下资料,发现貌似没有一个很好的简单的解决方案。所以自己在上面的代码中加了自己添加的判断,我的判断并不是正确的解决方案。另外如注释所说,还可能在某些机型上存在解析错误的bug。但是在我的测试机上勉强能用了。然后在Cocos工程里调用上述JAVA方法。
在C++层:
在自己的C++文件里添加JniHelper相关的类来调用JAVA方法。
#include "platform/android/jni/JniHelper.h"再通过方法就能调用到JAVA里的函数信息了。
static bool getStaticMethodInfo(JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode); static bool getMethodInfo(JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode);
可以参考http://blog.csdn.net/luxiaoyu_sdc/article/details/15874505。
然后在代码里实现getNetworkType()返回当前网络类型和getNetLevle()返回当前信号强度。如下:
const string& TestClass::getNetworkType(void) //返回当前网络类型(wifi or mobile) { static string strNetworkType; #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) //如果是IOS系统 strNetworkType = INVOKEOC_MGR->getNetworkType(); //这是获得IOS平台网络类型的方法,在此不提 #elif (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) //windows strNetworkType = "windows"; #elif (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) //如果是Android系统,则调用JAVA类里的getNetworkType()方法,返回当前网络类型。 cocos2d::JniMethodInfo t; if (cocos2d::JniHelper::getStaticMethodInfo(t, g_szJavaPackage, "getNetworkType", "()Ljava/lang/String;")) { jstring ret = (jstring)t.env->CallStaticObjectMethod(t.classID, t.methodID); strNetworkType = cocos2d::JniHelper::jstring2string(ret); t.env->DeleteLocalRef(ret); t.env->DeleteLocalRef(t.classID); } #endif return strNetworkType; } const int TestClass::getNetLevel(void) //返回当前手机信号强度 { int out_NetLevel = 1000; #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) //如果是IOS系统 out_NetLevel = INVOKEOC_MGR->getNetLevel(); #elif (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) #elif (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) //如果是Android系统,和上面的getNetworkType()方法一样,通常返回值是(int)0-4(弱->强) JniMethodInfo t; bool isHave = JniHelper::getStaticMethodInfo(t, g_szJavaPackage, "getNetInfo", "()[I"); if (isHave) { jintArray msg = (jintArray)t.env->CallStaticObjectMethod(t.classID, t.methodID); int len = t.env->GetArrayLength(msg); jint* elems = t.env->GetIntArrayElements(msg, 0); if (2 == len) { out_NetLevel = elems[1]; } t.env->DeleteLocalRef(t.classID); } else { cocos2d::log("JniFun call getNetInfo error!"); } #endif CCLOG("TestClass::getNetInfo ===== getNetInfo1:%d", out_NetLevel); return out_NetLevel; }
要在Lua中使用自定义的C++方法,自然需要让C++和Lua交互,要用到tolua++等,在此不提。
/*
**重要代码**
tolua_function(tolua_S,"getNetLevel", lua_class_TestClass_getNetLevel); tolua_function(tolua_S,"getNetworkType", lua_class_TestClass_getNetLevel);
**重要代码**
*/
让C++绑定Lua,获取网络类型:
int lua_class_TestClass_getNetworkType(lua_State* tolua_S) { int argc = 0; bool ok = true; //参数判断 argc = lua_gettop(tolua_S) - 1; if (argc == 0) { string ret = TestClass::getInstance()->getNetworkType(); tolua_pushcppstring(tolua_S, ret); return 1; } luaL_error(tolua_S, "%s , %d, was expecting %d \n", "TestClass::getInstance():getNetworkType", argc, 0); return 0; }获取信号强度:
int lua_class_TestClass_getNetLevel(lua_State* tolua_S) { int argc = 0; bool ok = true; //参数判断 argc = lua_gettop(tolua_S) - 1; if (argc == 0) { int ret = TestClass::getInstance()->getNetLevel(); tolua_pushnumber(tolua_S, (lua_Number)ret); return 1; } luaL_error(tolua_S, "%s, %d, was expecting %d \n", "TestClass::getInstance():getNetInfo", argc, 0); return 0; }之后在Lua中调用(注意下面的TestClass是经过Lua和C++交互转换的,不能直接使用C++里的TestClass类)。
local NetworkType = TestClass:getNetworkType() -- MOBILE or WIFI
local NetLevel = TestClass:getNetLevel() -- 0-4(弱到强)