2012-04-12 16 views
14

Estoy intentando crear un método que compruebe la conexión a Internet que necesita un parámetro de contexto. El JNIHelper me permite llamar a funciones estáticas con parámetros, pero no sé cómo "recuperar" la clase de actividad Cocos2d-x para usarlo como parámetro.Envío de un parámetro android.content.Context a una función con JNI

public static boolean isNetworkAvailable(Context context) { 
    boolean haveConnectedWifi = false; 
    boolean haveConnectedMobile = false; 
    ConnectivityManager cm = 
     (ConnectivityManager) context.getSystemService(
    Context.CONNECTIVITY_SERVICE); 
    NetworkInfo[] netInfo = cm.getAllNetworkInfo(); 
    for (NetworkInfo ni : netInfo) { 
     if (ni.getTypeName().equalsIgnoreCase("WIFI")) 
      if (ni.isConnected()) 
       haveConnectedWifi = true; 
     if (ni.getTypeName().equalsIgnoreCase("MOBILE")) 
      if (ni.isConnected()) 
       haveConnectedMobile = true; 
    } 
    return haveConnectedWifi || haveConnectedMobile; 
} 

y el código C++ es

JniMethodInfo methodInfo; 
if (!JniHelper::getStaticMethodInfo(methodInfo, 
    "my/app/TestApp", "isNetworkAvailable", "(Landroid/content/Context;)Z")) { 
     //error 
     return; 
} 
CCLog("Method found and loaded!"); 
methodInfo.env->CallStaticBooleanMethod(methodInfo.classID, 
methodInfo.methodID); 
methodInfo.env->DeleteLocalRef(methodInfo.classID); 
+0

¿Me puede decir ¿por qué necesita este contexto? ¿Solo para obtener getSystemService ????? –

+1

Esta no es la solución, pero el descriptor de isNetworkAvailable es incorrecto. Debería ser: "(Landroid/content/Context;) Z". Tenga en cuenta la L y Z –

Respuesta

3

Cocos2dxActivity.java: añadir esta línea a Cocos2dxActivity: private static Activity me = null; elimine esta línea de onCreate:

Cocos2dxActivity.context = getApplicationContext(); 

En su lugar puesto: me = this;

uso:

(ConnectivityManager) me.getSystemService(
    Context.CONNECTIVITY_SERVICE); 

Ahora no necesitas pasar el contexto de tu Jni ... Sé que este no es el sol pero para su caso no necesita preocuparse por el contexto de Jni. Simplemente puede hacer su trabajo.

Espero que esto ayude .. Utilicé esta forma de enviar correos de Android en mi juego. :)

+0

El atributo estático es probablemente la mejor solución aquí, y también se puede recuperar con llamadas jni, así que lo daré como correcto. Me –

+0

consejos de editar el código con MyCocos2dxActivity.me.getSystemService (ConnectivityManager) ( Context.CONNECTIVITY_SERVICE); por lo que muestra que puede funcionar incluso si isNetworkAvailable está en otra clase. –

1

El primer error que veo es que usted está tratando de obtener el método de forma incorrecta.

"(android/content/Context;)V" significa que está solicitando un método que reciba Context como parámetro y devuelva void que no es su caso.

Su llamada debe ser algo como esto:

jclass aClass = env->FindClass("my/app/TestApp"); 
env->GetMethodID(aClass, "isNetworkAvailable", "(android/content/Context;)Z"); 

no estoy completamente seguro de cómo pasar una Context a JNI sin romper cosas o estar seguro de que funcionará. Pero en lugar de pasarlo, puede llamar al getApplication() y usarlo como Context.

+0

Incluso si cambio la firma y la llamada a la función, el problema persiste. Lo que hace la función es llamar a OpenFeint, que requiere la actividad principal. Lo arreglé en cierto modo en el código Java, pero me gustaría saber cómo obtener la aplicación del código cpp en caso de que la necesite en otro lugar. –

+0

@EfEs: ese no es el código que muestra en su pregunta. No estoy seguro de cómo hacerlo entonces.Te recomendaría que ingreses a http://groups.google.com/group/android-ndk para obtener la respuesta. – Macarse

2

Puede pasar objeto Context a JNI utilizando el siguiente método:

extern "C" { 
JNIEXPORT jboolean JNICALL 
Java_yournamespace_yourclassname_methodname(JNIEnv* env, jobject thiz, jobject p_context); 
} 

en su clase java utilizar la siguiente declaración:

public native static boolean methodname(Context p_context); 

Ahora puede llamar a la función nativa de su código java y pasar un contexto de un parámetro.

como para conseguir su clase de aplicación y usarlo, me gustaría usar el siguiente código (en la parte C++):

jclass yourAppClass = env->FindClass("my/app/TestApp"); 
jmethodID someMethodId = env->GetStaticMethodID(yourAppClass , "methodName", "(Landroid/content/Context;)Z"); 
jboolean retval = env->CallStaticObjectMethod(yourAppClass , someMethodId , p_context); 
+0

Correcto pero incorrecto. Su código de solucionar mis problemas de llamadas, pero lo que quiero es el contexto dinámico real de la aplicación principal, y para eso tengo que recuperarlo primero a partir del código C++. –

+0

¿Qué quiere decir con contexto dinámico? El contexto principal de la aplicación se puede pasar como un argumento a su llamada JNI utilizando getApplicationContext() – Muzikant

+0

Y eso era mi pregunta, el fragmento que hace que, en el CPP. –

Cuestiones relacionadas