title: Share an image with a content provider in Android app
body: <p>I'm developing an Android app that is a gallery of images in which the images are downloaded from internet for display on the screen of smathphone. Images are displayed one at a time and the application has a button to share the image that is displayed. </p>
  
  <p>Following the directions I've found in some StackOverflow post which indicated that the right way to share an image was using a ContentProvider I have implemented the following code that works to share the images of certain applications (eg Twitter, Gmail ...) but does not work for others (Facebook, Yahoo, MMS ...).</p>
  
  <p>Then I show the code used hoping you can help me get the correct implementation to share images in all applications.</p>
  
  <p>Initially I capture the button press to share:</p>
  
  <pre><code>@Override
  public boolean onOptionsItemSelected(MenuItem item) {
  
      if (item.getItemId() == R.id.menu_share) {
  
          // I get the image being displayed on the screen
          View root = getView();
          ImageView imageView = (ImageView) root.findViewById(R.id.image);
          Drawable imageToShareDrawable = imageView.getDrawable();
  
          if (imageToShareDrawable instanceof BitmapDrawable) {
  
              // I convert the image to Bitmap
              Bitmap imageToShare = ((BitmapDrawable) imageToShareDrawable).getBitmap();
  
              // Name of de image extracted from a bean property
              String fileName = quote.getImage(); 
  
              // I keep the image in the folder "files" of internal storage application
              TempInternalStorage.createCachedFile(fileName, imageToShare, getActivity().getApplicationContext());
  
              // I start the Activity to select the application to share the image after the intent Built with the method "getDefaultShareIntent"
              startActivity(getDefaultShareIntent(fileName));
          } else {
              Toast.makeText(getActivity().getApplicationContext(), "Please wait, the quote is being downloaded", Toast.LENGTH_SHORT).show();
          }
      } 
  
      return true;
  }
  </code></pre>
  
  <p>The method for saving the image to the internal storage of the application is as follows:</p>
  
  <pre><code>public static void createCachedFile(String fileName, Bitmap image, Context context) {
  
      try {
          File file = new File(context.getFilesDir(), fileName);
  
          if (!file.exists()) {
              FileOutputStream fos = new FileOutputStream(file);
              image.compress(Bitmap.CompressFormat.JPEG, 100, fos);
              fos.flush();
              fos.close();
          } 
      } catch (Exception e) {
          Log.e("saveTempFile()", "**** Error");
      }
  }
  </code></pre>
  
  <p>The method that constructs the Intent to share it:</p>
  
  <pre><code>private Intent getDefaultShareIntent(String fileName) {
      final Intent shareIntent = new Intent();
      shareIntent.setAction(Intent.ACTION_SEND);
      shareIntent.setType("image/jpeg");
      shareIntent.putExtra(Intent.EXTRA_TEXT, "Test text");
      shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://" + CachedFileProvider.AUTHORITY + File.separator + "img" + File.separator + fileName));
      shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
  
      return shareIntent;
  }
  </code></pre>
  
  <p>Finally ContentProvider code is as follows:</p>
  
  <pre><code>public class CachedFileProvider extends ContentProvider {
  
  private static final String CLASS_NAME = "CachedFileProvider";
  
  public static final String AUTHORITY = "com.example.appname.cachefileprovider";
  
  private UriMatcher uriMatcher;
  
  @Override
  public boolean onCreate() {
      uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
  
      uriMatcher.addURI(AUTHORITY, "img/*", 1);
  
      return true;
  }
  
  @Override
  public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
  
      String LOG_TAG = CLASS_NAME + " - openFile";
  
      Log.i(LOG_TAG, "Called with uri: '" + uri + "'." + uri.getLastPathSegment());
  
      switch (uriMatcher.match(uri)) {
  
      case 1:
  
          String fileLocation = getContext().getFilesDir() + File.separator + uri.getLastPathSegment();
  
          ParcelFileDescriptor image = ParcelFileDescriptor.open(new File(fileLocation), ParcelFileDescriptor.MODE_READ_ONLY);
  
          return image;
  
      default:
          Log.i(LOG_TAG, "Unsupported uri: '" + uri + "'.");
          throw new FileNotFoundException("Unsupported uri: " + uri.toString());
      }
  }
  
  @Override
  public int update(Uri uri, ContentValues contentvalues, String s, String[] as) {
      return 0;
  }
  
  @Override
  public int delete(Uri uri, String s, String[] as) {
      return 0;
  }
  
  @Override
  public Uri insert(Uri uri, ContentValues contentvalues) {
      return null;
  }
  
  @Override
  public String getType(Uri uri) {
      return null;
  }
  
  @Override
  public Cursor query(Uri uri, String[] projection, String s, String[] as1, String s1) {
  
      MatrixCursor c = null;
  
      Log.i("&gt;&gt;&gt;&gt; projection", java.util.Arrays.toString(projection));
  
      String fileLocation = getContext().getFilesDir() + File.separator + uri.getLastPathSegment();
  
      File file = new File(fileLocation);
  
      long time = System.currentTimeMillis();
  
      c = new MatrixCursor(new String[] { "_id", "_data", "orientation", "mime_type", "datetaken", "_display_name" });
  
      c.addRow(new Object[] { 0,  file, 0, "image/jpeg", time, uri.getLastPathSegment() });
  
      return c;
  }
  
  @Override
  public String[] getStreamTypes(Uri uri, String mimeTypeFilter) {
      return null;
  }
  </code></pre>
  
  <p>}</p>
  
  <p>I have found that when the image is sharing some applications only call the method "query" (these are where the code does not work and I can not share the image) while there are others that also call the method "query" also call the method "openFile" and these do work and I can share the image.</p>
  
  <p>I hope you can help me, thank you very much in advance.</p>