Compartir una imagen con un proveedor de contenido en la aplicación de Android

Estoy desarrollando una aplicación de Android que es una galería de imágenes en la que las imágenes se descargan desde Internet para mostrar en la pantalla de smathphone. Las imágenes se muestran una a la vez y la aplicación tiene un botón para compartir la imagen que se muestra.

Siguiendo las instrucciones que he encontrado en algún post de StackOverflow que indica que la manera correcta de compartir una imagen era usar ContentProvider, he implementado el siguiente código que funciona para compartir las imágenes de ciertas aplicaciones (por ejemplo, Twitter, Gmail …) pero No funciona para otros (Facebook, Yahoo, MMS …).

Luego muestro el código usado esperando que me ayudes a obtener la implementación correcta para compartir imágenes en todas las aplicaciones.

Inicialmente captura la pulsación de botón para compartir:

@Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == R.id.menu_share) { // I get the image being displayed on the screen View root = getView(); ImageView imageView = (ImageView) root.findViewById(R.id.image); Drawable imageToShareDrawable = imageView.getDrawable(); if (imageToShareDrawable instanceof BitmapDrawable) { // I convert the image to Bitmap Bitmap imageToShare = ((BitmapDrawable) imageToShareDrawable).getBitmap(); // Name of de image extracted from a bean property String fileName = quote.getImage(); // I keep the image in the folder "files" of internal storage application TempInternalStorage.createCachedFile(fileName, imageToShare, getActivity().getApplicationContext()); // I start the Activity to select the application to share the image after the intent Built with the method "getDefaultShareIntent" startActivity(getDefaultShareIntent(fileName)); } else { Toast.makeText(getActivity().getApplicationContext(), "Please wait, the quote is being downloaded", Toast.LENGTH_SHORT).show(); } } return true; } 

El método para guardar la imagen en el almacenamiento interno de la aplicación es el siguiente:

 public static void createCachedFile(String fileName, Bitmap image, Context context) { try { File file = new File(context.getFilesDir(), fileName); if (!file.exists()) { FileOutputStream fos = new FileOutputStream(file); image.compress(Bitmap.CompressFormat.JPEG, 100, fos); fos.flush(); fos.close(); } } catch (Exception e) { Log.e("saveTempFile()", "**** Error"); } } 

El método que construye el intento de compartirlo:

 private Intent getDefaultShareIntent(String fileName) { final Intent shareIntent = new Intent(); shareIntent.setAction(Intent.ACTION_SEND); shareIntent.setType("image/jpeg"); shareIntent.putExtra(Intent.EXTRA_TEXT, "Test text"); shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://" + CachedFileProvider.AUTHORITY + File.separator + "img" + File.separator + fileName)); shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); return shareIntent; } 

Finalmente, el código de ContentProvider es el siguiente:

 public class CachedFileProvider extends ContentProvider { private static final String CLASS_NAME = "CachedFileProvider"; public static final String AUTHORITY = "com.example.appname.cachefileprovider"; private UriMatcher uriMatcher; @Override public boolean onCreate() { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(AUTHORITY, "img/*", 1); return true; } @Override public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { String LOG_TAG = CLASS_NAME + " - openFile"; Log.i(LOG_TAG, "Called with uri: '" + uri + "'." + uri.getLastPathSegment()); switch (uriMatcher.match(uri)) { case 1: String fileLocation = getContext().getFilesDir() + File.separator + uri.getLastPathSegment(); ParcelFileDescriptor image = ParcelFileDescriptor.open(new File(fileLocation), ParcelFileDescriptor.MODE_READ_ONLY); return image; default: Log.i(LOG_TAG, "Unsupported uri: '" + uri + "'."); throw new FileNotFoundException("Unsupported uri: " + uri.toString()); } } @Override public int update(Uri uri, ContentValues contentvalues, String s, String[] as) { return 0; } @Override public int delete(Uri uri, String s, String[] as) { return 0; } @Override public Uri insert(Uri uri, ContentValues contentvalues) { return null; } @Override public String getType(Uri uri) { return null; } @Override public Cursor query(Uri uri, String[] projection, String s, String[] as1, String s1) { MatrixCursor c = null; Log.i(">>>> projection", java.util.Arrays.toString(projection)); String fileLocation = getContext().getFilesDir() + File.separator + uri.getLastPathSegment(); File file = new File(fileLocation); long time = System.currentTimeMillis(); c = new MatrixCursor(new String[] { "_id", "_data", "orientation", "mime_type", "datetaken", "_display_name" }); c.addRow(new Object[] { 0, file, 0, "image/jpeg", time, uri.getLastPathSegment() }); return c; } @Override public String[] getStreamTypes(Uri uri, String mimeTypeFilter) { return null; } 

}

He encontrado que cuando la imagen está compartiendo algunas aplicaciones sólo llaman al método "consulta" (estos son donde el código no funciona y no puedo compartir la imagen), mientras que hay otros que también llaman el método "consulta" también llamar a la Método "openFile" y estos funcionan y puedo compartir la imagen.

Espero que me puedan ayudar, muchas gracias de antemano.

Como comentario @Sun Ning-s observó algunas "aplicaciones de destino compartido" puede manejar URI-s empezando con "content: // .." que ha implementado.

Otras aplicaciones manejan el archivo uri-s empezando por "file: // …." por lo que tienes que implementar un 2º menue share "share as file"

 private Intent getFileShareIntent(String fullPathTofile) { final Intent shareIntent = new Intent(); shareIntent.setAction(Intent.ACTION_SEND); shareIntent.setType("image/jpeg"); shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + fullPathTofile)); shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); return shareIntent; } 

Puedes usar la aplicación android para saber qué otras "aplicaciones de fuente compartida" proporcionan.

  • Preguntas sobre desarrollo y lanzamiento de hachas clave para Facebook SDK para Android
  • Cómo personalizar el evento de OnClick de Intención de participación en Android
  • Android facebook sdk publicar la alimentación a la línea de tiempo del usuario
  • Spring boot REST api seguridad para la aplicación de Android con Google + Facebook login
  • ¿Cómo publicar la actualización en la página de Facebook automáticamente por hora programada? Usando android
  • SDK de Android de Facebook y java.lang.NullPointerException
  • Aplicación mal configurada Lo sentimos, myapp no ​​ha sido aprobado para su visualización en App Center. En la parte de la aplicación Android
  • Facebook onCompleted Email java.lang.NullPointerException
  • Cómo utilizar el parámetro de paquete de paso para la paginación en el desarrollo de facebook android
  • Añadido facebook SDK ahora no puede reanudar la fuerza de actividad cerrar
  • Estudio de Android: INSTALL_FAILED_CONFLICTING_PROVIDER facebook sdk
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.