Estoy desarrollando una aplicación para Android y estoy interesado en saber cómo se puede actualizar el estado del usuario de la aplicación desde dentro de la aplicación utilizando las intenciones de compartir de Android.
Después de haber revisado el SDK de Facebook, parece que esto es bastante fácil de hacer, sin embargo, estoy dispuesto a permitir que el usuario lo haga a través de la ventana emergente Share Intent normal. visto aquí:
Probé el código de intención de compartir habitual, sin embargo, parece que ya no funciona para Facebook.
public void invokeShare(Activity activity, String quote, String credit) {
Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, activity.getString(R.string.share_subject));
shareIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Example text");
activity.startActivity(Intent.createChooser(shareIntent, activity.getString(R.string.share_title)));
}
ACTUALIZACIÓN: Después de investigar más, ¡parece que es un error con la aplicación de Facebook que aún no se ha resuelto! ( error de Facebook ) Por el momento, parece que voy a tener que aguantar el negativo "¡¡¡Compartir no funciona !!!" revisiones. Saludos Facebook: * (
fuente
Respuestas:
Aquí hay un enlace de error: https://developers.facebook.com/bugs/332619626816423
Gracias @billynomates:
fuente
Aparentemente, Facebook ya no le permite personalizar la pantalla para compartir, sin importar si solo está abriendo la URL sharer.php o usando intents de Android de formas más especializadas. Vea, por ejemplo, estas respuestas:
De todos modos, el uso de Intentos de fricción, que puede todavía compartir una URL, pero no el texto predeterminado con él , como billynomates comentó . (Además, si no tiene una URL para compartir, simplemente iniciar la aplicación de Facebook con el cuadro de diálogo "Escribir publicación" (es decir, actualización de estado) vacío es igualmente fácil; use el código a continuación pero déjelo fuera
EXTRA_TEXT
).Esta es la mejor solución que he encontrado que no implica el uso de ningún SDK de Facebook.
Este código abre la aplicación oficial de Facebook directamente si está instalada y, de lo contrario, vuelve a abrir sharer.php en un navegador. (La mayoría de las otras soluciones en esta pregunta muestran un enorme cuadro de diálogo "Completar acción usando ..." ¡ que no es óptimo en absoluto!)
String urlToShare = "/programming/7545254"; Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); // intent.putExtra(Intent.EXTRA_SUBJECT, "Foo bar"); // NB: has no effect! intent.putExtra(Intent.EXTRA_TEXT, urlToShare); // See if official Facebook app is found boolean facebookAppFound = false; List<ResolveInfo> matches = getPackageManager().queryIntentActivities(intent, 0); for (ResolveInfo info : matches) { if (info.activityInfo.packageName.toLowerCase().startsWith("com.facebook.katana")) { intent.setPackage(info.activityInfo.packageName); facebookAppFound = true; break; } } // As fallback, launch sharer.php in a browser if (!facebookAppFound) { String sharerUrl = "https://www.facebook.com/sharer/sharer.php?u=" + urlToShare; intent = new Intent(Intent.ACTION_VIEW, Uri.parse(sharerUrl)); } startActivity(intent);
(Con respecto al
com.facebook.katana
nombre del paquete, consulte el comentario de MatheusJardimB ).El resultado se ve así en mi Nexus 7 (Android 4.4) con la aplicación de Facebook instalada:
fuente
com.facebook
prefijo.La forma habitual
La forma habitual de crear lo que está pidiendo es simplemente hacer lo siguiente:
Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_TEXT, "The status update text"); startActivity(Intent.createChooser(intent, "Dialog title text"));
Esto funciona sin problemas para mí.
La forma alternativa (tal vez)
El problema potencial de hacer esto es que también está permitiendo que el mensaje se envíe por correo electrónico, SMS, etc. El siguiente código es algo que estoy usando en una aplicación, que permite al usuario enviarme un correo electrónico. -mail usando Gmail. Supongo que podrías intentar cambiarlo para que funcione solo con Facebook.
No estoy seguro de cómo responde a los errores o excepciones (supongo que eso ocurriría si Facebook no está instalado), por lo que es posible que deba probarlo un poco.
try { Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND); String[] recipients = new String[]{"e-mail address"}; emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, recipients); emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "E-mail subject"); emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "E-mail text"); emailIntent.setType("plain/text"); // This is incorrect MIME, but Gmail is one of the only apps that responds to it - this might need to be replaced with text/plain for Facebook final PackageManager pm = getPackageManager(); final List<ResolveInfo> matches = pm.queryIntentActivities(emailIntent, 0); ResolveInfo best = null; for (final ResolveInfo info : matches) if (info.activityInfo.packageName.endsWith(".gm") || info.activityInfo.name.toLowerCase().contains("gmail")) best = info; if (best != null) emailIntent.setClassName(best.activityInfo.packageName, best.activityInfo.name); startActivity(emailIntent); } catch (Exception e) { Toast.makeText(this, "Application not found", Toast.LENGTH_SHORT).show(); }
fuente
En Lollipop (21), puede usar
Intent.EXTRA_REPLACEMENT_EXTRAS
para anular la intención para Facebook específicamente (y especificar solo un enlace)https://developer.android.com/reference/android/content/Intent.html#EXTRA_REPLACEMENT_EXTRAS
private void doShareLink(String text, String link) { Intent shareIntent = new Intent(Intent.ACTION_SEND); shareIntent.setType("text/plain"); Intent chooserIntent = Intent.createChooser(shareIntent, getString(R.string.share_via)); // for 21+, we can use EXTRA_REPLACEMENT_EXTRAS to support the specific case of Facebook // (only supports a link) // >=21: facebook=link, other=text+link // <=20: all=link if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { shareIntent.putExtra(Intent.EXTRA_TEXT, text + " " + link); Bundle facebookBundle = new Bundle(); facebookBundle.putString(Intent.EXTRA_TEXT, link); Bundle replacement = new Bundle(); replacement.putBundle("com.facebook.katana", facebookBundle); chooserIntent.putExtra(Intent.EXTRA_REPLACEMENT_EXTRAS, replacement); } else { shareIntent.putExtra(Intent.EXTRA_TEXT, link); } chooserIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(chooserIntent); }
fuente
Descubrí que solo puedes compartir texto o imagen , no ambos usando
Intents
. El siguiente código comparte solo la imagen si existe, o solo el texto si la imagen no sale. Si desea compartir ambos, debe usar el SDK de Facebook desde aquí.Si usa otra solución en lugar del código siguiente, no olvide especificar también el nombre del paquete com.facebook.lite , que es el nombre del paquete de Facebook Lite . No lo he probado, pero com.facebook.orca es el nombre del paquete de Facebook Messenger si quieres apuntar a eso también.
Puedes agregar más métodos para compartir con WhatsApp , Twitter ...
public class IntentShareHelper { /** * <b>Beware,</b> this shares only image if exists, or only text if image does not exits. Can't share both */ public static void shareOnFacebook(AppCompatActivity appCompatActivity, String textBody, Uri fileUri) { Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_TEXT,!TextUtils.isEmpty(textBody) ? textBody : ""); if (fileUri != null) { intent.putExtra(Intent.EXTRA_STREAM, fileUri); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.setType("image/*"); } boolean facebookAppFound = false; List<ResolveInfo> matches = appCompatActivity.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); for (ResolveInfo info : matches) { if (info.activityInfo.packageName.toLowerCase().startsWith("com.facebook.katana") || info.activityInfo.packageName.toLowerCase().startsWith("com.facebook.lite")) { intent.setPackage(info.activityInfo.packageName); facebookAppFound = true; break; } } if (facebookAppFound) { appCompatActivity.startActivity(intent); } else { showWarningDialog(appCompatActivity, appCompatActivity.getString(R.string.error_activity_not_found)); } } public static void shareOnWhatsapp(AppCompatActivity appCompatActivity, String textBody, Uri fileUri){...} private static void showWarningDialog(Context context, String message) { new AlertDialog.Builder(context) .setMessage(message) .setNegativeButton(context.getString(R.string.close), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }) .setCancelable(true) .create().show(); } }
Para obtener Uri del archivo, use la siguiente clase:
public class UtilityFile { public static @Nullable Uri getUriFromFile(Context context, @Nullable File file) { if (file == null) return null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { try { return FileProvider.getUriForFile(context, "com.my.package.fileprovider", file); } catch (Exception e) { e.printStackTrace(); return null; } } else { return Uri.fromFile(file); } } // Returns the URI path to the Bitmap displayed in specified ImageView public static Uri getLocalBitmapUri(Context context, ImageView imageView) { Drawable drawable = imageView.getDrawable(); Bitmap bmp = null; if (drawable instanceof BitmapDrawable) { bmp = ((BitmapDrawable) imageView.getDrawable()).getBitmap(); } else { return null; } // Store image to default external storage directory Uri bmpUri = null; try { // Use methods on Context to access package-specific directories on external storage. // This way, you don't need to request external read/write permission. File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "share_image_" + System.currentTimeMillis() + ".png"); FileOutputStream out = new FileOutputStream(file); bmp.compress(Bitmap.CompressFormat.PNG, 90, out); out.close(); bmpUri = getUriFromFile(context, file); } catch (IOException e) { e.printStackTrace(); } return bmpUri; } }
Para escribir FileProvider , use este enlace: https://github.com/codepath/android_guides/wiki/Sharing-Content-with-Intents
fuente
Esto es lo que hice (para texto). En el código, copio el texto que sea necesario al portapapeles. La primera vez que una persona intenta usar el botón de intención de compartir, aparece una notificación que explica si desean compartir en Facebook, deben hacer clic en 'Facebook' y luego presionar prolongadamente para pegar (esto es para que sepan que Facebook ha ROTO el sistema de intención de Android). Entonces la información relevante está en el campo. También podría incluir un enlace a esta publicación para que los usuarios también puedan quejarse ...
private void setClipboardText(String text) { // TODO int sdk = android.os.Build.VERSION.SDK_INT; if(sdk < android.os.Build.VERSION_CODES.HONEYCOMB) { android.text.ClipboardManager clipboard = (android.text.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); clipboard.setText(text); } else { android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); android.content.ClipData clip = android.content.ClipData.newPlainText("text label",text); clipboard.setPrimaryClip(clip); } }
A continuación se muestra un método para tratar con versiones anteriores
public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.menu_item_share: Intent shareIntent = new Intent(Intent.ACTION_SEND); shareIntent.setType("text/plain"); shareIntent.putExtra(Intent.EXTRA_TEXT, "text here"); ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); //TODO ClipData clip = ClipData.newPlainText("label", "text here"); clipboard.setPrimaryClip(clip); setShareIntent(shareIntent); break; } return super.onOptionsItemSelected(item); }
fuente
Parece que en la versión 4.0.0 de Facebook muchas cosas han cambiado. Este es mi código que funciona bien. Espero que te ayude.
/** * Facebook does not support sharing content without using their SDK however * it is possible to share URL * * @param content * @param url */ private void shareOnFacebook(String content, String url) { try { // TODO: This part does not work properly based on my test Intent fbIntent = new Intent(Intent.ACTION_SEND); fbIntent.setType("text/plain"); fbIntent.putExtra(Intent.EXTRA_TEXT, content); fbIntent.putExtra(Intent.EXTRA_STREAM, url); fbIntent.addCategory(Intent.CATEGORY_LAUNCHER); fbIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); fbIntent.setComponent(new ComponentName("com.facebook.katana", "com.facebook.composer.shareintent.ImplicitShareIntentHandler")); startActivity(fbIntent); return; } catch (Exception e) { // User doesn't have Facebook app installed. Try sharing through browser. } // If we failed (not native FB app installed), try share through SEND String sharerUrl = "https://www.facebook.com/sharer/sharer.php?u=" + url; SupportUtils.doShowUri(this.getActivity(), sharerUrl); }
fuente
Esta solución también funciona. Si no hay Facebook instalado, simplemente ejecuta el diálogo de compartir normal. Si lo hay y no ha iniciado sesión, va a la pantalla de inicio de sesión. Si ha iniciado sesión, se abrirá el cuadro de diálogo para compartir y colocará la "URL para compartir" de Intent Extra.
Intent intent = new Intent(Intent.ACTION_SEND); intent.putExtra(Intent.EXTRA_TEXT, "Share url"); intent.setType("text/plain"); List<ResolveInfo> matches = getMainFragmentActivity().getPackageManager().queryIntentActivities(intent, 0); for (ResolveInfo info : matches) { if (info.activityInfo.packageName.toLowerCase().contains("facebook")) { intent.setPackage(info.activityInfo.packageName); } } startActivity(intent);
fuente
Aquí hay algo que hice que abrió la aplicación de Facebook con un enlace
shareIntent = new Intent(Intent.ACTION_SEND); shareIntent.setComponent(new ComponentName("com.facebook.katana", "com.facebook.katana.activity.composer.ImplicitShareIntentHandler")); shareIntent.setType("text/plain"); shareIntent.putExtra(Intent.EXTRA_TEXT, videoUrl);
fuente
public void invokeShare(Activity activity, String quote, String credit) { Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND); shareIntent.setType("text/plain"); shareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, activity.getString(R.string.share_subject)); shareIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Example text"); shareIntent.putExtra("com.facebook.platform.extra.APPLICATION_ID", activity.getString(R.string.app_id)); activity.startActivity(Intent.createChooser(shareIntent, activity.getString(R.string.share_title))); }
fuente
Facebook no permite compartir datos de texto sin formato con,
Intent.EXTRA_TEXT
pero puede compartir texto + enlace con el mensajero de Facebook usando esto, esto funciona bien para míIntent sendIntent = new Intent(); sendIntent.setAction(Intent.ACTION_SEND); sendIntent.putExtra(Intent.EXTRA_TEXT, text+url link); sendIntent.setType("text/plain"); sendIntent.setPackage("com.facebook.orca"); startActivity(sendIntent);
fuente
La forma más fácil que pude encontrar para pasar un mensaje de mi aplicación a Facebook fue copiar mediante programación al portapapeles y alertar al usuario que tiene la opción de pegar. Evita que el usuario lo haga manualmente; mi aplicación no se pega, pero el usuario podría hacerlo.
... if (app.equals("facebook")) { // overcome fb 'putExtra' constraint; // copy message to clipboard for user to paste into fb. ClipboardManager cb = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); ClipData clip = ClipData.newPlainText("post", msg); cb.setPrimaryClip(clip); // tell the to PASTE POST with option to stop showing this dialogue showDialog(this, getString(R.string.facebook_post)); } startActivity(appIntent); ...
fuente