2011-09-29 10 views
18

현재 C 기반 NDK 기반 Android 애플리케이션에서 작업 중입니다. 이 응용 프로그램은 임시 파일을 만들어야합니다. 일반적인 리눅스 시스템에서는 tmpfile을 사용하여 이러한 파일이 임시 디렉토리에 제대로 생성되고 프로세스가 끝날 때 정리되도록합니다.NDK로 Android에서 임시 파일 만들기

그러나, 다양한 안드로이드 장치에 내 조사

  • tmpfile 항상 실패하는 것을 나타내는 것;
  • /tmp 디렉토리가 없습니다.
  • 디렉토리 /data/local/tmp은 Android의 모든 변형에 존재하지 않습니다.
  • TEMP 환경 변수 집합이 없습니다.
  • mkstemptmpfile보다 좋지 않습니다.

지금, 내가 뭔가를 함께 해킹 수 있다고 확신하지만, SDK는 Java 응용 프로그램에 대한 context.getCacheDirFile.createTempFile을 제공한다는보고, 나는 C 수준에서 동등한이 있기를 바랍니다.

임시 파일을 만드는 데있어 신뢰할 수 있고 교차 Android 방식을 아는 사람이 있습니까?

답변

9

가장 좋은 방법은 시작시 Context.getCacheDir을 호출하고 경로를 getAbsolutePath으로 가져온 다음 해당 경로를 전역에 저장하는 JNI 함수를 호출하는 것입니다. 임시 파일을 만들려는 모든 함수는 해당 임시 파일 이름을 해당 경로에 추가하기 만하면됩니다. 당신이 정말로 JNI에서 페치하려면

또 다른 대안은 JNI 함수에 Context에 전달하고 getCacheDir 다시 자바로 전화를 GetMethodID/CallObjectMethod 잔뜩 사용하는 것입니다 만, 이전의 접근 방법은 많이있다 더 간단 해.

불행히도 지금은 좀 더 우아한 해결책이없는 것 같습니다.

+2

'setenv()'를 호출 할 때'libcore'를 사용할 수 있습니다. http://stackoverflow.com/a/22315463/192373을 참조하십시오. 이것은 네이티브에 캐시 디렉토리의 이름을 표시하는보다 우아한 방법 일 수 있습니다. –

0

은 mkstemp stdlib.h 이하

+0

이 정보가 도움이됩니까? mkstemp는 temp 디렉토리에 대한 전체 경로를 포함하는'template'을 사용한다고 생각합니다. –

2

Ertebolle가 참조 대해서 GetMethodID/CallObjectMethod 절차는 아래 NDK 가능하다. 순수한 네이티브 앱 (예 : Visual Studio 2015로 작성)으로 작업하고 Java 코드를 사용할 수없는 경우 필요합니다.

std::string android_temp_folder(struct android_app *app) { 
    JNIEnv* env; 
    app->activity->vm->AttachCurrentThread(&env, NULL); 

    jclass activityClass = env->FindClass("android/app/NativeActivity"); 
    jmethodID getCacheDir = env->GetMethodID(activityClass, "getCacheDir", "()Ljava/io/File;"); 
    jobject cache_dir = env->CallObjectMethod(app->activity->clazz, getCacheDir); 

    jclass fileClass = env->FindClass("java/io/File"); 
    jmethodID getPath = env->GetMethodID(fileClass, "getPath", "()Ljava/lang/String;"); 
    jstring path_string = (jstring)env->CallObjectMethod(cache_dir, getPath); 

    const char *path_chars = env->GetStringUTFChars(path_string, NULL); 
    std::string temp_folder(path_chars); 

    env->ReleaseStringUTFChars(path_string, path_chars); 
    app->activity->vm->DetachCurrentThread(); 
    return temp_folder; 
}