Is there a way for my android app to retrieve and set extended user attributes of files? Is there a way to use java.nio.file.Files
on android? Is there any way to use setfattr
and getfattr
from my dalvik app? I know that android use the ext4 file system, so i guess it should be possible. Any suggestions?
The Android Java library and the bionic C library do not support it. So you have to use native code with Linux syscalls for that.
Here is some sample code to get you started, tested on Android 4.2 and 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);
}
This works fine on internal storage but not on (emulated) external storage which uses the sdcardfs filesystem or other kernel functions to disable features not supported by the FAT filesystem such as symlinks and extended attributes. Arguably they do this because external storage can be accessed by connecting the device to a PC and the users expects that copying files back and forth preserves all information.
So this works:
File dataFile = new File(getFilesDir(),"test");
dataFile.createNewFile();
XAttrNative.setxattr(dataFile.getPath(), "user.testkey", "testvalue");
while this throws IOException
with the error message: "Operation not supported on transport endpoint":
File externalStorageFile = new File(getExternalFilesDir(null),"test");
externalStorageFile.createNewFile();
XAttrNative.setxattr(externalStorageFile.getPath(), "user.testkey", "testvalue");
© 2022 - 2024 — McMap. All rights reserved.