Доля намерения Google+ не может получить доступ к изображению
Я вызываю намерение поделиться изображением. это работает с большинством провайдеров, НО с Google+. Google+ открывает активность сообщения без изображения и отображает тост "Вы можете публиковать фотографии, сохраненные на вашем устройстве". в то же время.
File f = storeImage(image); // f = /data/data/com.myapp/files/1333070776978.jpg
Uri uri = Uri.fromFile(f);
Intent share = new Intent(Intent.ACTION_SEND);
share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
share.setType("image/jpeg");
share.putExtra(Intent.EXTRA_STREAM, uri);
share.putExtra(Intent.EXTRA_TITLE,"Share that title");
share.putExtra(Intent.EXTRA_SUBJECT,"Share that subject");
share.putExtra(Intent.EXTRA_TEXT,"Check that out...");
share.putExtra("sms_body", "sms body");
startActivity(Intent.createChooser(share, "Share Image"));
Я сохраняю изображение с помощью
Context.openFileOutput(fileName, Context.MODE_WORLD_READABLE);
я понял, что, установив FLAG_GRANT_READ_URI_PERMISSION, я предоставляю конкретный доступ Google+ к этому файлу.
он работает, когда я храню изображение в MediaStore, но на самом деле я не хочу помешать галерее изображений пользователей.
ContentValues values = new ContentValues(2);
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.Images.Media.DATA, f.getAbsolutePath());
Uri uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
любые советы приветствуются
Саймон
Ответы
Ответ 1
Google+ не может получить доступ к file://
Uris из частной папки другого приложения. И FLAG_GRANT_READ_URI_PERMISSION
не работает в этом случае, потому что это только для Uris в "данных" части намерения, но не для дополнительных функций.
Общим обходным решением является добавление его в галерею (через MediaStore
), но это не обязательно. Правильное решение в этом случае - использовать FileProvider
:
FileProvider - это специальный подкласс ContentProvider, который облегчает безопасное совместное использование файлов, связанных с приложением, путем создания content://
Uri для файла вместо file:///
Uri.
Сначала разместите следующее в своем AndroidManifest.xml
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.myapp.testshare.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
Затем этот файл в res\xml\filepaths.xml
:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<files-path name="shared_images" path="shared_images/" />
</paths>
Затем, чтобы поделиться файлом изображения, убедитесь, что он указан в указанном выше пути (т.е. shared_images
в разделе getFilesDir()
) и постройте намерение следующим образом:
File file = getImageFileToShare();
Uri fileUri = FileProvider.getUriForFile(this, "com.myapp.testshare.fileprovider", file);
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_STREAM, fileUri);
intent.setType("image/png");
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
(убедитесь, что полномочия, указанные в методе getUriForFile()
, совпадают с тем, который указан в манифесте).
Это создаст content://
Uri (например, content://com.myapp.testshare.fileprovider/shared_images/img1.png
, что приложение Google+ сможет получить доступ и, таким образом, включить его в сообщение).
Ответ 2
Саймон
Кажется, что он работает, чтобы установить разрешение после установки uri.
share.putExtra(Intent.EXTRA_STREAM, uri);
share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Ответ 3
попробуйте этот, у меня также возникают проблемы с этим, поскольку он появляется в Галерее, если я вставляю.
//здесь присутствует экземпляр файла
String uriString = MediaStore.Images.Media.insertImage(getContentResolver(),
out.getAbsolutePath(),null,null);
intent.putExtra(Intent.EXTRA_STREAM,Uri.parse(uriString));
https://github.com/google-plus/google-plus-office-hours/blob/master/2012_08_14-curiosity-android-app/src/com/example/CuriosityActivity.java
Ответ 4
Если вы используете пользовательский ContentProvider, вы должны проверить правильность типа MIME изображений. Правильным MIME для jpeg является "image/jpeg". Если вы вернете "image/jpg" в переопределенном getType (Uri uri); затем Google+ не может их прикрепить. Большинство других работ, например. обмена сообщениями и электронной почты. "image/jpg" НЕ является допустимым типом MIME IANA:
http://www.iana.org/assignments/media-types/image
Спецификация getType ясно об этом, но ее очень легко пропустить (я сделал). Решив это, я хотел, чтобы другие заметили это, потому что это очень неудобно.
Ответ 5
Вы можете использовать это:
Drawable drawable;
File file;
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
drawable = getResources().getDrawable(imgResId);
} else {
drawable = getResources().getDrawable(imgResId, null);
}
if (drawable != null) {
Bitmap bm = ((BitmapDrawable) drawable).getBitmap();
String path = Environment.getExternalStorageDirectory()
.toString();
OutputStream fOut = null;
file = new File(path, "pic.jpg"); // the File to save to
try {
file.createNewFile();
fOut = new FileOutputStream(file);
// obtaining the Bitmap
bm.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
fOut.flush();
fOut.close();
return file;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}