Android facebook 4.0.0 分享对话框不分享内容
Posted
技术标签:
【中文标题】Android facebook 4.0.0 分享对话框不分享内容【英文标题】:Android facebook 4.0.0 share dialog does not share the content 【发布时间】:2015-03-27 22:48:20 【问题描述】:几个小时以来,我一直在尝试通过 facebook 4.0.0 sdk 在我的 android 应用程序中分享内容。我完全关注facebook share document,但没有得到任何结果。当我按下共享按钮但其中没有内容时,共享对话框打开。如果我单击确定,它只会共享一个空字符串。请告诉我解决此问题的方法。
编辑
顺便说一句,当我从手机中删除 Facebook 原生应用时,我可以与 facebook 的 webview 共享。
CallbackManager callbackManager;
ShareDialog shareDialog;
private View rootView;
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
FacebookSdk.sdkInitialize(activity);
callbackManager = CallbackManager.Factory.create();
shareDialog = new ShareDialog(activity);
rootView = inflater.inflate(R.layout.fragment_events, container, false);
shareDialog.registerCallback(callbackManager, shareCallBack);
lbtnShare = (LinearLayout) rootView.findViewById(R.id.lbtn_shareOnFb);
lbtnShare.setOnClickListener(this);
init(rootView);
return rootView;
public FacebookCallback<Sharer.Result> shareCallBack = new FacebookCallback<Sharer.Result>()
@Override
public void onSuccess(Result result)
showToast(message(R.string.title_fbShare)).show();
@Override
public void onCancel()
@Override
public void onError(FacebookException error)
showToast(message(R.string.msgerr_shareOnFB) + " -- " + error.getMessage()).show();
;
public void onClick(View v)
switch (v.getId())
case R.id.lbtn_shareOnFb:
shareOnFB();
break;
default:
break;
private void shareOnFB()
if (ShareDialog.canShow(ShareLinkContent.class))
String eventUrl = "http://www.mypage.com?id=" + event.getId();
eventUrl = eventUrl.replaceAll(" ", "-");
ShareLinkContent adShareContent = new ShareLinkContent.Builder()
.setContentTitle(event.getTitle())
.setContentDescription(message(R.string.fbshareDesc))
.setContentUrl(Uri.parse(eventUrl))
.setImageUrl(Uri.parse(event.getImages().get(0).getName())).build();
shareDialog.show(adShareContent);
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
super.onActivityResult(requestCode, resultCode, data);
callbackManager.onActivityResult(requestCode, resultCode, data);
【问题讨论】:
我受够了 Facebook SDK 4.0 的文档(我见过的最差的文档)。我无法在时间线上分享与通过 ShareDialog 分享的帖子相似的正常帖子(2 天后没有进展)。虽然,我通过 ShareDialog 成功分享了与您类似的代码 是的,你是对的。如果你成功了,那为什么不在我的代码中告诉我错误的部分 因为我的代码和你的差不多,反正我已经贴出来了,请看一下 共享者的回调是如何工作的?在我的身上,它永远不会遇到 sharer.result 回调。除了在 shareDialog 上注册之外,我还遗漏了什么吗? @user2511882 +1 我可以分享任何内容,但如果我通过 WebDialog 进行此操作,无论成功还是失败,我都不会得到任何祝酒词。 【参考方案1】:您需要使用您所在的片段(此)而不是活动来创建 ShareDialog。 onActivityResult 在写入时返回给活动,因此它不会到达回调管理器。
【讨论】:
我改变了 shareDialog 就像那样 shareDialog = new ShareDialog(this);但没有任何改变。并且 shareCallBack 从未被调用过 是否调用了onActivityResult?在 Fragment 和 Activity 上都添加断点,然后查看调用的是哪一个。 Activity 中的 onActivityResult 在 Fragment 中被调用。太有趣了。 如果调用了activity的onActivityResult,说明你正在用activity创建SharDialog。 那是不可能的。shareDialog = new ShareDialog(AdFragment.this);我将 Fragment 本身发送到 ShareDialog 的构造函数。 Gerçekten:)【参考方案2】:我发布这个答案是因为 Gabby 想在那里分享我的代码。
这是我的 MainActivity.java ;
public class MainActivity extends ActionBarActivity implements ActionBar.TabListener
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
FragmentManager manager;
CustomShareActionProvider mShareActionProvider;
Intent mShareIntent;
CallbackManager callbackManager;
ShareDialog shareDialog;
MenuItem mItem;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FacebookSdk.sdkInitialize(getApplicationContext());
callbackManager = CallbackManager.Factory.create();
shareDialog = new ShareDialog(this);
manager = getSupportFragmentManager();
// Set up the action bar.
final ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setLogo(R.drawable.nav_logo);
getSupportActionBar().setDisplayUseLogoEnabled(true);
getSupportActionBar().setTitle("");
mSectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener()
@Override
public void onPageSelected(int position)
actionBar.setSelectedNavigationItem(position);
);
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++)
actionBar.addTab(
actionBar.newTab()
//.setText(mSectionsPagerAdapter.getPageTitle(i))
.setIcon(mSectionsPagerAdapter.getIcon(i))
.setTabListener(this));
@Override
public boolean onCreateOptionsMenu(Menu menu)
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
private Intent shareIntentContents()
mShareIntent = new Intent();
mShareIntent.setAction(Intent.ACTION_SEND);
mShareIntent.setType("text/plain");
mShareIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.share_all_title));
mShareIntent.putExtra(Intent.EXTRA_TEXT, getString(R.string.share_all_message) +"\n" + getString(R.string.share_onall_url));
return mShareIntent;
@Override
public boolean onOptionsItemSelected(MenuItem item)
int id = item.getItemId();
if (id == R.id.action_share)
mItem = item;
shareSocial();
else if (id == R.id.action_about)
Intent intent = new Intent(this,InfoActivity.class);
startActivity(intent);
else if (id == R.id.action_ilk_yardim)
Intent intent = new Intent(this,IlkYardimActivity.class);
startActivity(intent);
return super.onOptionsItemSelected(item);
private void shareSocial()
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(html.fromHtml("<font color=\"#18bea4\">" + "Merhaba!" + "</font>"));
builder.setMessage(getString(R.string.social_alert_view_message))
.setCancelable(true)
.setPositiveButton(getString(R.string.share_social_alertview_ok_button_title), new DialogInterface.OnClickListener()
public void onClick(DialogInterface dialog, int id)
mShareActionProvider = new CustomShareActionProvider(MainActivity.this);
MenuItemCompat.setActionProvider(mItem, mShareActionProvider);
mShareActionProvider = (CustomShareActionProvider) MenuItemCompat.getActionProvider(mItem);
mShareActionProvider.setShareIntent(shareIntentContents());
if (mShareActionProvider != null)
mShareActionProvider.setShareIntent(shareIntentContents());
mShareActionProvider.setOnShareListener(new CustomShareActionProvider.OnShareListener()
@Override
public boolean willHandleShareTarget(CustomShareActionProvider source, Intent intent)
if (intent.getComponent().getPackageName().contains("facebook"))
if (ShareDialog.canShow(ShareLinkContent.class))
ShareLinkContent linkContent = new ShareLinkContent.Builder()
.setContentTitle(getString(R.string.share_onfacebook_title))
.setContentDescription(
getString(R.string.share_onfacebook_message))
.setContentUrl(Uri.parse(getString(R.string.share_onfacebook_url)))
.setImageUrl(Uri.parse(getString(R.string.share_onfacebook_image_url)))
.build();
shareDialog.show(linkContent);
return true;
else //NOT FACEBOOK default behaviour.
return false;
);
else
Toast.makeText(MainActivity.this, (R.string.share_menu_error_title), Toast.LENGTH_LONG).show();
)
.setNegativeButton(getString(R.string.share_social_alertview_cancel_button_title), new DialogInterface.OnClickListener()
public void onClick(DialogInterface dialog, int id)
dialog.cancel();
);
AlertDialog alert = builder.create();
alert.show();
@Override
public void onActivityResult(final int requestCode, final int resultCode, final Intent data)
super.onActivityResult(requestCode, resultCode, data);
callbackManager.onActivityResult(requestCode, resultCode, data);
我有一个 CustomShareActionProvider 类,它可以帮助我检测用户点击事件。如果用户点击 Facebook 上的分享按钮,ShareDialog 就会打开。
这是我的 CustomShareActionProvider.class:
public class CustomShareActionProvider extends ActionProvider
public void setOnShareListener(OnShareListener listener)
mOnShareListener = listener;
setActivityChooserPolicyIfNeeded();
/**
* Listener for the event of selecting a share target.
*/
public interface OnShareTargetSelectedListener
/**
* Called when a share target has been selected. The client can
* decide whether to perform some action before the sharing is
* actually performed.
* <p>
* <strong>Note:</strong> Modifying the intent is not permitted and
* any changes to the latter will be ignored.
* </p>
* <p>
* <strong>Note:</strong> You should <strong>not</strong> handle the
* intent here. This callback aims to notify the client that a
* sharing is being performed, so the client can update the UI
* if necessary.
* </p>
*
* @param source The source of the notification.
* @param intent The intent for launching the chosen share target.
* @return The return result is ignored. Always return false for consistency.
*/
public boolean onShareTargetSelected(CustomShareActionProvider source, Intent intent);
private OnShareListener mOnShareListener; //also need to add getter and setter
public interface OnShareListener
/**
* Called when a share target has been selected. The client can
* decide whether to perform some action before the sharing is
* actually performed OR handle the action itself.
*
* @param source The source of the notification.
* @param intent The intent for launching the chosen share target.
* @return Return true if you have handled the intent.
*/
public boolean willHandleShareTarget(CustomShareActionProvider source, Intent intent);
/**
* The default for the maximal number of activities shown in the sub-menu.
*/
private static final int DEFAULT_INITIAL_ACTIVITY_COUNT = 4;
/**
* The the maximum number activities shown in the sub-menu.
*/
private int mMaxShownActivityCount = DEFAULT_INITIAL_ACTIVITY_COUNT;
/**
* Listener for handling menu item clicks.
*/
private final ShareMenuItemOnMenuItemClickListener mOnMenuItemClickListener =
new ShareMenuItemOnMenuItemClickListener();
/**
* The default name for storing share history.
*/
public static final String DEFAULT_SHARE_HISTORY_FILE_NAME = "share_history.xml";
/**
* Context for accessing resources.
*/
private final Context mContext;
/**
* The name of the file with share history data.
*/
private String mShareHistoryFileName = DEFAULT_SHARE_HISTORY_FILE_NAME;
private OnShareTargetSelectedListener mOnShareTargetSelectedListener;
private OnChooseActivityListener mOnChooseActivityListener;
/**
* Creates a new instance.
*
* @param context Context for accessing resources.
*/
public CustomShareActionProvider(Context context)
super(context);
mContext = context;
/**
* Sets a listener to be notified when a share target has been selected.
* The listener can optionally decide to handle the selection and
* not rely on the default behavior which is to launch the activity.
* <p>
* <strong>Note:</strong> If you choose the backing share history file
* you will still be notified in this callback.
* </p>
* @param listener The listener.
*/
public void setOnShareTargetSelectedListener(OnShareTargetSelectedListener listener)
mOnShareTargetSelectedListener = listener;
setActivityChooserPolicyIfNeeded();
/**
* @inheritDoc
*/
@Override
public View onCreateActionView()
// Create the view and set its data model.
ActivityChooserView activityChooserView = new ActivityChooserView(mContext);
if (!activityChooserView.isInEditMode())
ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mShareHistoryFileName);
activityChooserView.setActivityChooserModel(dataModel);
// Lookup and set the expand action icon.
TypedValue outTypedValue = new TypedValue();
mContext.getTheme().resolveAttribute(R.attr.actionModeShareDrawable, outTypedValue, true);
Drawable drawable = TintManager.getDrawable(mContext, outTypedValue.resourceId);
activityChooserView.setExpandActivityOverflowButtonDrawable(drawable);
activityChooserView.setProvider(this);
// Set content description.
activityChooserView.setDefaultActionButtonContentDescription(
R.string.abc_shareactionprovider_share_with_application);
activityChooserView.setExpandActivityOverflowButtonContentDescription(
R.string.abc_shareactionprovider_share_with);
return activityChooserView;
/**
* @inheritDoc
*/
@Override
public boolean hasSubMenu()
return true;
/**
* @inheritDoc
*/
@Override
public void onPrepareSubMenu(SubMenu subMenu)
// Clear since the order of items may change.
subMenu.clear();
ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mShareHistoryFileName);
PackageManager packageManager = mContext.getPackageManager();
final int expandedActivityCount = dataModel.getActivityCount();
final int collapsedActivityCount = Math.min(expandedActivityCount, mMaxShownActivityCount);
// Populate the sub-menu with a sub set of the activities.
for (int i = 0; i < collapsedActivityCount; i++)
ResolveInfo activity = dataModel.getActivity(i);
subMenu.add(0, i, i, activity.loadLabel(packageManager))
.setIcon(activity.loadIcon(packageManager))
.setOnMenuItemClickListener(mOnMenuItemClickListener);
if (collapsedActivityCount < expandedActivityCount)
// Add a sub-menu for showing all activities as a list item.
SubMenu expandedSubMenu = subMenu.addSubMenu(Menu.NONE, collapsedActivityCount,
collapsedActivityCount,
mContext.getString(R.string.abc_activity_chooser_view_see_all));
for (int i = 0; i < expandedActivityCount; i++)
ResolveInfo activity = dataModel.getActivity(i);
expandedSubMenu.add(0, i, i, activity.loadLabel(packageManager))
.setIcon(activity.loadIcon(packageManager))
.setOnMenuItemClickListener(mOnMenuItemClickListener);
/**
* Sets the file name of a file for persisting the share history which
* history will be used for ordering share targets. This file will be used
* for all view created by @link #onCreateActionView(). Defaults to
* @link #DEFAULT_SHARE_HISTORY_FILE_NAME. Set to <code>null</code>
* if share history should not be persisted between sessions.
* <p>
* <strong>Note:</strong> The history file name can be set any time, however
* only the action views created by @link #onCreateActionView() after setting
* the file name will be backed by the provided file. Therefore, if you want to
* use different history files for sharing specific types of content, every time
* you change the history file @link #setShareHistoryFileName(String) you must
* call @link android.app.Activity#invalidateOptionsMenu() to recreate the
* action view. You should <strong>not</strong> call
* @link android.app.Activity#invalidateOptionsMenu() from
* @link android.app.Activity#onCreateOptionsMenu(Menu)."
* <p>
* <code>
* private void doShare(Intent intent)
* if (IMAGE.equals(intent.getMimeType()))
* mShareActionProvider.setHistoryFileName(SHARE_IMAGE_HISTORY_FILE_NAME);
* else if (TEXT.equals(intent.getMimeType()))
* mShareActionProvider.setHistoryFileName(SHARE_TEXT_HISTORY_FILE_NAME);
*
* mShareActionProvider.setIntent(intent);
* invalidateOptionsMenu();
*
* <code>
*
* @param shareHistoryFile The share history file name.
*/
public void setShareHistoryFileName(String shareHistoryFile)
mShareHistoryFileName = shareHistoryFile;
setActivityChooserPolicyIfNeeded();
/**
* Sets an intent with information about the share action. Here is a
* sample for constructing a share intent:
* <p>
* <pre>
* <code>
* Intent shareIntent = new Intent(Intent.ACTION_SEND);
* shareIntent.setType("image/*");
* Uri uri = Uri.fromFile(new File(getFilesDir(), "foo.jpg"));
* shareIntent.putExtra(Intent.EXTRA_STREAM, uri.toString());
* </pre>
* </code>
* </p>
*
* @param shareIntent The share intent.
*
* @see Intent#ACTION_SEND
* @see Intent#ACTION_SEND_MULTIPLE
*/
public void setShareIntent(Intent shareIntent)
if (shareIntent != null)
final String action = shareIntent.getAction();
if (Intent.ACTION_SEND.equals(action) || Intent.ACTION_SEND_MULTIPLE.equals(action))
updateIntent(shareIntent);
ActivityChooserModel dataModel = ActivityChooserModel.get(mContext,
mShareHistoryFileName);
dataModel.setIntent(shareIntent);
/**
* Reusable listener for handling share item clicks.
*/
private class ShareMenuItemOnMenuItemClickListener implements OnMenuItemClickListener
@Override
public boolean onMenuItemClick(MenuItem item)
ActivityChooserModel dataModel = ActivityChooserModel.get(mContext,
mShareHistoryFileName);
final int itemId = item.getItemId();
Intent launchIntent = dataModel.chooseActivity(itemId);
if (launchIntent != null)
final String action = launchIntent.getAction();
if (Intent.ACTION_SEND.equals(action) ||
Intent.ACTION_SEND_MULTIPLE.equals(action))
updateIntent(launchIntent);
mContext.startActivity(launchIntent);
return true;
/**
* Set the activity chooser policy of the model backed by the current
* share history file if needed which is if there is a registered callback.
*/
private void setActivityChooserPolicyIfNeeded()
if (mOnShareListener == null)
return;
if (mOnChooseActivityListener == null)
mOnChooseActivityListener = new ShareActivityChooserModelPolicy();
ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mShareHistoryFileName);
dataModel.setOnChooseActivityListener(mOnChooseActivityListener);
/**
* Policy that delegates to the @link OnShareTargetSelectedListener, if such.
*/
private class ShareActivityChooserModelPolicy implements OnChooseActivityListener
@Override
public boolean onChooseActivity(ActivityChooserModel host, Intent intent)
if (mOnShareListener != null)
boolean result = mOnShareListener.willHandleShareTarget(
CustomShareActionProvider.this, intent);
return result;
return false;
private void updateIntent(Intent intent)
if (Build.VERSION.SDK_INT >= 21)
// If we're on Lollipop, we can open the intent as a document
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT |
Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
else
// Else, we will use the old CLEAR_WHEN_TASK_RESET flag
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
【讨论】:
【参考方案3】:您的代码在 onError() 方法中是异常的吗?消息是“未找到应用程序名称”。
如果正确,您需要在清单中添加代码:
<meta-data
android:name="com.facebook.sdk.ApplicationName"
android:value="@string/facebook_app_name" />
您需要在 string.xml 中编辑 app_name 与 Facebook 开发网站上相同的应用名称。
【讨论】:
不,它不会抛出任何异常。即使它没有落在我的片段中的任何 shareCallBack 方法上。我试过 3 款不同的手机 S4、s4-mini、S2 app_name 对于 facebook 应用程序和我的 android 应用程序都是相同的。我也在清单中添加了这个元数据标签,但没有任何改变。我仍然无法通过我的 android 应用在 facebook 上分享我的内容(链接、descriptipn、img) shareCallBack 已被调用?您可以在 onSuccess()、onCancel()、onError() 方法中编写日志。您会看到日志 cat 显示任何错误或警告。 当我点击分享按钮时,logcat 中没有错误。我在 FacebookCallback 的每个方法中都写了日志,它没有写入 logcat,因为它的方法从未被调用过【参考方案4】:这是我在片段中使用的onClick()
,我可以在 FB 上发帖
@Override
public void onClick(View view)
Profile profile = Profile.getCurrentProfile();
AccessToken accessToken = AccessToken.getCurrentAccessToken();
if (profile != null && accessToken != null)
if (accessToken.getPermissions().contains("publish_actions"))
ShareLinkContent shareContent = new ShareLinkContent.Builder()
.setContentTitle(title).setContentDescription(desc)
.setContentUrl(Uri.parse(url))
.build();
ShareDialog shareDialog = new ShareDialog(getActivity());
shareDialog.registerCallback(mCallbackManager, new FacebookCallback<Sharer.Result>()
@Override
public void onSuccess(Sharer.Result result)
Toast.makeText(getActivity(), "Share Success", Toast.LENGTH_SHORT).show();
@Override
public void onCancel()
Toast.makeText(getActivity(), "Share Cancelled", Toast.LENGTH_SHORT).show();
@Override
public void onError(FacebookException exception)
Toast.makeText(getActivity(), exception.getMessage(), Toast.LENGTH_LONG).show();
Log.e(TAG, "Share: " + exception.getMessage());
exception.printStackTrace();
);
if (ShareDialog.canShow(ShareLinkContent.class))
shareDialog.show(shareContent);
else
List<String> permissions = Arrays.asList("publish_actions");
LoginManager.getInstance().logInWithPublishPermissions(this, permissions);
【讨论】:
在您的代码中,Profile 和 AccessToken 始终返回 null。用户应该登录才能发布内容? 实际上,如果用户未登录并且您在发布之前登录,您将不会在 onSuccess() 中获得 Profile 和 AccessTokens,您只需添加 ProfileTracker,然后在待处理的情况下执行任何操作。检查捆绑在 Facebook-4.0-SDK.zip 中的 HelloFacebookSample 以上代码无需在 Android 设备上安装 FB 应用即可完美运行。如何解决设备上使用 ShareDialog 和 FB App 发帖的问题?【参考方案5】:我不确定这是否是你的问题,但我的分享对话框在 facebook 上总是空的。为了解决这个问题,我只是更改了 .setContentUrl。如果您放置一个指向 google play 或应用商店的链接,它只会清空对话框,因此您应该将其更改为任何其他链接。
【讨论】:
以上是关于Android facebook 4.0.0 分享对话框不分享内容的主要内容,如果未能解决你的问题,请参考以下文章
使用 Android 分享 Intent 在 Facebook 上分享视频
facebook 在 android 上的分享意图是不是仍然失效?