I am sharing a video on FB via share dialog in Android. The sharing works perfectly fine. However, FB post id returns null. The callback returns even before the video is uploaded. Please let me know, if I missing something. Below is my code.
public class TestFragment extends Fragment {
private CallbackManager callbackManager;
private ShareDialog shareDialog;
public TestFragment() {
// Required empty public constructor
}
public static TestFragment newInstance(String path, String json) {
TestFragment fragment = new TestFragment();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FacebookSdk.sdkInitialize(getActivity());
callbackManager = CallbackManager.Factory.create();
shareDialog = new ShareDialog(this);
// this part is optional
shareDialog.registerCallback(callbackManager, new FacebookCallback<Sharer.Result>() {
#Override
public void onSuccess(Sharer.Result result) {
Timber.d("result.getPostId() :: " + result.getPostId());
}
#Override
public void onCancel() {
Timber.d("Facebook : Cancelled");
}
#Override
public void onError(FacebookException e) {
Timber.d(e.getMessage());
}
});
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_test, container, false);
ButterKnife.inject(this, view);
return view;
}
#OnClick(R.id.facebookShare)
public void share() {
Timber.d("share button pressed");
if (ShareDialog.canShow(ShareVideoContent.class)) {
Timber.d("showing share dialog");
shareDialog.show(getVideoContent());
} else {
Timber.d("unable to show the share dialog");
}
}
private ShareVideoContent getVideoContent() {
Timber.d(mVideoMetadata.getVideoId());
ShareVideo shareVideo = new ShareVideo.Builder()
.setLocalUrl(Uri.parse("... file ..."))
.build();
ShareVideoContent content = new ShareVideoContent.Builder()
.setVideo(shareVideo)
.build();
return content;
}
#Override
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
callbackManager.onActivityResult(requestCode, resultCode, data);
}
}
shareDialog.show(shareContent, ShareDialog.Mode.FEED);
Set mode to ShareDialog.Mode.FEED.
It's working for me .
Here's example
When Login Success With Facebook Then Call This Method
shareOnFacebook()
private void shareOnFacebook(){
ShareLinkContent shareContent = new ShareLinkContent.Builder()
.setContentTitle("The Simpson!")
.setContentUrl(Uri.parse("http://www.codecube.in/airbucks-project"))
.build();
mFacebookShareDialog.show(shareContent, ShareDialog.Mode.FEED);
mFacebookShareDialog.registerCallback( this.callbackManager, new FacebookCallback<Sharer.Result>() {
#Override
public void onSuccess(Sharer.Result result) {
Log.v("MyApp", "Share success!"); //Showed if I press the share or the cancel button
String postID = result.getPostId();
Log.v("MyApp", "Share success!" +result.getPostId());
}
#Override
public void onCancel() {
Log.v("MyApp", "Share canceled"); //Only showed when I press the close button
}
#Override
public void onError(FacebookException e) {
Log.v("MyApp","Share error: " + e.toString());
}
});
mFacebookShareDialog.show(shareContent, ShareDialog.Mode.FEED);
}
#Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
callbackManager.onActivityResult(requestCode, resultCode, data);
}
Related
I have a simple app, in which I am using facebook sdk to get user info. I am trying to share content by using ShareLinkContent.Builder but I am receving error:
onError:
{FacebookServiceException: httpResponseCode: -1, facebookErrorCode: 100, facebookErrorType: null, message: The parameter 'href' or 'media' is required}
Here is my MainActivity:
CallbackManager callbackManager;
ShareDialog shareDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
savedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FacebookSdk.sdkInitialize(getApplicationContext());
callbackManager = CallbackManager.Factory.create();
shareDialog = new ShareDialog(this);
shareDialog.registerCallback(callbackManager, new FacebookCallback<Sharer.Result>() {
#Override
public void onSuccess(Sharer.Result result) {
Log.d(LOG_TAG, "success");
}
#Override
public void onError(FacebookException error) {
Log.e(TAG, "onError: ", error);
}
#Override
public void onCancel() {
Log.d(LOG_TAG, "cancel");
}
});
createPost.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (ShareDialog.canShow(ShareLinkContent.class)) {
ShareLinkContent.Builder post = new ShareLinkContent.Builder();
post = post.setContentUrl(Uri.parse(""));
post.setContentTitle("");
shareDialog.show(MainActivity.this, post.build());
}
}
});
}
#Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
callbackManager.onActivityResult(requestCode, resultCode, data);
}
What happens is that, dialog does not appear and I get the above error in logcat.
UPDATE:
What I want:
Is it possible to use ShareLinkContent.Builder with a null setContentUrl, I just want my user to share his text not a link or something else. Is it possible?
I would like to use Facebook login in my App. I have just registred app and added SDK to project. However, I tried to follow the tutorial from documentation but nothing worked (I need to get ID and email from profile and send to to my server).
Fragment
public class LoginFragment extends Fragment {
#BindView(R.id.ivLogo) ImageView ivLogo;
#BindView(R.id.email) EditText edEmail;
#BindView(R.id.password) EditText edPassword;
#BindView(R.id.btnFbLogin) LoginButton btnFbLogin;
private CallbackManager callbackManager;
private AccessTokenTracker accessTokenTracker;
private ProfileTracker profileTracker;
String email, password, ID;
User user;
public LoginFragment() {
// Required empty public constructor
}
public static LoginFragment newInstance() {
LoginFragment fragment = new LoginFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LoginManager.getInstance().registerCallback(callbackManager,
new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
// App code
Log.i("success", "success");
}
#Override
public void onCancel() {
// App code
}
#Override
public void onError(FacebookException exception) {
// App code
}
});
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_login_screen, container, false);
ButterKnife.bind(this, view);
btnFbLogin.setReadPermissions("email");
btnFbLogin.setFragment(this);
// Callback registration
btnFbLogin.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
// App code
}
#Override
public void onCancel() {
// App code
}
#Override
public void onError(FacebookException exception) {
// App code
}
});
return view;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
#Override
public void onResume() {
super.onResume();
((MainActivity) getActivity()).getSupportActionBar().hide();
}
private void FBcallback() {
FacebookCallback<LoginResult> callback = new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
AccessToken accessToken = loginResult.getAccessToken();
Profile profile = Profile.getCurrentProfile();
GraphRequest request = GraphRequest.newMeRequest(
loginResult.getAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(
JSONObject object,
GraphResponse response) {
try {
String email = object.getString("email");
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
#Override
public void onCancel() { }
#Override
public void onError(FacebookException e) { }
};
btnFbLogin.setReadPermissions("email");
btnFbLogin.registerCallback(callbackManager, callback);
}
private void loginEmail() {
FactoryAPI.getInstanceLogin().login("hardcoded mail", "hardcoded password").enqueue(new Callback<UserResponse>() {
#Override
public void onResponse(Call<UserResponse> call, Response<UserResponse> response) {
if (response.isSuccessful()) {
user = response.body().getUser();
startActivity();
} else {
Toast.makeText(getContext(), R.string.email_password_is_not_right, Toast.LENGTH_LONG).show();
}
}
#Override
public void onFailure(Call<UserResponse> call, Throwable t) {
}
});
}
private void loginFB() {
FactoryAPI.getServieFBlogin().loginFB(email, ID).enqueue(new Callback<UserResponse>() {
#Override
public void onResponse(Call<UserResponse> call, Response<UserResponse> response) {
if (response.isSuccessful()) {
user = response.body().getUser();
startActivity();
} else {
Toast.makeText(getContext(), "Something went wrong", Toast.LENGTH_LONG).show();
}
}
#Override
public void onFailure(Call<UserResponse> call, Throwable t) {
Log.e("error", "error");
}
});
}
public void getEmailPassword() {
email = edEmail.getText().toString();
password = edPassword.getText().toString();
if (email.isEmpty() || password.isEmpty()) {
Toast.makeText(getContext(), R.string.empty_properties, Toast.LENGTH_SHORT).show();
}
}
public static boolean emailValidation(CharSequence target) {
return !TextUtils.isEmpty(target) && Patterns.EMAIL_ADDRESS.matcher(target).matches();
}
public void startActivity() {
Intent intent = new Intent(getContext(), AccountActivity.class);
intent.putExtra("account", user);
startActivity(intent);
}
#Override
public void onActivityResult(int requestCode, int responseCode, Intent intent) {
super.onActivityResult(requestCode, responseCode, intent);
callbackManager.onActivityResult(requestCode, responseCode, intent);
}
#OnClick({R.id.sign_up_email, R.id.btnFbLogin})
public void onClick(View view) {
switch (view.getId()) {
case R.id.sign_up_email:
loginEmail();
case R.id.btnFbLogin:
break;
}
}
private void getProfile(Profile profile){
if(profile != null){
ID = profile.getId();
}
}
}
As your facebook login is in Fragment not in activity, so the
callback comes in onActivityResult() of Activity in which this fragment attached.
You can check this after override the onActivityResult() of your activity, and put a debug point there.
After you getting result in your activity onActivityResult() method, you can send it to your fragment's onActivityResult().
Hope this will help.
First of all if you are using LoginButton then you don't need to register with LoginManager. Here is the sample
//Using Facebook's LoginButton
//Register Callback
callbackManager = CallbackManager.Factory.create();
loginButton = (LoginButton) findViewById(R.id.login_button);
loginButton.setReadPermissions(Arrays.asList("email")); //set permissions as public_profile, email, etc
loginButton.setFragment(this); //If you are using in a fragment
// Callback registration
loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
// App code
}
#Override
public void onCancel() {
// App code
}
#Override
public void onError(FacebookException exception) {
// App code
}
});
Now with LoginManager when using Custom Button to login instead of FB's LoginButton
//To check if you are already logged In
boolean loggedIn = AccessToken.getCurrentAccessToken() == null;
// To Manually login. This will launch facebook's login screen.
LoginManager.getInstance().logInWithReadPermissions(this,
Arrays.asList("public_profile","email"));
In both the cases, for Fragment or Activity you need to handle onActivityResult
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
callbackManager.onActivityResult(requestCode, resultCode, data);
super.onActivityResult(requestCode, resultCode, data);
}
public class AndroidTwitterExample extends Activity {
private TwitterLoginButton twitterButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
setUpViews();
}
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onDestroy() {
super.onDestroy();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
twitterButton.onActivityResult(requestCode, resultCode, data);
}
private void setUpViews() {
setUpTwitterButton();
}
private void setUpTwitterButton() {
twitterButton = (TwitterLoginButton) findViewById(R.id.twitter_button);
twitterButton.setCallback(new Callback<TwitterSession>() {
#Override
public void success(Result<TwitterSession> result) {
String username =result.data.getUserName();
Toast.makeText(getApplicationContext(),
username,
Toast.LENGTH_SHORT).show();
Log.d("response",result.response.getBody().toString());
setUpViewsForTweetComposer();
}
#Override
public void failure(TwitterException exception) {
Toast.makeText(getApplicationContext(),
getResources().getString(R.string.app_name),
Toast.LENGTH_SHORT).show();
}
});
}
private void setUpViewsForTweetComposer() {
TweetComposer.Builder builder = new TweetComposer.Builder(this)
.text("Just setting up my Fabric!");
builder.show();
}
}
i tried the above code but result object i only get the username and userId how can i get profile pic and email.
For getting profile pic use this one in success of callback :
Twitter.getApiClient(result.data).getAccountService()
.verifyCredentials(true, false, new Callback<User>() {
#Override
public void failure(TwitterException e) {
//If any error occurs handle it here
}
#Override
public void success(Result<User> userResult) {
//If it succeeds creating a User object from userResult.data
User user = userResult.data;
//Getting the profile image url
String profileImage = user.profileImageUrl.replace("_normal", "");
Log.i("profile Image",""+profileImage);
}
});
and for email Id fetching here is reference url :
https://docs.fabric.io/android/twitter/log-in-with-twitter.html#request-user-email-address
I use fragment for facebook login. Normally everything goes fine. But in first time , when user login with facebook s/he redirected to facebook page and give permission to program but then (despite i use CallbackManager.onActivityResult) , program cannot handle the callback and stay background. How can i handle the callback ??
Relative code snippet:
public void onCreate(Bundle savedInstanceState) {
FacebookSdk.sdkInitialize(getActivity().getApplicationContext());
super.onCreate(savedInstanceState);
callbackManager = CallbackManager.Factory.create();
}
public void onResume() {
Log.i("tago" , "onResume");
super.onResume();
Profile profile = Profile.getCurrentProfile();
if (profile != null) {
tumisim = profile.getName();
firstname = profile.getFirstName();
lastname = profile.getLastName();
sharedtumisimkaydet(tumisim);
sharedfirstnamekaydet(firstname);
sharedlastnamekaydet(lastname);
}
}
public void onStop() {
super.onStop();
getActivity().finish();
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.facebookfragment, container, false);
int[] taniticiresimler = {R.mipmap.aciklama,R.mipmap.dene_uc,R.mipmap.yenigus,R.mipmap.galp};
CustomPagerAdapter pagerAdapter = new CustomPagerAdapter(getActivity(),taniticiresimler);
FadingIndicator indicator = (FadingIndicator)view.findViewById(R.id.circleIndicator);
ViewPager viewPager = (ViewPager) view.findViewById(R.id.pager);
viewPager.setAdapter(pagerAdapter);
indicator.setViewPager(viewPager);
indicator.setFillColor(Color.BLUE);
indicator.setStrokeColor(Color.BLACK);
indicator.setRadius(15f);
LoginButton loginButton = (LoginButton) view.findViewById(R.id.login_button);
loginButton.setReadPermissions(Arrays.asList("user_friends", "public_profile", "email"));
loginButton.setFragment(this);
loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
profile = Profile.getCurrentProfile();
if (profile.getId() != null) {
facebookID = profile.getId();
String a = sharedFacebookIDAl();
if (a.equals("defaultfacebookID")) {
sharedilkgiriskaydet(true);
}else if(!a.equals(facebookID)){
sharedilkgiriskaydet(true);
}else{
sharedilkgiriskaydet(false);
}
sharedfacebookIDkaydet(facebookID);
KullaniciProfilCek kPC = new KullaniciProfilCek();
kPC.execute(profile.getId());
}
GraphRequest request = GraphRequest.newMeRequest(AccessToken.getCurrentAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
try {
email = object.getString("email");
sharedemailkaydet(email);
cinsiyet = object.getString("gender");
sharedcinsiyetkaydet(cinsiyet);
coverphotourl = object.getJSONObject("cover").getString("source");
sharedcoverphotourlkaydet(coverphotourl);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "email,gender,cover");
request.setParameters(parameters);
request.executeAsync();
}
#Override
public void onCancel() {
Toast.makeText(getActivity(), "Facebook Login iptal edildi", Toast.LENGTH_LONG).show();
}
#Override
public void onError(FacebookException error) {
Toast.makeText(getActivity(), "Facebook Login hata oluşturdu", Toast.LENGTH_LONG).show();
}
});
return view;
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
callbackManager.onActivityResult(requestCode, resultCode, data);
Log.i("tago" , "geri geldi");
}
Inside the fragment you cannot listen onActivityResult directly. Listen the results in the onActivityResult inside your Activity. Put the code below in the Activity which holds the fragment.
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
Fragment fragment = (Fragment) getChildFragmentManager().findFragmentByTag(childTag);
if (fragment != null) {
fragment.onActivityResult(requestCode, resultCode, intent);
}
}
and then the OnActivityResult() inside the fragment will work.
You are using onActivityResult() wrong - you do not call super class implementation unless you know you need to. This got nothing with the need of calling super i.e. in onCreate() etc. Here's documentation you should read now:
https://developer.android.com/training/basics/intents/result.html
I have implemented a tab layout using fragments and viewpager. However, on my fifth tab, I want to share where the user is on the google maps, which is on the third tab. This is my code for my "Share on Facebook" tab.
TabFour.java
public class TabFour extends Fragment {
private UiLifecycleHelper uiHelper;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.activity_tab_four, container, false);
return rootView;
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
uiHelper = new UiLifecycleHelper(this, callback);
uiHelper.onCreate(savedInstanceState);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
uiHelper.onActivityResult(requestCode, resultCode, data, new FacebookDialog.Callback() {
#Override
public void onError(FacebookDialog.PendingCall pendingCall, Exception error, Bundle data) {
Log.e("Activity", String.format("Error: %s", error.toString()));
}
#Override
public void onComplete(FacebookDialog.PendingCall pendingCall, Bundle data) {
Log.i("Activity", "Success!");
}
});
}
#Override
public void onResume() {
super.onResume();
uiHelper.onResume();
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
uiHelper.onSaveInstanceState(outState);
}
#Override
public void onPause() {
super.onPause();
uiHelper.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
uiHelper.onDestroy();
}
private Session.StatusCallback callback = new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state,
Exception exception) {
// TODO Auto-generated method stub
}
};
}
However, there is an error on this line:
uiHelper = new UiLifecycleHelper(this, callback);
and the error says:
The constructor UiLifecycleHelper(TabFour, Session.StatusCallback) is undefined
What could be the possible problem? There is no other methods for the UiLifecycleHelper on Facebook Developers. Please help. Thanks!
Document say :
public UiLifecycleHelper(Activity activity, Session.StatusCallback callback)
Creates a new UiLifecycleHelper.
Parameters
activity: the Activity associated with the helper. If calling from a Fragment, use Fragment.getActivity()
callback: the callback for Session status changes, can be null
For more information you can check this link:
https://developers.facebook.com/docs/reference/android/current/UiLifecycleHelper
That's because the this you're using refers to the Fragment, not an Activity, which is what the constructor requires. Try replacing this with getActivity (or if you're using ABS, getSherlockActivity)
I know I am replying late, but I hope this will help all others..
In your fragment class call this..
FragmentActivity activity=getActivity();
Now in UiLifeCycleHelper constructor, pass activity instead of "this"
uiHelper=new UiLifeCycleHelper(activity, CallBack);
On Facebook SDK 4.x UiLifecycleHelper is replaced with CallbackManager. To implement Facebook Share Dialog in a fragment now is easier:
1) OnCreateView in your fragment class:
CallbackManager mCallbackManagerFacebook;
// Facebook Share
mCallbackManagerFacebook = CallbackManager.Factory.create();
2) In your app class:
// Facebook
FacebookSdk.sdkInitialize(getApplicationContext());
3) Override onActivityResult in your fragment class with:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
mCallbackManagerFacebook.onActivityResult(requestCode, resultCode, data);
}
4) For example, you have a button that OnClickListener the user can share a photo:
ImageButton fbBtn = (ImageButton) v.findViewById(R.id.facebookHomeDetailButton);
fbBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mProgressBar.setSpinSpeed(10);
mProgressBar.setVisibility(View.VISIBLE);
mProgressBar.spin();
if (ShareDialog.canShow(ShareLinkContent.class)) {
ParseFile fileObject = (ParseFile)mParseObjectsList.get(mPosition).get("thumbnail");
fileObject.getDataInBackground(new GetDataCallback() {
public void done(byte[] data, ParseException e) {
if (e == null) {
Log.d("test", "We've got data in data.");
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
SharePhoto photo = new SharePhoto.Builder()
.setBitmap(bitmap)
.build();
SharePhotoContent content = new SharePhotoContent.Builder()
.addPhoto(photo)
.build();
mShareDialogFacebook.show(getActivity(), content);
mProgressBar.stopSpinning();
mProgressBar.setVisibility(View.INVISIBLE);
} else {
Log.d("test", "There was a problem downloading the data.");
}
}
});
} else {
showDialogWithOk("¡Ooops!\nParece que no tienes Facebook instalado en tu dispositivo. Para compartir tendrías que instalar esta aplicación en tu dispositivo.\n¡Gracias!");
}
}
});
5) That´s all. I hope that this code can help.