title: Permission denied when sharing image through intent
body: <p>I'm trying to share an image from within an app's .apk (in res/drawable) using an <code>Intent</code>. Following the developer.android.com documentation (<a href="http://developer.android.com/training/sharing/send.html" rel="nofollow">[1]</a>, <a href="http://developer.android.com/training/secure-file-sharing/setup-sharing.html" rel="nofollow">[2]</a>, <a href="http://developer.android.com/guide/topics/data/data-storage.html#filesInternal" rel="nofollow">[3]</a>), I assumed I needed to do the following:</p>
  
  <ol>
  <li>Get the image from res/drawable as a <code>Bitmap</code> and save it in the app's internal storage,</li>
  <li>Using a <code>FileProvider</code>, get the content uri for the image,</li>
  <li>Create an <code>Intent</code> with <code>ACTION_SEND</code> action and add the uri as a stream</li>
  <li>Add <code>Intent.FLAG_GRANT_READ_URI_PERMISSION</code> flag to the intent</li>
  </ol>
  
  <p>In practice, I just created the default "Hello World" app, replaced the text view in the main activity by a button that triggers the image sharing, and tried to share the standard ic_launcher.png image from res/drawable.</p>
  
  <p>Everything runs fine until I select the other app to share the image with in the chooser dialog. No matter what I select (Adobe Reader, Facebook, MMS), the app receiving the image crashes and reports the following errors in their logs:</p>
  
  <pre><code>06-01 02:06:53.863: W/ActivityManager(356): Permission denied: checkComponentPermission() owningUid=10099
  06-01 02:06:53.953: E/AndroidRuntime(21961): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.adobe.reader/com.adobe.reader.services.cpdf.ARCreatePDFActivity}: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
  </code></pre>
  
  <p>Using the Android Debug Monitor I can see that the image file was created in the app's internal storage with <code>rw</code> permissions for the owner, no permissions for others.</p>
  
  <p><strong>UPDATE</strong>
  I finally had time to test this more thoroughly on a phone (4.3) and tablet (4.2). At both devices I got the exact same results. The "Permission Denied" warning is always seen in the log, but the end result may differ per app:</p>
  
  <ul>
  <li>Standard Android email app - email is sent without errors/crashes but
  does <em>not</em> contain the attachment, </li>
  <li>Gmail app - email is sent <em>with</em>
  attachment (this is the only case where I found the above code
  works), </li>
  <li>Facebook, Twitter, Adobe Reader - these all crash at the
  moment of selection in the chooser dialog;</li>
  </ul>
  
  <p>Does this mean that there's no "standard" way of sharing a (image) resource from within an app's internal storage, and the sharing logic needs to be customized depending on the receiving app?</p>
  
  <p>AndroidManifest.xml:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.imagesharetest.share" &gt;
      &lt;application
          android:allowBackup="true"
          android:icon="@drawable/ic_launcher"
          android:label="@string/app_name" &gt;
          &lt;activity
              android:name="com.imagesharetest.share.SharingActivity"
              android:label="@string/app_name" &gt;
              &lt;intent-filter&gt;
                  &lt;action android:name="android.intent.action.MAIN" /&gt;
                  &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
              &lt;/intent-filter&gt;
          &lt;/activity&gt;
          &lt;provider
              android:name="android.support.v4.content.FileProvider"
              android:authorities="com.imagesharetest.share.fileprovider"
              android:grantUriPermissions="true"
              android:exported="false"&gt;
              &lt;meta-data
                  android:name="android.support.FILE_PROVIDER_PATHS"
                  android:resource="@xml/filepaths" /&gt;
          &lt;/provider&gt;
      &lt;/application&gt;
  &lt;/manifest&gt;
  </code></pre>
  
  <p>res/filepaths.xml:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;paths&gt;
      &lt;files-path
          name="shareImages"
          path="images/" /&gt;
  &lt;/paths&gt;
  </code></pre>
  
  <p>activity xml:</p>
  
  <pre><code>&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:tools="http://schemas.android.com/tools"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      tools:context="${packageName}.${activityClass}"&gt;
      &lt;Button
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="Go!"
          android:id="@+id/shareButton"
          android:layout_centerVertical="true"
          android:layout_centerHorizontal="true"
          android:onClick="shareImage"/&gt;
  &lt;/RelativeLayout&gt;
  </code></pre>
  
  <p>activity .java:</p>
  
  <pre><code>package com.imagesharetest.share;
  
  import android.app.Activity;
  import android.content.Intent;
  import android.graphics.Bitmap;
  import android.graphics.BitmapFactory;
  import android.net.Uri;
  import android.os.Bundle;
  import android.support.v4.content.FileProvider;
  import android.view.View;
  
  import java.io.File;
  import java.io.FileOutputStream;
  
  public class SharingActivity extends Activity {
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_sharing);
      }
  
      public void shareImage(View v) {
          Uri icLauncherFileURI = FileProvider.getUriForFile(
                  SharingActivity.this, "com.imagesharetest.share.fileprovider",
                  getICLauncherBitmapAsInternalFile());
  
          Intent shareIntent = getShareIntentFor(icLauncherFileURI);
          startActivity(Intent.createChooser(shareIntent, "Sending ic_launcher..."));
      }
  
      private File getICLauncherBitmapAsInternalFile() {
          Bitmap icLauncherBitmap = BitmapFactory.decodeResource(
                  getResources(), R.drawable.ic_launcher);
          File imagePath = new File(getFilesDir(), "images");
          imagePath.mkdirs();
          File icLauncherFile = new File(imagePath, "shared_image.png");
          saveBitmapAsFile(icLauncherBitmap, icLauncherFile);
  
          return icLauncherFile;
      }
  
      private void saveBitmapAsFile(Bitmap bmp, File file) {
          try {
              FileOutputStream fos = new FileOutputStream(file);
  //            FileOutputStream fos = SharingActivity.this.openFileOutput(file.getName(), Context.MODE_WORLD_READABLE);
              bmp.compress(Bitmap.CompressFormat.PNG, 100, fos);
              fos.flush();
              fos.close();
          } catch (java.io.IOException e) {
              e.printStackTrace();
          }
      }
  
      private Intent getShareIntentFor(Uri contentUri) {
          Intent shareIntent = new Intent();
          shareIntent.setAction(Intent.ACTION_SEND);
          shareIntent.putExtra(Intent.EXTRA_STREAM, contentUri);
          shareIntent.setType("image/png");
          shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
          return shareIntent;
      }
  }
  </code></pre>