Android pass parameter to Native Activity
Asked Answered
N

1

12

My android application compirises two Activities: ".MainActivity" and "android.app.NativeActivity". The latter is implemented purely in C++. On button click in ".MainActivity" I start a native one trying to pass some parameters:

public void pressedButton(View view)
{
    Intent intent = new Intent(this, android.app.NativeActivity.class);
    intent.putExtra("MY_PARAM_1", 123);
    intent.putExtra("MY_PARAM_2", 321);
    startActivity(intent);
}

How do I get MY_PARAM_1 and MY_PARAM_2 from within android.app.NativeActivity's entry point (that is a C-function void android_main(struct android_app* state))?

Nisa answered 11/10, 2012 at 13:55 Comment(0)
P
18

In the android_app structure there's a data member called activity of type ANativeActivity*. Inside the latter, there's a JavaVM *vm and a misleadingly called jobject clazz. The clazz is actually a JNI-compliant object instance pointer to a Java object of type android.app.NativeActivity, which has all Activity methods, including getIntent().

There's a JNIEnv there, too, but it looks like it's not attached to the activity's main thread.

Use JNI invokations to retrieve the intent, then extras from the intent. It goes like this:

JNIEnv *env;
state->activity->vm->AttachCurrentThread(&env, 0);

jobject me = state->activity->clazz;

jclass acl = env->GetObjectClass(me); //class pointer of NativeActivity
jmethodID giid = env->GetMethodID(acl, "getIntent", "()Landroid/content/Intent;");
jobject intent = env->CallObjectMethod(me, giid); //Got our intent

jclass icl = env->GetObjectClass(intent); //class pointer of Intent
jmethodID gseid = env->GetMethodID(icl, "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;");

jstring jsParam1 = (jstring)env->CallObjectMethod(intent, gseid, env->NewStringUTF("MY_PARAM_1"));
const char *Param1 = env->GetStringUTFChars(jsParam1, 0);
//When done with it, or when you've made a copy
env->ReleaseStringUTFChars(jsParam1, Param1);

//Same for Param2
Periapt answered 11/10, 2012 at 14:37 Comment(2)
Thank you. But it has raised another question unclear to me: can I use state->activity->env as is, or have I to acquire it using state->activity->vm->AttachCurrentThread(&env, 0);?Nisa
Hm... I'm looking at the thread startup code (in android_native_app_glue.c), and it looks like it's not attached to the native activity thread. So yeah, you have to attach a JVM to the thread first instead of using env. Edited the answer.Periapt

© 2022 - 2024 — McMap. All rights reserved.