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.
");
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.
", wpath3);
perror(NULL);
} else if (path) {
if (chdir(path) != 0) {
fprintf(stderr, "Error: Unable to change working directory to %s.
", path);
perror(NULL);
}
}
(*env)->ReleaseStringUTFChars(env, stringPath, wpath3);
goto retAndroid;
bailAndroid:
fprintf(stderr, "Error: JNI call failure.
");
ret = -1;
retAndroid:
if (isAttached) (*gJavaVM)->DetachCurrentThread(gJavaVM); // Clean up.
return (ret);
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…