Search code examples
androidfacebook-android-sdkandroid-facebookfacebook-sdk-4.0

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


Solution

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