Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android facebook 4.0.0 share dialog does not share the content

For hours I have been trying to share a content in my android app by facebook 4.0.0 sdk. I exactly followed facebook share document but got no result. Share dialog open when I press share button but no content is in it. If I click ok it share an empty string just. Please show me a way to fix this.

Edit

BTW When I remove Facebook native app from my phone, I can share with webview of facebook.

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

enter image description here

like image 613
gabby Avatar asked Mar 27 '15 22:03

gabby


2 Answers

You need to create the ShareDialog with the fragment you are in(this), not the activity. The onActivityResult is returned to the activity as it's written so it doesn't make it to the callback manager.

like image 134
Gokhan Caglar Avatar answered Oct 29 '22 18:10

Gokhan Caglar


I post this answer because Gabby wants to share my codes in there.

This is my 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);
}

I have a CustomShareActionProvider class which is helping me to detect user tap events. If the user tap the share on Facebook button, ShareDialog opens.

Here is my 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);
    }
}
}
like image 39
emresancaktar Avatar answered Oct 29 '22 18:10

emresancaktar