自定义ContentProvider – openInputStream(),openOutputStream()

内容提供程序/解析程序API提供了一种使用URI和openInputStream()以及openOutputStream()方法在进程之间传输数据的复杂但强大的方法。 自定义内容提供程序可以使用自定义代码覆盖openFile()方法,以有效地将URI解析为Stream ; 但是, openFile()的方法签名具有ParcelFileDescriptor返回types,并且不清楚如何为从此方法返回的动态生成内容生成正确的表示。

从内容提供程序返回内存映射的InputStream?

是否有在现有代码库中为动态内容实现ContentProvider.openFile()方法的示例? 如果没有,你可以建议这样做的源代码或过程吗?

MemoryFile支持这一点,但公共API尚未最终确定。

从总是有用的CommonsWare中查看这个很棒的示例项目。 它允许您创建一个ParcelFileDescriptor管道,其中包含您想要的任何InputStream,以及另一侧的接收应用程序:

https://github.com/commonsguy/cw-omnibus/tree/master/ContentProvider/Pipe

关键部分是在openFile中创建管道:

 public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { ParcelFileDescriptor[] pipe=null; try { pipe=ParcelFileDescriptor.createPipe(); AssetManager assets=getContext().getResources().getAssets(); new TransferThread(assets.open(uri.getLastPathSegment()), new AutoCloseOutputStream(pipe[1])).start(); } catch (IOException e) { Log.e(getClass().getSimpleName(), "Exception opening pipe", e); throw new FileNotFoundException("Could not open pipe for: " + uri.toString()); } return(pipe[0]); } 

然后创建一个保持管道满的线程:

 static class TransferThread extends Thread { InputStream in; OutputStream out; TransferThread(InputStream in, OutputStream out) { this.in = in; this.out = out; } @Override public void run() { byte[] buf = new byte[8192]; int len; try { while ((len = in.read(buf)) > 0) { out.write(buf, 0, len); } in.close(); out.flush(); out.close(); } catch (IOException e) { Log.e(getClass().getSimpleName(), "Exception transferring file", e); } } }