title: openInputStream cause SecurityException:Permission Denial (Android N+)
body: <p>I need help with this problem since I'm new to Android.</p>
  
  <p>My app support <strong>JellyBean (16)</strong> up to <strong>Oreo (26)</strong>.</p>
  
  <p>I have an <strong>UploadService</strong> that requires <code>openInputStream()</code> to upload data because the new behavior in Nougat. </p>
  
  <p>This code works fine in Marshmallow and below, but always give me <code>SecurityException</code> crash on Nougat. And it crashes on the line where <code>openInputStream()</code> is called with <strong>error</strong>:</p>
  
  <blockquote>
    <p>java.lang.SecurityException: Permission Denial: reading com.miui.gallery.provider.GalleryOpenProvider uri content://com.miui.gallery.open/raw/%2Fstorage%2Femulated%2F0%2FDCIM%2FCamera%2FIMG_20171008_182834.jpg from pid=30846, uid=10195 requires the provider be exported, or grantUriPermission()</p>
  </blockquote>
  
  <p>The file uri could be from various app (gallery, camera, etc). I've narrowed down the problem to uri that comes from <code>ACTION_GET_CONTENT</code> intent (anything that comes from camera intent or MediaRecorder works fine). </p>
  
  <p>I think it's because the uri lost its permission when passed into the service, but adding <code>Intent.FLAG_GRANT_WRITE_URI_PERMISSION</code> and <code>Intent.FLAG_GRANT_READ_URI_PERMISSION</code> doesn't help.</p>
  
  <p>Also tried adding <code>FLAG_GRANT_PERSISTABLE_URI_PERMISSION</code> flag, but it still crashes and <code>getContentResolver().takePersistableUriPermission()</code> causes another <code>SecurityException</code> crash saying the said uri hasn't been granted persistable uri...</p>
  
  <p><strong>UploadService.java</strong></p>
  
  <pre><code>  //.......... code to prepare for upload
  
    if ( contentResolver != null &amp;&amp; schemeContentFile ) {
              mMime = UtilMedia.getMime(this, uri);
  
              try {
                  InputStream is     = contentResolver.openInputStream(uri);
                  byte[]      mBytes = getBytes(is);
  
                  Bundle fileDetail = UtilMedia.getFileDetailFromUri(this, uri);
  
                  Log.d("AndroidRuntime", TAG + " " + mMime + " " + UtilToString.bundleToString(fileDetail) + " imageFile " + mFile);
  
                  currTitle = fileDetail.getString(OpenableColumns.DISPLAY_NAME, "");
                  MediaType type = MediaType.parse(mMime);
                  requestFile = RequestBody.create(type, mBytes);
  
              } catch ( IOException e ) {
                  e.printStackTrace();
              } catch ( SecurityException e ) {
                  e.printStackTrace();
              }
          }
  
    //............continue to upload
  </code></pre>
  
  <p>Thank You in advance.</p>
  
  <p><strong>EDIT (Additional Info)</strong>
  In case this is important. The activity calling the service is calling <code>finish()</code> after it sends all the required data to the service, letting user to use the app, while the upload resumed in the background (with notification to tell user). And also, the upload works based on queue, and user can choose to upload multiple files in the activity. The first file always gets uploaded, but the files after always return with the crash.</p>