2013-07-22 12 views
12

Gibt es eine Möglichkeit für meine Android-App, erweiterte Benutzerattribute von Dateien abzurufen und festzulegen? Gibt es eine Möglichkeit, java.nio.file.Files auf Android zu verwenden? Gibt es eine Möglichkeit, setfattr und getfattr von meiner dalvik App zu verwenden? Ich weiß, dass Android das ext4 Dateisystem benutzt, also denke ich, dass es möglich sein sollte. Irgendwelche Vorschläge?Wie lege ich erweiterte Benutzerattribute für Android-Dateien fest?

Antwort

12

Die Android Java-Bibliothek und die bionische C-Bibliothek unterstützen dies nicht. Sie müssen dafür nativen Code mit Linux-Syscalls verwenden.

Hier ist ein Beispielcode, mit dem Sie loslegen können, getestet auf Android 4.2 und 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); 
} 

Dieser auf internen Speicher funktioniert gut, aber nicht auf (emulierten) externen Speicher, der die sdcardfs Dateisystem oder einem anderen Kernel verwendet Funktionen zum Deaktivieren von Funktionen, die nicht vom FAT-Dateisystem unterstützt werden, z. B. Symlinks und erweiterte Attribute. Wahrscheinlich tun sie dies, weil auf externen Speicher zugegriffen werden kann, indem das Gerät mit einem PC verbunden wird und die Benutzer erwarten, dass das Kopieren von Dateien hin und her alle Informationen erhält.

So funktioniert das:

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

während dies wirft IOException mit der Fehlermeldung: "Operation nicht auf Transportendpunkt unterstützt":

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

warum die zweite eine Ausnahme auslöst? – Blackbelt

+0

Weil Google keine Funktionalität will, die über das von FAT unterstützte hinausgeht, um auf externem Speicher zu arbeiten - emuliert oder nicht. Dazu gehören Symlinks, erweiterte Attribute, ... Sie erzwingen dies mit sdcardfs und anderen Kernel-Funktionen. Wahrscheinlich tun sie dies, weil auf externen Speicher zugegriffen werden kann, indem das Gerät mit einem PC verbunden wird und die Benutzer erwarten, dass das Kopieren von Dateien hin und her alle Informationen erhält. –

+0

Nun eigentlich sollte dies Teil Ihrer Antwort sein – Blackbelt

Verwandte Themen