Подтвердить что ты не робот

Совместное использование изображения с помощью приложения Google+ с использованием Intent.ACTION_SEND и Intent.EXTRA_STREAM

Мое приложение создает изображения, которые пользователь может сохранить или поделиться с другими. Ниже приведен код для большинства приложений: 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 +?

Спасибо.

UPDATE:

Мое приложение генерирует изображения, которые являются общими, поэтому образец ниже из @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+ и всеми другими приложениями, с которыми я тестировал. Я оставляю вопрос открытым, если это не лучшая практика. Кто-нибудь может подтвердить, что это правильный способ сделать это?

4b9b3361

Ответ 1

Отличная добыча! Вы можете указать 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"));
    }
  }
}

Ответ 2

Спасибо, что подняли этот вопрос!

Да, похоже, что Google+ принимает только медиа от контент-провайдеров (контент://uris), а не файл://uris. Поэтому нам нужно сначала поместить изображение в MediaStore. Более простой способ сделать это:

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

Ответ 3

Причина, по которой вы получаете эту ошибку, связана с тем, что "на SD-карте" НЕ "на вашем устройстве".

Обсуждение этой проблемы можно найти здесь: https://groups.google.com/a/googleproductforums.com/forum/#!topic/google-plus-discuss/pdlOTM8JEXg/discussion

Обходной путь через MediaStore, по-видимому, является единственным решением, пока Google не обновит приложение Google+ с исправлением.

Обновление. Решение, упомянутое выше, работает только в том случае, если вы хотите разделить изображение за один раз. Если вы вызовете ContentResolver.insert(...) несколько раз, вы получите изображение, отображаемое несколько раз в вашей галерее. Я придумал следующее решение, которое пытается получить существующий идентификатор изображения, и если он не существует, вы можете вставить его...

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...
    }