使用Intent.ACTION_SEND和Intent.EXTRA_STREAM与Google+应用分享图片

时间:2012-01-26 18:14:53

标签: android android-intent google-plus

我的应用会生成用户可以保存或与他人共享的图像。以下代码适用于大多数应用程序:Messenger,Facebook,Dropbox,电子邮件等。含义,图像由所选应用程序加载,用户可以使用该应用程序成功共享图像。

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")); 

但是,当我在应用列表中选择Google+时,Google +会启动,但该图片不会包含在帖子窗口中。相反,Google +会显示带有以下内容的Toast消息:

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

这有点令人困惑,因为图像在外部SD卡上,即/mnt/sdcard/AppDir/file.png。我正在使用Google+应用的最新更新(2.3.1.242969)。

是否还有另一种与Google +共享图片的技巧?

谢谢。

更新:

我的应用会生成共享的图片,因此以下来自@ chirag-shah的示例并非直接适用。但是,使用MediaStore看起来是正确的想法。我已经确定了以下基本代码:

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")); 
}

这适用于Google+和我测试过的所有其他应用。我打开这个问题以防这不是最佳做法。任何人都可以确认这是正确的方法吗?

3 个答案:

答案 0 :(得分:9)

很棒!您可以指定MediaStore Uri(看起来像 content:// media / external / images / media / 42 ),而不是文件系统上的绝对路径。

示例:

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"));
    }
  }
}

答案 1 :(得分:3)

感谢您提出这个问题!

是的,似乎Google+只接受来自内容提供商的媒体(内容:// uris),而不是文件:// uris。所以我们需要先将图像放入MediaStore。更简单的方法是:

MediaStore.Images.Media.insertImage(context.getContentResolver(), tmpFile.getAbsolutePath(), tmpFile.getName(), null);

答案 2 :(得分:2)

您收到此错误的原因是因为“在SD卡上”并非“在您的设备上”。

有关此问题的讨论,请访问:https://groups.google.com/a/googleproductforums.com/forum/#!topic/google-plus-discuss/pdlOTM8JEXg/discussion

通过MediaStore的解决方案似乎是唯一的解决方案,直到Google通过修补程序更新Google+应用。

更新:上述解决方案仅在您想要一次共享图像时才有效。如果多次调用ContentResolver.insert(...),最终会在图库中多次显示图像。我想出了以下解决方案,试图获取图像的现有ID,如果它不存在,你可以插入它...

Cursor c = getActivity().getContentResolver()
            .query(Images.Media.EXTERNAL_CONTENT_URI,
                    null,
                    Images.Media.DATA + "=?",
                    new String[] { filePath }, null);
    if (c.getCount() > 0 && c.moveToFirst()) {
        Uri shareUri = Uri.withAppendedPath(
                Images.Media.EXTERNAL_CONTENT_URI,
                ""
                        + c.getInt(c
                                .getColumnIndex(Images.Media._ID)));
        c.close();

        startActivity(Intent.createChooser(
                new Intent(Intent.ACTION_SEND)
                        .putExtra(Intent.EXTRA_STREAM,
                                shareUri).setType(
                                   "image/*"), ""));
    } else {
    // ContentResolver.insert(...) and use that uri...
    }