Есть ли способ, с помощью которого приложение для Android может извлекать и устанавливать расширенные пользовательские атрибуты файлов? Есть ли способ использовать java.nio.file.Files
для Android? Есть ли способ использовать setfattr
и getfattr
из моего приложения dalvik? Я знаю, что андроид использует файловую систему ext4, поэтому я предполагаю, что это должно быть возможно. Любые предложения?
Как установить расширенные пользовательские атрибуты в файлах Android?
Ответ 1
Библиотека Android Java и библиотека Bionic 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");