Reputation: 639
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);
}
Upvotes: 5
Views: 14239
Reputation: 1567
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);
}
}
}
Upvotes: 1
Reputation: 1
Im not sure if thats your problem, but my share dialogs were always empty on facebook. To solve this, i just changed the .setContentUrl. If you put a link to google play or app store it will simply empty the dialog, so you should change it to any different link.
Upvotes: 0
Reputation: 11
Your code is exception in onError() method? Message is "Not found app name".
If right you need add code in manifest:
<meta-data
android:name="com.facebook.sdk.ApplicationName"
android:value="@string/facebook_app_name" />
You need edit app_name in string.xml the same app name on Facebook dev website.
Upvotes: 1
Reputation: 1811
This is the onClick()
I am using in a fragment and I am able to post with this on 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);
}
}
}
Upvotes: 0
Reputation: 1137
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.
Upvotes: 4