I'm trying to implement deep linking in my Android app, so far I can post to my wall but only posts that are really links that goes to google.com (obviously this is a test link). I want the user to be navigated to my app when clicking on the post through the Facebook app, please I need a step by step guide as am not that old in android programming. Here's my code:
private void sharePost() {
// code for sharing the post on facebook
Session session = Session.getActiveSession();
session.requestNewPublishPermissions(new Session.NewPermissionsRequest(this, PERMISSIONS));
Bundle postParams = new Bundle();
postParams.putString("name", "JSON Twitter");
postParams.putString("app_name", "JSON Twitter");
postParams.putString("package", "com.example.jsontwitter");
postParams.putString("url", "com.example.jsontwitter");
postParams.putString("caption", "Hello, anyone there ?!");
postParams.putString("description", "This is a description");
postParams.putString("link", "https://google.com");
postParams.putString("class", "com.example.jsontwitter.MainActivity");
new Request(session, "me/feed", postParams,
HttpMethod.POST, new Request.Callback() {
public void onCompleted(Response response) {
/* handle the result */
}
}).executeAsync();
}
One facebook status callback implemetation needed
private Session.StatusCallback mFBStatuscallback = new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state,
Exception exception) {
onSessionStateChange(session, state, exception);
}
};
Then i dont know what permission you have give.
But the permission i gave was
private static final List<String> PERMISSION = Arrays
.asList("publish_actions","publish_stream");
new permission request
set the default audience and the send the callback object(mFBStatuscallback)
Session.NewPermissionsRequest newPermissionsRequest = new Session.NewPermissionsRequest(
(Activity) mCtx, PERMISSION).setDefaultAudience(SessionDefaultAudience.FRIENDS)
.setRequestCode(100).setCallback(mFBStatuscallback);
session.requestNewPublishPermissions(newPermissionsRequest);
And rest all same as your's. I hope it will work.
Note If you keep pressing on post button for many time only one time the message gets posted. After that it takes some interval to post another message. Its a default behavior of facebook
Related
I'm able to query taggable friend from facebook but the photo url return is too small.
Is there a way to get a larger photo?
I tried everything I could think of but still won't work.
Request request = new Request(session,"/me/taggable_friends,",null,HttpMethod.GET);
Bundle params = new Bundle();
params.putInt("width", 100);
params.putInt("height", 100);
request.setParameters(params);
also tried something like this
Request request = new Request(session,"/me/taggable_friends?height=100,width=100",null,HttpMethod.GET);
Below is my code for handling the session, I don't have a login button for my application
private void onSessionStateChange(final Session session, SessionState state, Exception exception
{
if(session.isClosed())
{
Session.openActiveSession(this, true, callback);
}
}
#Override
public void onResume() {
super.onResume();
// For scenarios where the main activity is launched and user
// session is not null, the session state change notification
// may not be triggered. Trigger it if it's open/closed.
Settings.addLoggingBehavior( LoggingBehavior.INCLUDE_ACCESS_TOKENS );
Session session = Session.getActiveSession();
if (session != null)
{
//if session is either closed or open we go to session state change
//else we open it
if(session.isOpened() || session.isClosed())
onSessionStateChange(session, session.getState(), null);
else
session.openForRead(new Session.OpenRequest(this).setPermissions(Arrays.asList("public_profile","user_friends")).setCallback(callback));
}
}
Here's the callback
private Session.StatusCallback callback = new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
onSessionStateChange(session, session.getState(), null);
}
};
Please tell me if you know the solution, appreciate it.
me/taggable_friends?fields=name,picture.width(400).height(400)
Keep in mind that those are minimum values, so you may get pictures that are "at least 400x400".
Another possibility:
me/taggable_friends?fields=name,picture.type(large)
I am no Android developer, but this is how it may work:
Request request = new Request(session,"me/taggable_friends", null, HttpMethod.GET);
Bundle bundle = new Bundle();
bundle.putString("fields", "name,picture.width(400).height(400)");
request.setParameters(bundle);
You need to retrieve IDs using friends_taggable, and then use IDs like:
/0101010101/picture?redirect=true&height=200&type=square&width=200
Replace 0101010101 with the ID you want.
Basically you can call this http address and read the picture data directly:
"http://graph.facebook.com/" + id
+ "/picture?redirect=true&height=200&type=square&width=200
Request request = new Request(session,"me/taggable_friends",null,HttpMethod.GET);
Bundle bundle = new Bundle();
bundle.putString("fields", "name,picture.type(large)");
request.setParameters(bundle);
Here's the solution, hope it helps others too.
Facebook has since updated its Library and now the correct way on (4.1.0) is:
Bundle params = new Bundle();
params.putString("limit","1000");
params.putString("fields", "id,name,picture.width(256).height(256)");
new GraphRequest(AccessToken.getCurrentAccessToken(),
"/me/taggable_friends",
params,
HttpMethod.GET,
new GraphRequest.Callback() {
#Override
public void onCompleted(GraphResponse graphResponse) {
if(graphResponse != null(){
// ... handle the result
}
}
}).executeAsync();
Hi I am new to android programming. I want to share a image with some description on facebook.
I have tried every method explain in answers on stackoverflow. My problem is facebook dialog opens but it doesn't have specified bundle parameters.
Please help me with this. I have already tried almost 20 different code snippets. Please give me fully functional code.
#Override
public void onClick(View v) {
fb = new Facebook(app_id);
Bundle par = new Bundle();
par.putString("name", "Ass");
fb.dialog(con,"feed",par, new DialogListener(){
#Override
public void onCancel() {
// TODO Auto-generated method stub
}
#Override
public void onComplete(Bundle arg0) {
// TODO Auto-generated method stub
}
#Override
public void onError(DialogError arg0) {
// TODO Auto-generated method stub
}
#Override
public void onFacebookError(FacebookError arg0) {
// TODO Auto-generated method stub
}});
}
});
}
Have you already set up the facebook side of the application on the development page?
You need to have your app registered on facebook if you are intending to use their api and/or do graph requests or wall posts on behalf of a user authtoken.
You should read this tutorial (check part 5 for fb app registering) and all of the related info around it to really get going with facebook interaction within your app.
I know I did and end up creating my own library for log-in short-cuts or graph requests etc... it's not that simple, it will take you some time aswell.
Also;
Are you using the loginButton from the sdk? Like this:
<com.facebook.widget.LoginButton
android:id="#+id/authButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="30dp"
/>
It automatically handles user login to facebook whether he has the facebook app installed or not and retrieves a session status result (onStatusChange callback).
Make sure you handle that right first and that the session is correctly initiated.
Still, posting your log will give us a better idea of what you encountering with.
I have to say, tho, that the facebook api for android is pretty solid so far so you must be doing something wrong for sure.
<<<<<< EDIT: >>>>>>
Ok then, assuming you have the user correctly logged-in (session.getActiveSession() == Session.OPENED I believe), the next step is to make sure you enabled necessary permissions.
This example is from the official facebook documentation, try it (execute publishStory() in your app):
private void publishStory() {
Session session = Session.getActiveSession();
if (session != null){
// Check for publish permissions
List<String> permissions = session.getPermissions();
if (!isSubsetOf(PERMISSIONS, permissions)) {
pendingPublishReauthorization = true;
Session.NewPermissionsRequest newPermissionsRequest = new Session
.NewPermissionsRequest(this, PERMISSIONS);
session.requestNewPublishPermissions(newPermissionsRequest);
return;
}
Bundle postParams = new Bundle();
postParams.putString("name", "Facebook SDK for Android");
postParams.putString("caption", "Build great social apps and get more installs.");
postParams.putString("description", "The Facebook SDK for Android makes it easier and faster to develop Facebook integrated Android apps.");
postParams.putString("link", "https://developers.facebook.com/android");
postParams.putString("picture", "https://raw.github.com/fbsamples/ios-3.x-howtos/master/Images/iossdk_logo.png");
Request.Callback callback= new Request.Callback() {
public void onCompleted(Response response) {
JSONObject graphResponse = response
.getGraphObject()
.getInnerJSONObject();
String postId = null;
try {
postId = graphResponse.getString("id");
} catch (JSONException e) {
Log.i(TAG,
"JSON error "+ e.getMessage());
}
FacebookRequestError error = response.getError();
if (error != null) {
Toast.makeText(getActivity()
.getApplicationContext(),
error.getErrorMessage(),
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getActivity()
.getApplicationContext(),
postId,
Toast.LENGTH_LONG).show();
}
}
};
Request request = new Request(session, "me/feed", postParams,
HttpMethod.POST, callback);
RequestAsyncTask task = new RequestAsyncTask(request);
task.execute();
}
private boolean isSubsetOf(Collection<String> subset, Collection<String> superset) {
for (String string : subset) {
if (!superset.contains(string)) {
return false;
}
}
return true;
}
The code issues a POST to the users feed wall with the graph params specified at the bundle.
If session does not have the needed publish permissions, then a permission request will be issued instead. If user granted those permissions, then the RequestAsyncTask should be executed next time you call the method.
As you can see the basic idea is to get the user to log-in with his facebook account (first step), then request necessary permissions for the action, in this case, publish permissions for a wall post (second step), and lastly issue a graph request into "me/feed" with the params needed for the wall post.
In any case, if you still encountering problems please try to debug from your log as it indicates wether the request failed because of invalid session or no permissions etc...
Post your log here in that case , but this should work.
Is it possible to create a class to encapsulate the Android SDK on android?
i.e - I don't want to clutter my activity with all the FB sessions and stuff, I want to have a class that I can call and it will do the job.
For example,
FacebookSDK sdk = new FacebookSDK();
sdk.publish();
For now I couldn't find a way to do this, without using Fragments or cluttering my activity with the facebook code.
Many Thank!
Its all about session management.
//Check for active session -
Session session = Session.getActiveSession();
// if it doesnt exist create one-
if(session ==null)
session= new Session(getApplicationContext)
// if it is not open open it first
if (!session.isOpened() && !session.isClosed()) {
session.openForRead(new Session.OpenRequest(this)
.setPermissions(Arrays.asList("basic_info"))
.setCallback(statusCallback));
}
else
{
Session.openActiveSession(getActivity(), this, true, statusCallback);
}
// callback listner fires when session state changes
private class SessionStatusCallback implements Session.StatusCallback {
#Override
public void call(Session session, SessionState state, Exception exception) {
//If your session is opened
if(session.isOpened()
publishData(session);
}
Method to publish your request -
public void publishData(Session session)
{
OpenRequest open = new OpenRequest(this);
open.setLoginBehavior(SessionLoginBehavior.SUPPRESS_SSO);
open.setPermissions(Arrays.asList(new String[]{"email", "publish_actions", "user_birthday", "user_hometown"}));
open.setCallback(this);
session.openForPublish(open);
}
publishData defination can also be -
public void publishData(Session session)
{
Bundle params = new Bundle();
params.putByteArray("message", "some message".egtBytes());
params.putByteArray("name", "some name".getBytes());
params.putByteArray("link", "some link".getBytes());
params.putByteArray("description", "Some description".getBytes());
params.putByteArray("picture", "picture.url".getBytes());
Request postToWall = Request.newRestRequest(session,
"/" + pickedUsersId.get(0) + "/feed", params, HttpMethod.POST);
postToWall.setCallback( new Request.Callback()
{
#Override
public void onCompleted(Response response)
{
// get response
Log.e(TAG, response.toString());
}
});
Request.executeBatchAsync(postToWall);
}
In short, no.
Your activity needs to be notifying the Facebook SDK of lifecycle events in order to properly store state and handle the UI flow to and from the Facebook SDK activities.
UILifecycleHelper is an effort to encapsulate this as much as possible.
You may be able to unclutter your code by having all your activities extend some base class (i.e. FBActivity) that makes all the proper calls to UILifecycleHelper, though this only helps if all your activities are interacting with Facebook in a fairly uniform manner.
here is my code for updating status:
new Session(context);
Session.setActiveSession(session);
Session.openActiveSession(context);
Log.e("session after setted",Session.getActiveSession().toString());
Request request = Request.newMeRequest(Session.getActiveSession(), new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser user, Response response) {
// If the response is successful
if (Session.getActiveSession().isOpened()) {
if (user != null) {
session = Session.getActiveSession();
postFromAlarm();
Log.e("user","not null");
}else{
postFromAlarm();
Log.e("user","null");
}
} else{
postFromAlarm();
Log.e("not open session",Session.getActiveSession().toString());
Log.e("session","not open");
}
}
});
Log.e("request session",request.getSession().toString());
Request.executeBatchAsync(request);
Log.e("session after setted",Session.getActiveSession().toString());
is showing a good and healthy session, which can be used for posting. because in logcat, it is showing that the session is open, accesstoken is good, app_id is also good.
but using this session when i am trying to post, in the onComplete() method, executed these lines:
Log.e("not open session",Session.getActiveSession().toString());
Log.e("session","not open");
and it is showing that:
{Session state:CLOSED, token:null, appId:***************** }
what is wrong? i have tried without new Session(context), but getting the same result. what should i do?
save the session when you create it for first time using
SessionStore.save(mFacebook, getBaseContext());
and also restore the session when same user performs post operation
SessionStore.restore(mFacebook, getBaseContext());
where mFacebook is your Facebook object reference
The title says it all. I'm using a custom button to fetch the user's facebook information (for "sign up" purposes). Yet, I don't want the app to remember the last registered user, neither the currently logged in person via the Facebook native app. I want the Facebook login activity to pop up each time. That is why I want to log out any previous users programmatically.
How can I do that? This is how I do the login:
private void signInWithFacebook() {
SessionTracker sessionTracker = new SessionTracker(getBaseContext(), new StatusCallback()
{
#Override
public void call(Session session, SessionState state, Exception exception) {
}
}, null, false);
String applicationId = Utility.getMetadataApplicationId(getBaseContext());
mCurrentSession = sessionTracker.getSession();
if (mCurrentSession == null || mCurrentSession.getState().isClosed()) {
sessionTracker.setSession(null);
Session session = new Session.Builder(getBaseContext()).setApplicationId(applicationId).build();
Session.setActiveSession(session);
mCurrentSession = session;
}
if (!mCurrentSession.isOpened()) {
Session.OpenRequest openRequest = null;
openRequest = new Session.OpenRequest(RegisterActivity.this);
if (openRequest != null) {
openRequest.setPermissions(null);
openRequest.setLoginBehavior(SessionLoginBehavior.SSO_WITH_FALLBACK);
mCurrentSession.openForRead(openRequest);
}
}else {
Request.executeMeRequestAsync(mCurrentSession, new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser user, Response response) {
fillProfileWithFacebook( user );
}
});
}
}
Ideally, I would make a call at the beginning of this method to log out any previous users.
Update for latest SDK:
Now #zeuter's answer is correct for Facebook SDK v4.7+:
LoginManager.getInstance().logOut();
Original answer:
Please do not use SessionTracker. It is an internal (package private) class, and is not meant to be consumed as part of the public API. As such, its API may change at any time without any backwards compatibility guarantees. You should be able to get rid of all instances of SessionTracker in your code, and just use the active session instead.
To answer your question, if you don't want to keep any session data, simply call closeAndClearTokenInformation when your app closes.
This method will help you to logout from facebook programmatically in android
/**
* Logout From Facebook
*/
public static void callFacebookLogout(Context context) {
Session session = Session.getActiveSession();
if (session != null) {
if (!session.isClosed()) {
session.closeAndClearTokenInformation();
//clear your preferences if saved
}
} else {
session = new Session(context);
Session.setActiveSession(session);
session.closeAndClearTokenInformation();
//clear your preferences if saved
}
}
Since Facebook's Android SDK v4.0 (see changelog) you need to execute the following:
LoginManager.getInstance().logOut();
Here is snippet that allowed me to log out programmatically from facebook. Let me know if you see anything that I might need to improve.
private void logout(){
// clear any user information
mApp.clearUserPrefs();
// find the active session which can only be facebook in my app
Session session = Session.getActiveSession();
// run the closeAndClearTokenInformation which does the following
// DOCS : Closes the local in-memory Session object and clears any persistent
// cache related to the Session.
session.closeAndClearTokenInformation();
// return the user to the login screen
startActivity(new Intent(getApplicationContext(), LoginActivity.class));
// make sure the user can not access the page after he/she is logged out
// clear the activity stack
finish();
}
Since Facebook's Android SDK v4.0 you need to execute the following:
LoginManager.getInstance().logOut();
This is not sufficient. This will simply clear cached access token and profile so that AccessToken.getCurrentAccessToken() and Profile.getCurrentProfile() will now become null.
To completely logout you need to revoke permissions and then call LoginManager.getInstance().logOut();. To revoke permission execute following graph API -
GraphRequest delPermRequest = new GraphRequest(AccessToken.getCurrentAccessToken(), "/{user-id}/permissions/", null, HttpMethod.DELETE, new GraphRequest.Callback() {
#Override
public void onCompleted(GraphResponse graphResponse) {
if(graphResponse!=null){
FacebookRequestError error =graphResponse.getError();
if(error!=null){
Log.e(TAG, error.toString());
}else {
finish();
}
}
}
});
Log.d(TAG,"Executing revoke permissions with graph path" + delPermRequest.getGraphPath());
delPermRequest.executeAsync();
Session class has been removed on SDK 4.0. The login magement is done through the class LoginManager. So:
mLoginManager = LoginManager.getInstance();
mLoginManager.logOut();
As the reference Upgrading to SDK 4.0 says:
Session Removed - AccessToken, LoginManager and CallbackManager classes supercede and replace functionality in the Session class.
Yup, As #luizfelippe mentioned Session class has been removed since SDK 4.0. We need to use LoginManager.
I just looked into LoginButton class for logout. They are making this kind of check. They logs out only if accessToken is not null. So, I think its better to have this in our code too..
AccessToken accessToken = AccessToken.getCurrentAccessToken();
if(accessToken != null){
LoginManager.getInstance().logOut();
}
private Session.StatusCallback statusCallback = new SessionStatusCallback();
logout.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Session.openActiveSession(this, true, statusCallback);
}
});
private class SessionStatusCallback implements Session.StatusCallback {
#Override
public void call(Session session, SessionState state,
Exception exception) {
session.closeAndClearTokenInformation();
}
}
Facebook provides two ways to login and logout from an account. One is to use LoginButton and the other is to use LoginManager. LoginButton is just a button which on clicked, the logging in is accomplished. On the other side LoginManager does this on its own. In your case you have use LoginManager to logout automatically.
LoginManager.getInstance().logout() does this work for you.