Android和Facebook分享意图

我正在开发一个Android应用程序,并有兴趣知道如何使用Android的共享意图从应用程序内更新应用程序用户的状态。

看过Facebook的SDK看起来这很容易做,但是我很想让用户通过常规的Share Intent弹出窗口来做到这一点? 看到这里:

弹出

我已经尝试了通常的共享意图代码,但是这不再适用于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))); } 

更新:做了更多的挖掘,它看起来像Facebook的应用程序,还没有得到解决的错误! ( Facebook的错误 )对于平均的时间,看起来我只是要忍受负面的“共享不起作用!!!” 评论。 干杯Facebook:*(

Facebook应用程序不处理EXTRA_SUBJECTEXTRA_TEXT字段。

这里是错误链接: https : //developers.facebook.com/bugs/332619626816423

谢谢@billynomates:

事情是,如果你把一个URL在EXTRA_TEXT字段,它确实工作。 这就像他们故意剥离任何文字。

显然Facebook不再(截至2014年)允许您自定义共享屏幕,无论您是打开sharer.php URL还是使用Android意图更专业的方式。 例如看这些答案:

  • “Sharer.php不再允许你自定义。”
  • “您需要使用Facebook Android SDK或Easy Facebook Android SDK进行分享。”

无论如何,使用简单的意图, 你仍然可以共享一个URL,但没有任何默认的文字 ,因为billynomates评论 。 (另外,如果你没有URL可以分享,只需要用空的“Write Post”(即状态更新)对话框启动Facebook应用程序同样简单;使用下面的代码,但是省略EXTRA_TEXT 。)

这是我发现的最好的解决方案,不涉及使用任何Facebook的SDK。

这个代码直接打开官方的Facebook应用程序,如果它被安装,否则回到在浏览器中打开sharer.php。 (这个问题中的大多数其他解决方案都会带来一个非常不理想的“完整操作使用…”对话框 !)

 String urlToShare = "https://stackoverflow.com/questions/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); 

(关于com.facebook.katana包的名字,请看MatheusJardimB的评论 。)

在安装了Facebook应用程序的Nexus 7(Android 4.4)上,结果如下所示:

在这里输入图像描述

通常的方法

通常的方式来创建你所要求的是简单地做到以下几点:

  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")); 

这对我来说没有任何问题。

另一种方式(也许)

这样做的潜在问题在于,您还允许通过电子邮件,短信等方式发送邮件。以下代码是我在应用程序中使用的一些内容,它允许用户向我发送电子邮件邮件使用Gmail。 我猜你可以尝试改变它,使其只与Facebook工作。

我不知道它是如何响应任何错误或异常(我猜如果没有安装Facebook,会发生这种情况),所以你可能需要测试一下。

  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(); } 

这是我做的(用于文本)。 在代码中,我将任何需要的文本复制到剪贴板。 个人第一次尝试使用共享意图按钮,我弹出一个通知,说明他们是否希望分享到Facebook,他们需要点击“Facebook”,然后长按粘贴(这是为了让他们知道Facebook已经破解了Android意图系统)。 那么相关信息就在这个领域。 我也可能包括一个链接到这个职位,所以用户也可以抱怨…

 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); } } 

以下是处理w / prior版本的方法

 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); } 

在棒棒糖(21)中,您可以使用Intent.EXTRA_REPLACEMENT_EXTRAS覆盖Facebook的意图(并指定一个链接)

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); } 

这个解决方案也适用。 如果没有安装Facebook,则只运行正常的共享对话框。 如果有,并且您没有登录,则会进入登录屏幕。 如果您已经登录,它将打开共享对话框,并从Intent Extra中输入“Share url”。

 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); 

我发现你只能分享文字 图像 ,不能同时使用Intents 。 下面的代码共享只有图像存在,或者只有图像不存在时的文本 。 如果你想分享这两个,你需要从这里使用Facebook SDK。

如果您使用其他解决方案而不是下面的代码,请不要忘记指定包名称com.facebook.lite ,也就是Facebook Lite的包名称。 我没有测试,但com.facebook.orcaFacebook Messenger的包名称,如果你想要的目标也是如此。

你可以添加更多的方法与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(); } } 

为了从文件中获取Uri ,请使用下面的类:

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

要编写FileProvider ,请使用以下链接: https : //github.com/codepath/android_guides/wiki/Sharing-Content-with-Intents

这是我用链接打开Facebook的应用程序

 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); 
  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))); } 

Facebook版本4.0.0似乎有这么多的东西已经改变。 这是我的代码工作正常。 希望它可以帮助你。

  /** * 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); } 

Facebook不允许与Intent.EXTRA_TEXT分享纯文本数据,但您可以使用此分享文本+链接与facebook messanger,这对我来说工作正常

  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);