Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sharing an image with Google+ app using Intent.ACTION_SEND and Intent.EXTRA_STREAM

Tags:

My app generates images that a user can save or share with others. The code below works for most apps: Messenger, Facebook, Dropbox, email, etc. Meaning, the image is loaded by the chosen app, and a user can share the image successfully with that app.

Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("image/png");
File o = new File(dir, "file.png");
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(o));
startActivity(Intent.createChooser(intent , "Send options")); 

However, when I choose Google+ in the list of apps, google+ starts, but the image is not included in the post window. Instead, google+ displays a Toast message with:

"You can only post photos stored on your device."

This is a little confusing, because the image is on the external SD card, i.e. /mnt/sdcard/AppDir/file.png. I am using the latest update of Google+ app (2.3.1.242969).

Is there another trick to sharing an image with google+?

Thank you.

UPDATE:

My app generates the images that are shared, so the sample below from @chirag-shah wasn't directly applicable. But, using the MediaStore looks like the right idea. I've settled on the basic code below:

void shareImage(int position) {
    File f = getFileFor(position);
    ContentValues values = new ContentValues(2);
    values.put(MediaStore.Images.Media.MIME_TYPE, "image/png");
    values.put(MediaStore.Images.Media.DATA, f.getAbsolutePath());
    Uri uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setType("image/png");
    intent.putExtra(Intent.EXTRA_STREAM, uri);
    startActivity(Intent.createChooser(intent , "Send options")); 
}

This works with Google+ and all other apps I've tested with. I'm leaving the question open in case this is not best practice. Can anyone confirm that this is the right way to do it?

like image 401
stephen.z Avatar asked Jan 26 '12 18:01

stephen.z


People also ask

How do I share a bitmap with intent?

setType("image/png"); intent. putExtra(Intent. EXTRA_STREAM, b); startActivity(Intent. createChooser(intent , "Share"));

How do I send intent from one app to another?

When you construct an intent, you must specify the action you want the intent to perform. Android uses the action ACTION_SEND to send data from one activity to another, even across process boundaries. You need to specify the data and its type.


2 Answers

Great catch! You can specify the MediaStore Uri (which looks like content://media/external/images/media/42) instead of the absolute path on the file system.

Example:

public class MyActivity extends Activity {
  ...
  static final int IMAGE_REQUEST = 0;

  protected void pickImage() {
    Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    startActivityForResult(intent, IMAGE_REQUEST);
  }

  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == IMAGE_REQUEST) {
      Uri uri = data.getData();

      Intent intent = new Intent(Intent.ACTION_SEND);
      intent.setType("image/png");
      // uri looks like content://media/external/images/media/42
      intent.putExtra(Intent.EXTRA_STREAM, uri);
      startActivity(Intent.createChooser(intent , "Share"));
    }
  }
}
like image 86
Chirag Shah Avatar answered Dec 15 '22 19:12

Chirag Shah


Thanks for raising this question!

Yes it seems that Google+ only accepts media from content providers (content:// uris), not file:// uris. So we need to put the image into MediaStore first. An easier way to do this is:

MediaStore.Images.Media.insertImage(context.getContentResolver(), tmpFile.getAbsolutePath(), tmpFile.getName(), null);
like image 45
Randy Sugianto 'Yuku' Avatar answered Dec 15 '22 19:12

Randy Sugianto 'Yuku'