Android facebook 4.0.0 分享对话框不分享内容

Android facebook 4.0.0 share dialog does not share the content

几个小时以来,我一直在尝试通过 facebook 4.0.0 sdk 在我的 android 应用程序中分享内容。我完全按照 facebook share document 但没有得到结果。按共享按钮时共享对话框打开,但其中没有内容。如果我单击“确定”,它只会共享一个空字符串。请告诉我解决此问题的方法。

编辑

顺便说一句,当我从 phone 中删除 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);
    }

您需要使用您所在的片段(this)创建 ShareDialog,而不是 activity。 onActivityResult 返回到 activity,因为它被写入,所以它不会进入回调管理器。

这是我在片段中使用的 onClick(),我可以 post 在 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);
            }
        }
    }

您的代码在 onError() 方法中出现异常?消息是 "Not found app name"。 如果正确,您需要在清单中添加代码: <meta-data android:name="com.facebook.sdk.ApplicationName" android:value="@string/facebook_app_name" />

您需要在 Facebook 开发网站上的 string.xml 中编辑 app_name 相同的应用程序名称。

我post这个答案是因为 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 class,它可以帮助我检测用户点击事件。如果用户点击“在 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);
    }
}
}

我不确定这是否是你的问题,但我在 Facebook 上的分享对话框总是空的。为了解决这个问题,我只是更改了 .setContentUrl。如果您将 link 放入 google 播放或应用程序商店,它只会清空对话框,因此您应该将其更改为任何不同的 link.