Question

I need to get Android unique device ID in my native library. As far as i know, it can be done with Java API and i need to use JNI. I read this, there is similar problem, but different ID is accessed. But this solution needs reference to JNIEnv for getting Java objects/methods. When JNI method called from Java, this is not problem, JNIEnv will be passed from Java. But how i can get JNIEnv for "total" native code?

Was it helpful?

Solution 2

I found that JNIEnv can be accessed with JavaVM, which can be created with JNI invocation API. By default in Android NDK this functions not exported to user(from platforms/android-19/arch-arm/usr/include/jni.h):

/*
 * VM initialization functions.
 *
 * Note these are the only symbols exported for JNI by the VM.
 */
#if 0  /* In practice, these are not exported by the NDK so don't declare them */
jint JNI_GetDefaultJavaVMInitArgs(void*);
jint JNI_CreateJavaVM(JavaVM**, JNIEnv**, void*);
jint JNI_GetCreatedJavaVMs(JavaVM**, jsize, jsize*);
#endif

But this functions presented in /system/lib/libdvm.so on my device. After including function definition for JNI_CreateJavaVM in my code and linking to libdvm, copied from device, i got access to creation of JavaVM in Android. This is not recommended, of course, but, if you want it and your device libdvm supports this, you can do it.

OTHER TIPS

The entrypoint of your native activity receives a struct android_app* as its argument. android_app contains an ANativeActivity* named activity, which in turn contains a JNIEnv* named env.

To be able to call Android Java API methods from your native code you'll have to attach the current thread to the VM first, i.e.:

JNIEnv *env = state->activity->env;
JavaVM *vm = state->activity->vm;
(*vm)->AttachCurrentThread(vm, &env, NULL);

(where state is the struct android_app*)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top