una temporalmente suspendida solucion restringida recuperar por edad dura desbloquear cuenta cuanto como bloqueo bloqueada android android-intent android-sharing android-fileprovider

android - temporalmente - recuperar cuenta de twitter bloqueada por edad



La intención de compartir imágenes funciona para Gmail, pero bloquea FB y Twitter (2)

Twitter (erróneamente) asume que habrá una columna MediaStore.MediaColumns.DATA. Comenzando en KitKat, el MediaStore devuelve un valor nulo, así que afortunadamente, Twitter maneja los nulos con gracia y hace lo correcto.

public class FileProvider extends android.support.v4.content.FileProvider { @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { Cursor source = super.query(uri, projection, selection, selectionArgs, sortOrder); String[] columnNames = source.getColumnNames(); String[] newColumnNames = columnNamesWithData(columnNames); MatrixCursor cursor = new MatrixCursor(newColumnNames, source.getCount()); source.moveToPosition(-1); while (source.moveToNext()) { MatrixCursor.RowBuilder row = cursor.newRow(); for (int i = 0; i < columnNames.length; i++) { row.add(source.getString(i)); } } return cursor; } private String[] columnNamesWithData(String[] columnNames) { for (String columnName : columnNames) if (MediaStore.MediaColumns.DATA.equals(columnName)) return columnNames; String[] newColumnNames = Arrays.copyOf(columnNames, columnNames.length + 1); newColumnNames[columnNames.length] = MediaStore.MediaColumns.DATA; return newColumnNames; } }

Estoy tratando de permitir que el usuario comparta una imagen con otras aplicaciones en el dispositivo. La imagen está dentro del archivo / subdirectorio del área de almacenamiento interno de mi aplicación. Funciona bien con Gmail, pero Facebook y Twitter se bloquean al responder a mi intención.

EDITAR: Google+ también funciona bien.

Aquí están las secciones relevantes del código.

En Application.xml

<provider android:name="android.support.v4.content.FileProvider" android:authorities="org.iforce2d.myapp.MyActivity" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/filepaths" /> </provider>

xml / filepaths.xml

<paths xmlns:android="http://schemas.android.com/apk/res/android"> <files-path name="shared" path="shared"/> </paths>

Aquí está el código para compartir en mi actividad:

File imagePath = new File(getContext().getFilesDir(), "shared"); File newFile = new File(imagePath, "snapshot.jpg"); Uri contentUri = FileProvider.getUriForFile(getContext(), "org.iforce2d.myapp.MyActivity", newFile); Intent shareIntent = new Intent(); shareIntent.setAction(Intent.ACTION_SEND); shareIntent.setType("image/jpeg"); shareIntent.putExtra(Intent.EXTRA_STREAM, contentUri); shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); List<ResolveInfo> resInfos = getPackageManager().queryIntentActivities(shareIntent, PackageManager.MATCH_DEFAULT_ONLY); for (ResolveInfo info : resInfos) { getContext().grantUriPermission(info.activityInfo.packageName, contentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION); } startActivity(Intent.createChooser(shareIntent, "Share image..."));

El valor de contentUri cuando se registra es:

content://org.iforce2d.myapp.MyActivity/shared/snapshot.jpg

Solo he comprobado esto con Gmail, Facebook y Twitter como las aplicaciones de recepción, pero los resultados han sido muy consistentes en una amplia gama de versiones de SO (desde 2.2.1 a 4.4.3) y 7 dispositivos incluyen un Kindle.

Gmail funciona muy bien. La miniatura de la imagen aparece en la composición del correo y se adjunta correctamente al correo cuando se envía.

Twitter y Facebook se estrellan, como a continuación.

Aquí están los rastros de pila de logcat que muestran el problema que tienen estas dos aplicaciones, parece ser el mismo problema para ambas (esto se toma de 4.4.3, pero los errores fueron prácticamente los mismos hasta la versión 2.2. 1 aunque con una redacción ligeramente diferente del mensaje de error):

Caused by: java.lang.IllegalStateException: Couldn''t read row 0, col 0 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it. at android.database.CursorWindow.nativeGetString(Native Method) at android.database.CursorWindow.getString(CursorWindow.java:434) at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51) at android.database.CursorWrapper.getString(CursorWrapper.java:114) at com.twitter.library.media.util.f.a(Twttr:95) ... Caused by: java.lang.IllegalStateException: Couldn''t read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it. at android.database.CursorWindow.nativeGetString(Native Method) at android.database.CursorWindow.getString(CursorWindow.java:434) at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51) at android.database.CursorWrapper.getString(CursorWrapper.java:114) at com.facebook.photos.base.media.MediaItemFactory.b(MediaItemFactory.java:233) ...

Dado que compartir imágenes en Facebook y Twitter es algo que millones de personas hacen durante todo el día, estoy bastante sorprendido de que sea tan difícil de implementar: /

¿Alguien puede ver algo que estoy haciendo mal aquí?


EDITAR: la solución descrita en esta respuesta funciona, pero la solución provista por Stefan es más elegante. Debería ser la respuesta aceptada.

Además, a partir de enero de 2015, la aplicación de Facebook ya no tiene este error (y ahora funciona con el FileProvider estándar) pero Twitter aún lo tiene. Con suerte, desaparecerá completamente en el futuro, y ninguno de estos será necesario.

Si bien el objeto FileProvider parece maravilloso en teoría, no parece funcionar cuando se comparte con muchas aplicaciones de terceros (mientras que las de Google, como G +, Gmail, etc. funcionan perfectamente). O bien no expone suficiente información, o esas aplicaciones simplemente asumen que estás compartiendo archivos, y por lo tanto fallan.

¡Es realmente frustrante! : /

La única forma confiable que he encontrado para compartir archivos de imagen es copiarlos en el directorio de almacenamiento externo (puede crear un subdirectorio .nomedia para evitar que aparezcan en la aplicación Galería).

Por ejemplo:

Bitmap bitmapToShare = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher); File pictureStorage = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); File noMedia = new File(pictureStorage, ".nomedia"); if (!noMedia.exists()) noMedia.mkdirs(); File file = new File(noMedia, "shared_image.png"); saveBitmapAsFile(bitmapToShare, file); Intent shareIntent = new Intent(); shareIntent.setAction(Intent.ACTION_SEND); shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file)); shareIntent.setType("image/png"); startActivity(shareIntent);

Anexo: por supuesto, también debe verificar getExternalStorageState() antes de intentar escribir / copiar el archivo allí.