Problema de intención de compartir en el feed de Instagram

8

Tengo una aplicación que comparte imágenes de la URL. Última actualización de Android, recibí el mensaje de instagram "No se puede cargar la imagen" cuando quiero compartir una imagen en el feed de instagram.

Pero puedo compartir la historia de la imagen, el mensaje directo y en todas partes ... Tengo este problema solo con el feed de 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;
}
jancooth
fuente
intente esto: share.setType ("image / jpeg");
Ali tiene
@AliHas i have ("image / *)
enero
¿Tiene el mismo problema, alguna noticia?
Mauriblint

Respuestas:

3

Actualización: este problema se solucionó en la versión de Instagram lanzada a principios de esta semana. Las soluciones alternativas ya no son necesarias.


Ninguna de las soluciones mencionadas anteriormente funcionó para mí, ya que parece que el intercambio directo a través de ContentProvidersu derivado se FileProvidervio interrumpido por un cambio realizado en la aplicación de Instagram.

Me di cuenta de que compartir un MediaStorecontenido Uri todavía funciona, ya que otras aplicaciones como Google Photos que escriben en MediaStore antes de compartir aún podían compartir imágenes para alimentar.

Puede insertar una imagen Fileen el MediaStoresiguiente:

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

Luego, con eso Urique has devuelto, comparte a través de Intención de la siguiente manera:

    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
    }

Si bien no es ideal, ya que la imagen se escribe en el MediaStorecomportamiento, lo que puede no ser el comportamiento deseado en muchos casos, vuelve a habilitar la capacidad de compartir en el mediano plazo mientras Instagram repara su whoopsie.

MattMatt
fuente
1
Esperaré la actualización de Instagram.
Jancooth
1
Gracias @MattMatt, intentaré hacer lo mismo con Java, ¿sabes si es posible? No soy desarrollador de Android / Java há
mauriblint
1
De nada @mauriblint. Definitivamente es posible hacer esto en Java, de hecho, el compilador de Kotlin crea código de bytes de Java en el momento de la construcción. Este Gist puede ser útil para usted: gist.github.com/benny-shotvibe/1e0d745b7bc68a9c3256
MattMatt
1
Muchas gracias, @MattMatt! Podría escribir la solución en Java siguiendo su código Kotlin, realmente apreciado, he estado lidiando con este problema durante casi 7 días
mauriblint
1
Hola @MattMatt, ¿qué hay de compartir videos? ¿Hay algún valor clave que necesitemos cambiar?
Choletski
1

su uri es "content: //packagename/xxx.jpg", debe ser "content: // media / external / images / media / ..."; Será trabajado.

perdido000117
fuente
0

Ok, busqué y encontré una solución. No sé si esto es correcto, pero resolvió mi problema.

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

Solución encontrada en esta respuesta.

jancooth
fuente
Obtuve el
@Choletski, esto no es para el modo de lanzamiento. Solo para el modo de depuración.
Jancooth
@jancooth No funciona para mí, incluso en modo de depuración. ¿Encontraste alguna solución para el modo de lanzamiento?
Gurgen Gevondov
@GurgenGevondov Sigo buscando t. Si encontró alguna solución, actualíceme.
Jancooth
1
@jancooth Parece ser un problema de Instagram, porque con versiones anteriores de Instagram apk todo funciona bien
Gurgen Gevondov
0

Parece que Facebook ya tiene el error para este problema: https://developers.facebook.com/support/bugs/1326888287510350/

Como solución temporal, puede guardar medios en MediaStore. Este es el método que utilizamos para almacenar y luego devolver la uri para compartir Instagram.

    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
}
Papi
fuente