Пользовательский ContentProvider - openInputStream (), openOutputStream () - PullRequest
16 голосов
/ 27 января 2010

API поставщика / распознавателя контента предоставляют сложный, но надежный способ передачи данных между процессами с использованием URI и методов openInputStream() и openOutputStream(). Пользовательские поставщики контента могут переопределить метод openFile() пользовательским кодом для эффективного преобразования URI в Stream; однако сигнатура метода openFile() имеет тип возврата ParcelFileDescriptor, и неясно, как можно сгенерировать правильное представление для динамически сгенерированного содержимого для возврата из этого метода.

Возвращение карты памяти InputStream от поставщика контента?

Существуют ли примеры реализации метода ContentProvider.openFile() для динамического контента в существующей кодовой базе? Если нет, можете ли вы предложить исходный код или процесс для этого?

Ответы [ 2 ]

24 голосов
/ 06 февраля 2013

Проверьте этот замечательный пример проекта из всегда полезного 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 голос
/ 29 января 2010

MemoryFile поддерживает это, но публичный API еще не завершен.

...