App's path for external storage in native code

后端 未结 2 1023
野趣味
野趣味 2020-12-18 08:29

I am trying to write a native library for my application so that i can do all file operation in the native code. I read that getExternalStorageDirectory() give

2条回答
  •  情歌与酒
    2020-12-18 08:59

    JNI is your friend, and this isn't too complicated, as getExternalStorageDirectory is a static method. This function gets the value, and changes the working directory to it, for good measure.

    #include 
    #include  // chdir()
    #include  // MAXPATHLEN
    
    // To call Java methods when running native code inside an Android activity,
    // a reference is needed to the JavaVM.
    static JavaVM *gJavaVM;
    
    JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
    {
        gJavaVM = vm;
        return JNI_VERSION_1_6;
    }
    
    int cdToExtStorage(void) {
    
        // Make JNI calls to get the external storage directory, and cd to it.
    
        // To begin, get a reference to the env and attach to it.
        JNIEnv *env;
        int isAttached = 0;
        int ret = 0;
        jthrowable exception;
        if (((*gJavaVM)->GetEnv(gJavaVM, (void**)&env, JNI_VERSION_1_6)) < 0) {
            // Couldn't get JNI environment, so this thread is native.
            if (((*gJavaVM)->AttachCurrentThread(gJavaVM, &env, NULL)) < 0) {
                fprintf(stderr, "Error: Couldn't attach to Java VM.\n");
                return (-1);
            }
            isAttached = 1;
        }
    
        // Get File object for the external storage directory.
        jclass classEnvironment = (*env)->FindClass(env, "android/os/Environment");
        if (!classEnvironment) goto bailAndroid;
        jmethodID methodIDgetExternalStorageDirectory = (*env)->GetStaticMethodID(env, classEnvironment, "getExternalStorageDirectory", "()Ljava/io/File;"); // public static File getExternalStorageDirectory ()
        if (!methodIDgetExternalStorageDirectory) goto bailAndroid;
        jobject objectFile = (*env)->CallStaticObjectMethod(env, classEnvironment, methodIDgetExternalStorageDirectory);
        exception = (*env)->ExceptionOccurred(env);
        if (exception) {
            (*env)->ExceptionDescribe(env);
            (*env)->ExceptionClear(env);
        }
    
        // Call method on File object to retrieve String object.
        jclass classFile = (*env)->GetObjectClass(env, objectFile);
        if (!classFile) goto bailAndroid;
        jmethodID methodIDgetAbsolutePath = (*env)->GetMethodID(env, classFile, "getAbsolutePath", "()Ljava/lang/String;");
        if (!methodIDgetAbsolutePath) goto bailAndroid;
        jstring stringPath = (*env)->CallObjectMethod(env, objectFile, methodIDgetAbsolutePath);
        exception = (*env)->ExceptionOccurred(env);
        if (exception) {
            (*env)->ExceptionDescribe(env);
            (*env)->ExceptionClear(env);
        }
        // Extract a C string from the String object, and chdir() to it.
        const char *wpath3 = (*env)->GetStringUTFChars(env, stringPath, NULL);
        if (chdir(wpath3) != 0) {
            fprintf(stderr, "Error: Unable to change working directory to %s.\n", wpath3);
            perror(NULL);
        } else if (path) {
            if (chdir(path) != 0) {
                fprintf(stderr, "Error: Unable to change working directory to %s.\n", path);
                perror(NULL);
            }
        }
    
        (*env)->ReleaseStringUTFChars(env, stringPath, wpath3);
    
        goto retAndroid;
    
    bailAndroid:
        ARLOGe("Error: JNI call failure.\n");
        ret = -1;
    retAndroid:
        if (isAttached) (*gJavaVM)->DetachCurrentThread(gJavaVM); // Clean up.
        return (ret);
    }
    

提交回复
热议问题