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