Как установить расширенные пользовательские атрибуты для файлов Android?
Есть ли способ для моего приложения для Android, чтобы получить и установить расширенные пользовательские атрибуты файлов? Есть ли способ использовать java.nio.file.Files
на андроид? Есть ли способ использовать setfattr
а также getfattr
из моего приложения dalvik? Я знаю, что Android использует файловую систему ext4, поэтому я думаю, что это должно быть возможно. Какие-либо предложения?
1 ответ
Java-библиотека Android и бионическая библиотека C не поддерживают ее. Таким образом, вы должны использовать нативный код с системными вызовами Linux для этого.
Ниже приведен пример кода, с которого можно начать тестирование на Android 4.2 и 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);
}
Это прекрасно работает на внутреннем хранилище, но не на (эмулированном) внешнем хранилище, которое использует файловую систему sdcardfs или другие функции ядра для отключения функций, не поддерживаемых файловой системой FAT, таких как символические ссылки и расширенные атрибуты. Возможно, они делают это, потому что к внешнему хранилищу можно получить доступ, подключив устройство к ПК, и пользователи ожидают, что копирование файлов назад и вперед сохраняет всю информацию.
Так что это работает:
File dataFile = new File(getFilesDir(),"test");
dataFile.createNewFile();
XAttrNative.setxattr(dataFile.getPath(), "user.testkey", "testvalue");
в то время как это бросает IOException
с сообщением об ошибке: "Операция не поддерживается на транспортной конечной точке":
File externalStorageFile = new File(getExternalFilesDir(null),"test");
externalStorageFile.createNewFile();
XAttrNative.setxattr(externalStorageFile.getPath(), "user.testkey", "testvalue");