2012-04-12 8 views
14

Próbuję utworzyć metodę, która sprawdza połączenie internetowe, które wymaga parametru kontekstowego. JNIHelper pozwala mi wywoływać funkcje statyczne z parametrami, ale nie wiem, jak "pobrać" klasę aktywności Cocos2d-x, aby użyć jej jako parametru.Wysyłanie parametru android.content.Context do funkcji z 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; 
} 

i C++ kod jest

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

możesz mi powiedzieć, dlaczego trzeba tym kontekście? Aby uzyskać getSystemService ????? –

+1

To nie jest rozwiązanie, ale deskryptor dla isNetworkAvailable jest niepoprawny. Powinno to być: "(Landroid/content/Context;) Z". Zauważ, że L i Z –

Odpowiedz

3

Cocos2dxActivity.java: Dodaj tę linię do Cocos2dxActivity: private static Activity me = null; Usuń ten wiersz z onCreate:

Cocos2dxActivity.context = getApplicationContext(); 

umieścić na swoim miejscu: me = this;

zastosowanie:

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

teraz nie musisz przekazywać kontekstu ze swojego Jni ... Wiem, że to nie jest zol ale w twoim przypadku nie musisz martwić się o kontekst od Jni ... Możesz po prostu wykonać swoją pracę.

Mam nadzieję, że to pomoże .. Użyłem tej metody, aby wysyłać pocztę z Androida w mojej grze. :)

+0

Atrybut statyczny jest prawdopodobnie najlepszym rozwiązaniem, a także można go odzyskać za pomocą wywołań jni, więc podam go jako poprawny. –

+0

Proponuję edytować kod za pomocą (ConnectivityManager) MyCocos2dxActivity.me.getSystemService ( Context.CONNECTIVITY_SERVICE); więc pokazuje, że może działać, nawet jeśli isNetworkAvailable jest w innej klasie. –

1

Pierwszy błąd widzę jest to, że starają się metodę nieprawidłowo.

"(android/content/Context;)V" oznacza, prosicie o metodzie, która odbiera Context jako parametr i zwraca void który nie jest twoja sprawa.

Twoje połączenie powinno być coś takiego:

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

nie jestem całkowicie pewien, w jaki sposób przekazać Context do JNI bez zerwania rzeczy lub będąc pewien, że zadziała. Ale zamiast go przekazywać, możesz zadzwonić pod numer getApplication() i użyć go jako Context.

+0

Nawet jeśli zmienię sygnaturę i wywołanie funkcji, problem pozostanie. Funkcja polega na wywołaniu OpenFeint, które wymaga głównej aktywności. W pewnym sensie naprawiłem to w kodzie java, ale chciałbym wiedzieć, jak pobrać aplikację z kodu cpp na wypadek, gdy potrzebuję jej gdzie indziej. –

+0

@EfEs: To nie jest kod, który pokazujesz w swoim pytaniu. Nie jestem pewien, jak to zrobić.Polecam przekopanie się na http://groups.google.com/group/android-ndk, aby poznać odpowiedź. – Macarse

2

Możesz przekazać obiekt kontekst JNI stosując następujące metody:

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

na klasy Java używać następujące oświadczenie:

public native static boolean methodname(Context p_context); 

Teraz można wywołać funkcję ze swojego ojczystego kod java i przekazać kontekstowi parametr.

jak coraz klasa app i użyć go, chciałbym użyć następującego kodu (w C++ część):

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

Prawidłowe, ale niepoprawne. Twój kod naprawia moje problemy z połączeniem, ale to, czego chcę, to rzeczywisty dynamiczny kontekst głównej aplikacji i do tego muszę go najpierw pobrać z kodu C++. –

+0

Co masz na myśli przez dynamiczny kontekst? Główny kontekst aplikacji może zostać przekazany jako argument do wywołania JNI za pomocą metody getApplicationContext() – Muzikant

+0

I to było moje pytanie - fragment, który to robi w CPP. –