14

我正在调用共享图像的意图。这适用于大多数提供商,但适用于 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);

任何建议表示赞赏

西蒙

4

5 回答 5

6

Google+ 无法file://从其他应用程序的私人文件夹访问 Uris。并且FLAG_GRANT_READ_URI_PERMISSION在这种情况下不起作用,因为它仅适用于 Intent 的“数据”部分中的 Uris,而不适用于额外内容。

一种常见的解决方法是将其添加到图库(通过MediaStore),但没有必要这样做。在这种情况下,正确的解决方案是使用FileProvider

FileProvider 是 ContentProvider 的一个特殊子类,它通过为文件创建 content://Uri 而不是 Uri 来促进与应用程序关联的文件的安全共享file:///

首先将以下内容放入您的 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.pngGoogle+ 应用能够访问并因此包含在帖子中一样)。

于 2014-06-02T15:54:00.477 回答
2

西蒙,

似乎在设置uri之后设置权限是可行的。

share.putExtra(Intent.EXTRA_STREAM, uri);
share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
于 2012-04-01T16:42:31.113 回答
1

如果您使用的是自定义 ContentProvider,则必须检查图像的 MIME 类型是否正确。jpeg 的正确 MIME 是“image/jpeg”。如果在覆盖的 getType(Uri uri) 中返回“image/jpg”;方法然后 Google+ 无法附加它们。大多数其他工作,例如消息传递和电子邮件。“image/jpg”不是有效的 IANA MIME 类型:

http://www.iana.org/assignments/media-types/image

getType 的规范对此很清楚,但很容易错过(我做过)。解决了这个问题后,我想确保其他人发现这个问题,因为它非常不明显。

于 2013-11-25T04:05:43.493 回答
1

试试这个,如果我做一个插入,我也有这个问题,因为它会出现在画廊中。

//这里是一个文件实例

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

于 2012-08-20T06:51:09.197 回答
0

你可以使用这个:

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();
    }
} 
于 2015-10-14T23:43:35.767 回答