2013-07-22 14 views
12

Esiste un modo per la mia app per Android di recuperare e impostare attributi utente estesi dei file? C'è un modo per utilizzare java.nio.file.Files su Android? C'è un modo per usare setfattr e getfattr dalla mia app dalvik? So che Android usa il file system ext4, quindi penso che dovrebbe essere possibile. Eventuali suggerimenti?Come posso impostare attributi utente estesi su file Android?

risposta

12

La libreria Java di Android e la libreria Bionic C non la supportano. Quindi devi usare il codice nativo con Linux syscalls per quello.

Ecco alcuni esempi di codice per iniziare, testati su Android 4.2 e Android 4.4.

XAttrNative.java

package com.appfour.example; 

import java.io.IOException; 

public class XAttrNative { 
    static { 
     System.loadLibrary("xattr"); 
    } 

    public static native void setxattr(String path, String key, String value) throws IOException; 
} 

xattr.c

#include <string.h> 
#include <jni.h> 
#include <asm/unistd.h> 
#include <errno.h> 

void Java_com_appfour_example_XAttrNative_setxattr(JNIEnv* env, jclass clazz, 
     jstring path, jstring key, jstring value) { 
    char* pathChars = (*env)->GetStringUTFChars(env, path, NULL); 
    char* keyChars = (*env)->GetStringUTFChars(env, key, NULL); 
    char* valueChars = (*env)->GetStringUTFChars(env, value, NULL); 

    int res = syscall(__NR_setxattr, pathChars, keyChars, valueChars, 
      strlen(valueChars), 0); 

    if (res != 0) { 
     jclass exClass = (*env)->FindClass(env, "java/io/IOException"); 
     (*env)->ThrowNew(env, exClass, strerror(errno)); 
    } 

    (*env)->ReleaseStringUTFChars(env, path, pathChars); 
    (*env)->ReleaseStringUTFChars(env, key, keyChars); 
    (*env)->ReleaseStringUTFChars(env, value, valueChars); 
} 

Questo funziona bene nella memoria interna, ma non su (emulato) memorizzazione esterna che utilizza il file system sdcardfs o altro kernel funzioni per disabilitare funzionalità non supportate dal filesystem FAT come symlinks e attributi estesi. Probabilmente lo fanno perché è possibile accedere all'archiviazione esterna collegando il dispositivo a un PC e gli utenti si aspettano che la copia di file avanti e indietro preservi tutte le informazioni.

Così funziona:

File dataFile = new File(getFilesDir(),"test"); 
dataFile.createNewFile(); 
XAttrNative.setxattr(dataFile.getPath(), "user.testkey", "testvalue"); 

mentre questo getta IOException con il messaggio di errore: "Operazione non supportato su trasporto endpoint":

File externalStorageFile = new File(getExternalFilesDir(null),"test"); 
externalStorageFile.createNewFile(); 
XAttrNative.setxattr(externalStorageFile.getPath(), "user.testkey", "testvalue"); 
+0

perché la seconda genera un'eccezione? – Blackbelt

+0

Perché Google non desidera alcuna funzionalità che vada oltre quella supportata da FAT per funzionare su memoria esterna, emulata o meno. Ciò include collegamenti simbolici, attributi estesi, ... Lo fanno rispettare con sdcardfs e altre funzionalità del kernel. Probabilmente lo fanno perché è possibile accedere all'archiviazione esterna collegando il dispositivo a un PC e gli utenti si aspettano che la copia di file avanti e indietro preservi tutte le informazioni. –

+0

beh, in realtà questo dovrebbe essere parte della tua risposta – Blackbelt