15

I am trying to create a method that checks for internet connection that needs a Context parameter. The JNIHelper allows me to call static functions with parameters, but I don't know how to "retrieve" Cocos2d-x Activity class to use it as a parameter.

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;
}

and the c++ code is

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);
MLProgrammer-CiM
  • 17,231
  • 5
  • 42
  • 75

3 Answers3

3

Cocos2dxActivity.java: Add this line to Cocos2dxActivity: private static Activity me = null; Remove this line from onCreate:

Cocos2dxActivity.context = getApplicationContext();

In its place put: me = this;

use :

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

Now you don't need to pass the context from your Jni... I know this is not the solution but for your case you don't need to worry about context from Jni.. You can simply do your work.

Hope this helps.. I used this way to send mail from android in my game. :)

Nikhil Aneja
  • 1,259
  • 8
  • 13
  • Static attribute is probably the best solution here, and it also is retrievable with jni calls so I'll give it as correct. – MLProgrammer-CiM Apr 28 '12 at 19:19
  • I advice you edit the code with (ConnectivityManager) MyCocos2dxActivity.me.getSystemService( Context.CONNECTIVITY_SERVICE); so it shows it can work even if the isNetworkAvailable is in another class. – MLProgrammer-CiM Apr 28 '12 at 19:24
2

You can pass Context object to JNI using the following method:

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

on your java class use the following declaration:

public native static boolean methodname(Context p_context);

Now you can call the native function from your java code and pass a context a parameter.

as for getting your app class and use it, I'd use the following code (in the C++ part):

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);
Muzikant
  • 8,070
  • 5
  • 54
  • 88
  • Correct but incorrect. Your code fix my call problems, but what I want is the actual dynamic context of the main application, and for that I need to retrieve it first from the c++ code. – MLProgrammer-CiM Apr 28 '12 at 19:16
  • What do you mean by dynamic context? The main application context can be passed as an argument to your JNI call using getApplicationContext() – Muzikant Apr 29 '12 at 17:54
  • And that was my question, the snippet that does that, in CPP. – MLProgrammer-CiM Apr 30 '12 at 10:35
1

The first error I see is that you are trying to get the method incorrectly.

"(android/content/Context;)V" means you are asking for a method that receives Context as a parameter and returns void which is not your case.

Your call should be something like this:

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

I am not completely sure how to pass a Context to JNI without breaking things or being sure it will work. But instead of passing it, you can call getApplication() and use it as a Context.

Macarse
  • 91,829
  • 44
  • 175
  • 230
  • Even if I change the signature and function call, the problem remains. What the function does is to call OpenFeint, which requieres the main Activity. I sort of fixed it in the java code, but I would like to know how to get the app from cpp code in case I need it somewhere else. – MLProgrammer-CiM Apr 24 '12 at 13:31
  • @EfEs: That's not the code you are showing in your question. I am not sure how to do it then. I would recommend you digging into http://groups.google.com/group/android-ndk to learn the answer. – Macarse Apr 24 '12 at 13:40