我正在开发一款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 bug)对于平均时间,我似乎只能忍受负面的“分享不起作用!!!”评论。干杯Facebook:*(
答案 0 :(得分:108)
显然Facebook不再(截至2014年)允许您自定义共享屏幕,无论您是打开sharer.php URL还是以更专业的方式使用Android意图。例如,请参阅以下答案:
无论如何,使用简单的意图,你可以仍然共享一个网址,但不能共享任何默认文字,如billynomates commented。 (此外,如果您没有要共享的URL,只需启动带有空“Write Post”(即状态更新)对话框的Facebook应用程序同样容易;使用下面的代码但忽略EXTRA_TEXT
。)
这是我发现不涉及使用任何Facebook SDK的最佳解决方案。
此代码直接打开官方Facebook应用(如果已安装),否则将回退到浏览器中打开sharer.php。 (这个问题中的大多数其他解决方案都会提出a huge "Complete action using…" dialog,这根本不是最优的!)
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's comment。)
在安装了Facebook应用的Nexus 7(Android 4.4)上,结果如下所示:
答案 1 :(得分:90)
Facebook应用程序无法处理
EXTRA_SUBJECT
或EXTRA_TEXT
字段。
以下是错误链接:https://developers.facebook.com/bugs/332619626816423
谢谢@billynomates:
问题是,如果您在
EXTRA_TEXT
字段中添加了网址,那么会 工作。这就像他们故意剥离任何文本一样。
答案 2 :(得分:15)
通常的方式
创建您要求的通常方法是简单地执行以下操作:
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();
}
答案 3 :(得分:4)
这是我做的(文字)。在代码中,我复制剪贴板所需的任何文本。当个人第一次尝试使用共享意图按钮时,我弹出一个通知,说明他们是否希望分享到Facebook,他们需要点击“Facebook&#39;然后长按粘贴(这是为了让他们意识到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 /先前版本的方法
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);
}
答案 4 :(得分:4)
在Lollipop(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);
}
答案 5 :(得分:3)
我发现您只能共享文字 或 图片,而不能同时使用Intents
。如果存在,则下面的代码仅共享图像,如果图像未退出,则仅共享文本。如果您想共享这两者,则需要使用Facebook SDK from here.
如果您使用其他解决方案而不是代码,请不要忘记指定包名称 com.facebook.lite ,这是 Facebook Lite的包名 。我没有测试,但 com.facebook.orca 是 Facebook Messenger 的包名称,如果你想要定位它。
添加更多方法进行分享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
答案 6 :(得分:1)
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);
}
答案 7 :(得分:0)
以下是我用链接打开Facebook App的方法
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);
答案 8 :(得分:0)
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)));
}
答案 9 :(得分:0)
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);
答案 10 :(得分:0)
我可以找到将消息从我的应用程序传递到Facebook的最简单方法是以编程方式复制到剪贴板,并提醒用户他们可以选择粘贴。这样可以避免用户手动执行操作;我的应用程序没有粘贴,但是用户可以粘贴。
...
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);
...