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

时间:2010-01-27 15:51:38

标签: android file-io android-contentprovider

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

Returning a memory mapped InputStream from a content provider?

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

2 个答案:

答案 0 :(得分:24)

从常用的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);
        }
    }
}

答案 1 :(得分:1)

MemoryFile支持此功能,但公共API尚未最终确定。

相关问题