Search code examples
androidcjava-native-interfacejnienv

JNIEnv for get ANDROID_ID from native code


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?


Solution

  • 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.