应用程序以本机代码进行外部存储的路径 [英] App's path for external storage in native code

查看:91
本文介绍了应用程序以本机代码进行外部存储的路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为我的应用程序编写本机库,以便我可以用本机代码执行所有文件操作.我读到getExternalStorageDirectory()给出目录的外部存储的路径.

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 the path of the external storage of directory.

我的问题是,如何在不将位置硬编码为某个字符串的情况下访问相同内容? android ndk中有任何函数可以与C ++代码中的Java getExternalStorageDirectory()提供相同的功能吗?

My question is how can i access the same without hard-coding the location to some string? Is there any function in android ndk that can give the same function as getExternalStorageDirectory() of java in C++ code?

推荐答案

JNI是您的朋友,这并不复杂,因为getExternalStorageDirectory是静态方法.此函数会获取值,并将工作目录更改为该值,以防万一.

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 <jni.h>
#include <unistd.h> // chdir()
#include <sys/param.h> // 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);
}

这篇关于应用程序以本机代码进行外部存储的路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆