2011-09-29 7 views
18

Attualmente sto lavorando a un'applicazione Android basata su C, basata su NDK. Questa applicazione ha bisogno di creare file temporanei. Su un normale sistema Linux, userei tmpfile per garantire che questi file siano creati correttamente in una directory temporanea e ripuliti alla fine del processo.Creazione di file temporanei in Android con NDK

Tuttavia, le mie indagini su diversi dispositivi Android sembrano indicare che

  • tmpfile fallisce sempre;
  • non esiste la directory /tmp;
  • directory /data/local/tmp non è presente su tutte le varianti di Android;
  • non vi è alcun set di variabili di ambiente TEMP;
  • mkstemp non funziona meglio di tmpfile.

Ora, io sono sicuro che avrei potuto incidere qualcosa insieme, ma visto che l'SDK offre context.getCacheDir e File.createTempFile per le applicazioni Java, spero che ci sia un equivalente in C-level.

Qualcuno sa di un buon metodo affidabile e cross-Android per la creazione di un file temporaneo?

risposta

9

Il modo migliore che abbiamo trovato è quella di chiamare Context.getCacheDir all'avvio, ottenere il suo percorso con getAbsolutePath, quindi chiamare una funzione JNI per memorizzare quel percorso in una globale. Qualsiasi funzione che desideri creare un file temporaneo aggiunge semplicemente un nome di file temporaneo adatto a quel percorso.

Se si vuole veramente a prenderlo da JNI un'altra alternativa sarebbe quella di passare un Context a una funzione JNI e utilizzare un gruppo di GetMethodID/CallObjectMethod roba di richiamare in Java per getCacheDir, ma il primo approccio è molto più semplice.

Purtroppo, al momento non sembra esserci una soluzione più elegante.

+2

È possibile utilizzare 'libcore' per chiamare' setenv() ', vedere http://stackoverflow.com/a/22315463/192373. Questo potrebbe essere un modo più elegante per mostrare il nome della cache dir a nativo. –

0

mkstemp è disponibile in NDK sotto stdlib.h

+0

Questo aiuto? Penso che mkstemp consumi un 'template' che contiene il percorso completo di una directory temporanea. –

2

La procedura seguente GetMethodID/CallObjectMethod che Ertebølle riferisce. È necessario se si sta lavorando con un'app nativa pura (come costruita da Visual Studio 2015) e non si può usare il codice 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; 
}