代码之家  ›  专栏  ›  技术社区  ›  hannasm

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

  •  16
  • hannasm  · 技术社区  · 15 年前

    内容提供者/解析器API提供了一种使用URI和 openInputStream() openOutputStream() 方法。自定义内容提供程序可以覆盖 openFile() 方法使用自定义代码有效地将URI解析为 Stream ; 然而,签名的方法 有一个 ParcelFileDescriptor 返回类型,不清楚如何为从该方法返回的动态生成的内容生成适当的表示。

    Returning a memory mapped InputStream from a content provider?

    是否有实施的例子 ContentProvider.openFile() 现有代码库中动态内容的方法?如果不是,你能推荐源代码或流程吗?

    2 回复  |  直到 7 年前
        1
  •  2
  •   Jeff Sharkey    14 年前

        2
  •  26
  •   Hans-Christoph Steiner    11 年前

    从总是有用的公共软件中查看这个伟大的示例项目。它允许您创建一个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);
            }
        }
    }