title: Sharing via Seekable Pipe or Stream with Another Android App?
body: <p>Lots of <code>Intent</code> actions, like <code>ACTION_VIEW</code>, take a <code>Uri</code> pointing to the content the action should be performed upon. If the content is backed by a file -- whether the <code>Uri</code> points directly to the file, or to a <code>ContentProvider</code> serving the file (<a href="http://developer.android.com/reference/android/support/v4/content/FileProvider.html" rel="noreferrer">see <code>FileProvider</code></a>) -- this generally works.</p>
  
  <p>There are scenarios in which developers do not want to have the content reside in a file for sharing with other apps. One common scenario is for encryption: the decrypted data should reside in RAM, not on disk, to minimize the risk of somebody getting at that decrypted data.</p>
  
  <p>My classic solution to sharing from RAM is to <a href="https://github.com/commonsguy/cw-omnibus/tree/master/ContentProvider/Pipe" rel="noreferrer">use <code>ParcelFileDescriptor</code> and <code>createPipe()</code></a>. However, when the activity responding to <code>ACTION_VIEW</code> (or whatever) gets an <code>InputStream</code> on that pipe, the resulting stream is limited compared to the streams you get when the <code>ContentProvider</code> is serving up content from a file. For example, <a href="https://github.com/commonsguy/cw-omnibus/tree/master/ContentProvider/Pipe" rel="noreferrer">this sample app</a> works fine with Adobe Reader and crashes QuickOffice.</p>
  
  <p>Based on <a href="https://stackoverflow.com/questions/12920429/anyone-have-mediaplayer-working-with-parcelfiledescriptor-and-createpipe">past</a> <a href="https://stackoverflow.com/questions/12894976/anyone-have-mediarecorder-working-with-parcelfiledescriptor-and-createpipe">related</a> questions, my assumption is that <code>createPipe()</code> is truly creating a pipe, and that <a href="https://stackoverflow.com/questions/5806522/how-in-portable-c-to-seek-forward-when-reading-from-a-pipe">pipes are non-seekable</a>. Clients that attempt to "rewind" or "fast forward" run into problems as a result.</p>
  
  <p>I am seeking a reliable solution for sharing in-memory content with a third-party app that gets around this limitation. Specifically:</p>
  
  <ul>
  <li><p>It has to use a <code>Uri</code> syntax that is likely to be honored by client apps (i.e., <code>ACTION_VIEW</code> implementers); solutions that involve something obtuse that client apps are unlikely to recognize (e.g., pass such-and-so via an <code>Intent</code> extra) do not qualify</p></li>
  <li><p>The data to be shared cannot be written to a file as part of the sharing (of course, the client app could wind up saving the received bytes to disk, but let's ignore that risk for the moment)</p></li>
  <li><p>Ideally it does not involve the app looking to share the data opening up a <code>ServerSocket</code> or otherwise exacerbating security risks</p></li>
  </ul>
  
  <p>Possible suggested ideas include:</p>
  
  <ul>
  <li><p>Some way to reconfigure <code>createPipe()</code> that results in a seekable pipe</p></li>
  <li><p>Some way to use a socket-based <code>FileDescriptor</code> that results in a seekable pipe</p></li>
  <li><p>Some kind of RAM disk or something else that feels like a file to the rest of Android but is not persistent</p></li>
  </ul>
  
  <p>A key critierion, if you will, of a working solution is if I can get a PDF served from RAM that QuickOffice can read.</p>
  
  <p>Any suggestions?</p>
  
  <p>Thanks!</p>