【问题标题】:Share intent issue in Instagram feed在 Instagram 提要中分享意图问题
【发布时间】:2020-03-21 11:00:11
【问题描述】:

我有一个从 url 共享图像的应用程序。上次安卓更新,当我想在 Instagram 订阅中分享图片时,我收到了来自 Instagram 的消息“无法加载图片”。

但我可以在任何地方分享图片故事、直接消息和...我只遇到这个问题。

public void onShareItemOreo() {
    // Get access to bitmap image from view
    imageView = (ImageView) findViewById(R.id.thumbnail);

    // Get access to the URI for the bitmap
    Uri bmpUri = prepareShareIntent(imageView);
    if (bmpUri != null) {

        //outfile is the path of the image stored in the gallery
        // Construct a ShareIntent with link to image
        Intent shareIntent = new Intent();
        shareIntent.setAction(Intent.ACTION_SEND);
        shareIntent.putExtra(Intent.EXTRA_STREAM, bmpUri);
        shareIntent.setData(bmpUri);
        shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        shareIntent.setType("image/*");
        shareIntent.putExtra(Intent.EXTRA_TEXT,marketLink);
        // Launch sharing dialog for image
        startActivity(Intent.createChooser(shareIntent, "Share Image"));
    } else {
        //
    }
}


public Uri prepareShareIntent(ImageView imageView) {

    // Fetch Bitmap Uri locally
    Drawable drawable = imageView.getDrawable();
    Bitmap bmp = null;
    if (drawable instanceof BitmapDrawable){
        bmp = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
    } else {
        return null;
    }

    Uri bmpUri = getBitmapFromDrawable(bmp);// see previous remote images section and notes for API > 23
    // Construct share intent as described above based on bitmap
    Intent shareIntent = new Intent();
    shareIntent.setAction(Intent.ACTION_SEND);
    shareIntent.putExtra(Intent.EXTRA_STREAM, bmpUri);
    shareIntent.setType("image/*");

    return bmpUri;
}

【问题讨论】:

  • 试试这个:share.setType("image/jpeg");
  • @AliHas i have ("image/*)
  • 遇到同样的问题,有什么消息吗?

标签: android image android-intent share


【解决方案1】:

更新: 此问题已在本周早些时候发布的 Instagram 版本中得到修复。不再需要变通方法。


上面提到的解决方案都不适合我,因为 Instagram 应用程序中的更改似乎破坏了通过 ContentProvider 或其派生词 FileProvider 的直接分享。

我确实注意到,共享 MediaStore 内容 Uri 仍然有效,因为在共享之前写入 MediaStore 的其他应用(例如 Google 照片)仍然能够共享图像以供馈送。

您可以将图像File 插入到MediaStore,如下所示:

@SuppressLint("InlinedApi")
fun insertImageToMediaStore(file: File, relativePath: String): Uri? {

    val values = ContentValues().apply {
        put(MediaStore.Images.Media.DISPLAY_NAME, file.name)

        val mimeType = when (file.extension) {
            "jpg", "jpeg" -> "jpeg"
            "png" -> "png"
            else -> return null
        }

        put(MediaStore.Images.Media.MIME_TYPE, "image/$mimeType")

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            put(MediaStore.MediaColumns.RELATIVE_PATH, relativePath)
            put(MediaStore.MediaColumns.IS_PENDING, 1)
        }
    }

    val collection = when (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        true -> MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL)
        false -> MediaStore.Images.Media.EXTERNAL_CONTENT_URI
    }

    val uri = contentResolver.insert(collection, values)

    uri?.let {
        contentResolver.openOutputStream(uri)?.use { outputStream ->
            try {
                outputStream.write(file.readBytes())
                outputStream.close()
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }


        values.clear()

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            values.put(MediaStore.Images.Media.IS_PENDING, 0)
            contentResolver.update(uri, values, null, null)
        }

    } ?: throw RuntimeException("MediaStore failed for some reason")

    return uri
}

然后使用返回的Uri,通过 Intent 分享如下:

    val filePath = "/data/data/io.jammy.withintent/files/IMG-20200321_093350_2020-122758.jpg" // this is an example path from an app-internal image file

    val context: Context? = this
    val intent = Intent(Intent.ACTION_SEND)
    intent.type = "image/*"

    insertImageToMediaStore(File(filePath), "Pictures/Your Subdirectory")?.let { uri ->

        val clipData = ClipData.newRawUri("Image", uri)

        intent.clipData = clipData
        intent.putExtra(Intent.EXTRA_STREAM, uri)

        val target = Intent.createChooser(intent, "Share Image")
        target?.let { context?.startActivity(it) }

    } ?: run {
        Log.e(TAG, "Unsupported image file")
        return
    }

虽然并不理想,因为图像随后被写入 MediaStore,这在许多情况下可能不是理想的行为,但它重新启用了在中期分享的能力,同时 Instagram 修复了他们的问题。

【讨论】:

  • 谢谢@MattMatt,我会尝试用Java做同样的事情,你知道是否可能吗?我不是 android/java 开发者há
  • 不客气@mauriblint。在 Java 中绝对可以做到这一点,事实上 Kotlin 编译器无论如何都会在构建时创建 Java 字节码!这个要点可能对你有帮助:gist.github.com/benny-shotvibe/1e0d745b7bc68a9c3256
  • 非常感谢@MattMatt!我可以按照您的 Kotlin 代码用 Java 编写解决方案,非常感谢,我已经处理这个问题将近 7 天了
  • 嘿@MattMatt 视频共享怎么样?我们是否需要更改任何关键值?
  • 嘿@Choletski,您可以将MediaStore.Images.Media.* 调用更改为MediaStore.Video.Media.*,并确保您将MIME 类型字符串设置为与您发送的文件匹配的视频类型.这是一个 Gist,展示了如何使用上述方法处理图像或视频文件:gist.github.com/noln/584afabed1362fabbc2516275a5f755b
【解决方案2】:

Facebook 正在处理这个错误,让我们拭目以待! 订阅以接收此错误报告的更新通知。 https://developers.facebook.com/support/bugs/1326888287510350/

【讨论】:

  • 谢谢,我已经订阅了。但是我们怎么知道他们正在研究它。
【解决方案3】:

您的 uri 是“content://packagename/xxx.jpg”,它需要是“content://media/external/images/media/...”;它会起作用的。

【讨论】:

    【解决方案4】:
    【解决方案5】:

    好的,我搜索并找到了解决方案。我不知道这是正确的方法,但解决了我的问题..

    StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
    StrictMode.setVmPolicy(builder.build());
    

    Found solution in this answer.

    【讨论】:

    • 即使使用这个我也遇到同样的错误,请确认是否仍然为您工作
    • @Choletski ,这不适用于发布模式。仅用于调试模式。
    • @jancooth 即使在调试模式下也对我不起作用。有没有找到释放模式的解决方案?
    • @GurgenGevondov 我仍在寻找 t。如果您找到任何解决方案,请更新我。
    • @jancooth 这似乎是 Instagram 的问题,因为使用旧版本的 Instagram apk 一切正常
    【解决方案6】:

    看起来 Facebook 已经有这个问题的错误:https://developers.facebook.com/support/bugs/1326888287510350/

    作为临时解决方法,您可以将媒体保存到 MediaStore。这是我们用来存储然后返回用于 Instagram 分享的 uri 的方法。

        private fun insertImageToMediaStore(file: File): Uri? {
    
        val fileUri = FileProvider.getUriForFile(
            context,
            "${context.applicationContext.packageName}.provider",
            file
        )
        val mimeType = context.contentResolver.getType(fileUri) ?: "image/*"
        val isImage = mimeType.contains("image")
        val values = ContentValues().apply {
    
            put(
                if (isImage) {
                    MediaStore.Images.Media.DISPLAY_NAME
                } else {
                    MediaStore.Video.Media.DISPLAY_NAME
                },
                file.name
            )
    
            put(
                if (isImage) {
                    MediaStore.Images.Media.MIME_TYPE
                } else {
                    MediaStore.Video.Media.MIME_TYPE
                },
                mimeType
            )
        }
    
        val collection = if (isImage) {
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI
        } else {
            MediaStore.Video.Media.EXTERNAL_CONTENT_URI
        }
    
        val uri = context.contentResolver.insert(collection, values)
    
        uri?.let {
            context.contentResolver.openOutputStream(uri)?.use { outputStream ->
                try {
                    outputStream.write(file.readBytes())
                    outputStream.close()
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
    
    
            values.clear()
    
        } ?: throw RuntimeException("MediaStore failed for some reason")
    
        return uri
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多