我正在尝试开发一个程序,该程序可以使实际上不在设备上存储的文件中的数据看起来像是存储在设备上的文件。我得到的印象是我需要调整以适应我的目的的 ContentProvider 的一部分是 openFile 命令。当然,openFile 会生成一个 ParcelFileDescriptor。这是我碰壁的地方,因为我在 ParcelFileDescriptor 中找不到任何接收或返回字节或字节数组或文件数据的命令。
例如,假设我想创建一个在后台运行的应用程序,并欺骗我的默认 Android 文件资源管理器,让我认为我的“文档”文件夹中有一个名为“Phantom.txt”的文件,即使实际上没有这样的文件存在于存储空间。然后,当用户打开这个不存在的文件时,后台应用程序提供的数据应该包含(但显然不能包含,因为它甚至不存在)。此应用程序的代码必须包含以下代码:
public class myContentProvider extends ContentProvider {
public ParcelFileDescriptor openFile(Uri uri, String mode) {
if(uri.toString()=="file:\\\\Documents\\Phantom.txt") {
return new myPFD();
} else {
return super.openFile(uri, mode);
}
}
}
public class myPFD extends ParcelFileDescriptor {
private final String filedata = "This file doesn't really exist!\nThis text is actually part of an application!\nIt isn't saved to your flash memory!\nWeird, isn't it?";
private int readPosition;
public myPFD() {
super(ParcelFileDescriptor.open(File.createTempFile("uselessParameterFiller", ".tmp"), ParcelFileDescriptor.MODE_READ_ONLY));
readPosition = 0;
}
//NOTE: There is no actual read(byte [] b) command in ParcelFileDescriptor,
//But this illustrates the kind of functionality I'm looking to achieve.
//I just need to replace the nonexistant ParcelFileDescriptor.read(byte [] b)
//with whatever Android actually uses to read the actual data of the file.
public int read(byte [] b) {
byte [] dataAsBytes = filedata.getBytes();
if(readPosition<dataAsBytes.length) {
int x = readPosition;
for(x=readPosition;x<Math.min(readPosition + b.length, dataAsBytes.length);x++){
b[x - readPosition] = dataAsBytes[x];
}
int output = x - readPosition;
readPosition = x;
return output;
} else {
return -1;
}
}
//For simplicity's sake, I have forgone writing customizations of other reading
//commands such as "int read()", and "int read(byte [], int, int)". Also the
//command "seek(long)", for assigning a reading position.
//I have also neglected to show any commands that would allow me to recieve and
//handle any data that an external app might try to write to this nonexistant
//file. Though I would also like to know how to do this.
}