How to revoke all Facebook permissions using Android SDK? - android

I'm having a problem revoking Facebook permissions using the Android SDK.
There's a case in my app where I want to revoke all permissions. According to the Facebook documentation, you can use AsyncFacebookRunner to do this, and "if you don't specify a permission then this will de-authorize the application completely."
I'm currently doing it like this:
String method = "DELETE";
Bundle params = new Bundle();
params.putString("permission", "");
mAsyncRunner.request("/me/permissions", params, method, new RequestListener()
{ ... }, null);
using the request signature like this:
void request(String graphPath, Bundle parameters, final String httpMethod,
RequestListener listener, final Object state)
The onComplete() callback function seems to come back OK, but doesn't appear to have de-authorized the access token. I'm inferring this because the next time I call facebook.authorize(), it works without pushing the user to the Facebook login page.
Any ideas what I need to change to completely de-authorize an access token? Or is there a different/better way to do this? Many thanks!

For anybody looking to do this in later versions of the SDK/Graph API - It appears the correct way to do this now is as shown here https://developers.facebook.com/docs/graph-api/reference/user/permissions/
new Request(
session,
"/me/permissions/{permission-to-revoke}",
null,
HttpMethod.DELETE,
new Request.Callback() {
public void onCompleted(Response response) {
/* handle the result */
}
}
).executeAsync();
Leaving the /{permission-to-revoke} off of the second parameter will revoke all the permissions

You can delete the entire application (not only permissions) from users Facebook account using latest SDK (mine is 4.1.1)
void deleteFacebookApplication(){
new GraphRequest(AccessToken.getCurrentAccessToken(), "/me/permissions", null, HttpMethod.DELETE, new GraphRequest.Callback() {
#Override
public void onCompleted(GraphResponse response) {
boolean isSuccess = false;
try {
isSuccess = response.getJSONObject().getBoolean("success");
} catch (JSONException e) {
e.printStackTrace();
}
if (isSuccess && response.getError()==null){
// Application deleted from Facebook account
}
}
}).executeAsync();
}

It appears from this post: Facebook deauthorize my app and others that it's not possible to deauthorize an application programmatically. Unfortunately, the call above returns successfully to onCreate() but does nothing to deauth/delete the app for the user.
Bottom line: It looks like the only way to deauth an app is for the user to do it directly in Facebook. If anyone knows differently, please say so - but otherwise, don't waste your time trying! Thanks.

I am using the code suggested in the question and it completely de-authorized my test application. Tested it several times and it worked every each one of them.
This is also the code suggested in the official facebook documentation here: https://developers.facebook.com/docs/mobile/android/build/ - Step 7

Related

Facebook for Android FacebookDialog.ShareDialogBuilder doesn't recognize URI returned by Request.newUploadStagingResourceWithImageRequest

I am relatively new to android and facebook so please bear with me. IMPORTANT NOTE: Wherever I type h.. that means http://www. I'm not intending to post links here but I have to in order to explain this (my permission only allows 2 links) so please bear with me.
This app does a facebook post using the FacebookDialog.ShareDialogBuilder. This all works great now IF the image for the post using the .setPicture method is given a static hardcoded URL h..example.com/share_name/image_name.png. In that case the post works and the picture shows up on the post and everything is fine.
However, the image sent to the post is dynamically created by the app. Therefore I am sending the image to facebook's staging area which also works fine.
The Request.newUploadStagingResourceWithImageRequest returns a response that has the JSON encoded URI of the location of
the image in facebook's staging area.
The problem is that the FacebookDialog.ShareDialogBuilder doesn't like that URI location. Somehow it's not formed properly or something or I'm just doing something wrong.
Here are the details and what I've tried:
1) uriMine, the location where the image gets stored, as it is originally returned from facebook's staging resource upload call is:
"fbstaging://graph.facebook.com/staging_resources/MDE4NTY0NzE4MDQ0MTUwNjA6MTM5ODI2Nzc3Ng==". I don't know what the protocol "fbstaging:" is all about (I searched and searched online but nothing) but I
ran the app as is with that at first. The result was, well, unpredictable results apparently, as it got stuck in a loop (the looper class kept repeating in no particular pattern). It would show the post screen but you couldn't type in a message as it would lock up, close, repeat etc...
2) After getting a little education online about well formed URL's I replaced the fbstaging:// with h.. and thus changed the uriMine variable to the following:
h..graph.facebook.com/staging_resources/MDE4NTY0NzE4MDQ0MTUwNjA6MTM5ODI2Nzc3Ng==
This solved the endless loop problem (made the post work fine) except it would not show any image.
3) To see if it would work with any old normal URL of the form h..blablabla.com/image_resource I hardcoded URL's of a few images online and it worked fine, and showed the images.
4) Ok, I promise, I'm all most done (whew!). So, where it stands right now is:
a) passing uriMine as fbstaging://graph.facebook.com/staging_resources/etc etc
makes it freak out.
b) sending a normal URL of an online resource works fine (formed as a browser forms it, by the way).
c) prepending http://www. instead of the fbstaging:// makes the post work but facebook doesn't show the image, as if it can't find it.
By the way, going directly to the above by copy/pasting it into a browser gets redirected to the following:
h..dnsrsearch.com/index.php?origURL=http%3A//www.graph.facebook.com/staging_resources/MDE4NTY0NzE4MDQ0MTUwNjA6MTM5ODI2Nzc3Ng%3D%3D&r=
as apparently it can't find it.
SO:
What is it about that URI that is wrong or what am I missing? Please help.
Thank you very much for your time and patience reading this.
public class FacebookActivity extends Activity {
// initialize the global object to enable passing of activity to facebook dialog
public GlobalClass globalObject = new GlobalClass();
private UiLifecycleHelper uiHelper; // for Facebook...to mimic android's activity life cycle
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
uiHelper = new UiLifecycleHelper(this, null);
uiHelper.onCreate(savedInstanceState);
// set the calling activity...to pass to Face book
globalObject.setCurrentActivity(this);
// start Facebook Login
Session currentSession = new Session(this);
currentSession = Session.openActiveSession(this, true, new Session.StatusCallback() {
// callback when session changes state
#Override
public void call(final Session session, SessionState state, Exception exception) {
// this callback should fire multiple times, be sure to get the right one i.e. session.isOpened()
if (session.isOpened()) {
// make request to the /me API
Request.newMeRequest(session, new Request.GraphUserCallback() {
// callback after Graph API response with user object
#Override
public void onCompleted(GraphUser user, Response response) {
if (user != null) {
Bitmap bitmap = takeScreenshot();
Request imageRequest = Request.newUploadStagingResourceWithImageRequest(Session.getActiveSession(), bitmap, new Request.Callback() {
#Override
public void onCompleted(Response response) {
String uriMine = "";
JSONObject data = response.getGraphObject().getInnerJSONObject();
try {
uriMine = data.getString("uri");
uriMine = "http://www." + uriMine.substring(12); // strip off the "fbstaging://" from the uri
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (FacebookDialog.canPresentShareDialog(getApplicationContext(),
FacebookDialog.ShareDialogFeature.SHARE_DIALOG))
{
FacebookDialog shareDialog = new FacebookDialog.ShareDialogBuilder(globalObject.getCurrentActivity())
.setLink("https://play.google.com/store")
.setPicture(uriMine)
.setRequestCode(NativeProtocol.DIALOG_REQUEST_CODE)
.setApplicationName("This is the App Name")
.setName("This is the name")
.setDescription("This is the description")
.setCaption("This is the caption")
.build();
uiHelper.trackPendingDialogCall(shareDialog.present());
}
else
{
Toast.makeText(globalObject.getCurrentActivity(), "Please install the Facebook App first from Google Play.", Toast.LENGTH_LONG).show();
}
}
});
imageRequest.executeAsync();
}
}
}).executeAsync();
}
}
});
}
The staging resource endpoint is only used for staging binary data for open graph objects or actions, and is not meant for the regular link shares. See the documentation here: https://developers.facebook.com/docs/reference/android/current/class/Request/#newUploadStagingResourceWithImageRequest
In this case, you can either use the PhotoShareDialogBuilder (but then you can't add a link), or you can upload the image to your own hosting service, and use an http/https url in the setPicture method.

how to get a list of all user friends (not only who use the app)?

in android application :
i want to get a list of all friends of the person who login to my app , not only those who use the app ?
i use the following :
private void makeMeRequest(final Session session) {
// Make an API call to get user data and define a
// new callback to handle the response.
RequestAsyncTask request =new Request( session,
"/me/friends",
null,
HttpMethod.GET,
new Request.Callback() {
#Override
public void onCompleted(Response response) {
// TODO Auto-generated method stub
Log.e(LOG_TAG,"Members: " + response.toString());
}
}).executeAsync();
}
but the response returns empty list , although there are some apps that show person's friend list ,what can i do ??
It is not possible to get ALL friends with v2.0+, only with Apps created before end of April 2014 by using v1.0 of the Graph API. And it will only work until end of April 2015. See changelog for more information about the versions: https://developers.facebook.com/docs/apps/changelog
There is also invitable_friends and taggable_friends though, but they are reserved for Apps on facebook.com:
https://developers.facebook.com/docs/graph-api/reference/v2.1/user/invitable_friends
https://developers.facebook.com/docs/graph-api/reference/v2.1/user/taggable_friends
This may also be interesting for inviting friends: https://developers.facebook.com/docs/games/requests/v2.1

HelloFacebookSample wall post request doesn't work after using Friendpicker

Using facebook SDK 3.5 and Android4 device (samsung xcover2).
I'm trying to pick friends and post to my wall.
Preconditions:
FBAndroid-3.5.apk installed from the SDK, launched and authenticated
HellofacebookSample.apk: changed canPresentShareDialog flag to force use Request instead of FacebookDialog.ShareDialogBuilder()
// canPresentShareDialog = FacebookDialog.canPresentShareDialog()
canPresentShareDialog = false;
Steps:
( I need it this way since I want to restrict allowed viewers)
Open sample app
click "log in with facebook"
=>user logged in
pick some friends
post status update
=> request.executeAsync();
Result:
Request is not completed. Entry is not posted. No diagnostic messages.
However, it usually works the other way round: First post and then pick friends.
And depending on unknown variables (outside temp, solar wind?) above main use case might succeed.
If the sample app is in such mood, force stopping it and restarting sometimes helps. If I run without FBAndroid-3.5.apk, use case usually is much more unreliable.
I just want a zero state from where I can run the use case succesfully.
FacebookDialog.ShareDialogBuilder() seems to be working. If it supported viewer restriction, I would use it instead.
CODE
Here is the code snippet of the sample application. (I have specifically canPresentShareDialog=false, which could also be done by uninstalling the facebook native apk).
private void postStatusUpdate() {
if (canPresentShareDialog) {
FacebookDialog shareDialog = createShareDialogBuilder().build();
uiHelper.trackPendingDialogCall(shareDialog.present());
} else if (user != null && hasPublishPermission()) {
final String message = getString(R.string.status_update, user.getFirstName(), (new Date().toString()));
Request request = Request
.newStatusUpdateRequest(Session.getActiveSession(), message, place, tags, new Request.Callback() {
#Override
public void onCompleted(Response response) {
showPublishResult(message, response.getGraphObject(), response.getError());
}
});
Log.i("MYAPP", "request executeAsync() ");
request.executeAsync();
} else {
pendingAction = PendingAction.POST_STATUS_UPDATE;
}
}
Full Activity can be seen at:
https://github.com/facebook/facebook-android-sdk/blob/master/samples/HelloFacebookSample/src/com/facebook/samples/hellofacebook/HelloFacebookSampleActivity.java
It seems that my restrictive firewall caused this. S**t.

Facebook login fails on some devices

I have implemented the Facebook login and it works fine on some devices/AVDs. My development device is a Gingerbread phone, but testing it with a 4.1.1 device, it simply does not log in. After pressing the facebook button, it shows a blank screen (trying to connect Facebook), and after 1-2 seconds it comes back to the home screen. Also, no errors are toasted or displayed in the Logcat. Oh, and the Facebook application is installed in the device... Any ideas?
UPDATE:
I enabled logging as suggested by Mark Venzke and using this procedure, and I got this warning (twice) on every login attempt (note: testing with a HTC One S phone):
07-05 20:14:50.582: W/PackageManager(605): Unable to load service info ResolveInfo{4171dbf0 com.htc.socialnetwork.facebook.remote.FacebookSyncService p=0 o=0 m=0x108000}
Note the com.htc.socialnetwork.facebook.remote.FacebookSyncService line, so is there any extra step needed for HTC devices?
Also, I'm attaching the code where the login is performed:
private void onSessionStateChange(Session session, SessionState state, Exception exception) {
if (isResumed) {
FragmentManager manager = getSupportFragmentManager();
int backStackSize = manager.getBackStackEntryCount();
for (int i = 0; i < backStackSize; i++) {
manager.popBackStack();
}
com.facebook.Settings.addLoggingBehavior(LoggingBehavior.REQUESTS);
if (state.isOpened()) {
Bundle params = new Bundle();
params.putString("fields", "id");
params.putString("limit", "1");
Request request = new Request(Session.getActiveSession(), "me", params, HttpMethod.GET, new Callback()
{
#Override
public void onCompleted(Response response)
{
if (response != null)
{
Log.d("AuthGraphResponse", response.toString());
long id;
try {
id = response.getGraphObject().getInnerJSONObject().getLong("id");
app.setFacebookId(id);
Log.d("UserID", Long.valueOf(id).toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
}
});
RequestAsyncTask task = new RequestAsyncTask(request);
task.execute();
showFragment(AUTH, false);
} else if (state.isClosed()) {
showFragment(UNAUTH, false);
}
}
}
UPDATE 2:
Is it possible that HTC renames the package name of the default Facebook application in all the devices (or some of them, whatever) to com.htc.socialnetwork.facebook (instead of com.facebook.katana) and it leads to this conflict? I don't really think that uninstalling the default app and installing Facebook from Google Play is an acceptable solution (also, I think default apps cannot be uninstalled).
UPDATE 3:
Not solved yet. 19 hours to award the 100 reputation bounty!
UPDATE 4:
Another interesting line of the LogCat:
07-15 10:55:51.718: E/chromium(30475): external/chromium/net/disk_cache/stat_hub.cc:216: [0715/105551:ERROR:stat_hub.cc(216)] StatHub::Init - App com.facebook.katana isn't supported.
There is certainly a conflict between your stock app and the SDK. So if you don't want to uninnstall the stock HTC app and still use the SDK 3.0 I think your best bet without modying the source code of the sdk would be to disable SSO and login only through webview.
This can easily be done by adding the SessionLoginBehavior.SUPRESS_SSO everytime you try to open a new session. Here is a sample I changed from the SessionLoginSample (LoginUsingActivityActivity) from the Facebook SDK to show you what to do :
#Override
public void onCreate(Bundle savedInstanceState) {
...
Session session = Session.getActiveSession();
if (session == null) {
if (savedInstanceState != null) {
session = Session.restoreSession(this, null, statusCallback, savedInstanceState);
}
if (session == null) {
session = new Session(this);
}
Session.setActiveSession(session);
//add the check, for if session is opened
if (session.getState().equals(SessionState.CREATED_TOKEN_LOADED) || !session.getState().isOpened()) {
//Add the suppress SSO behavior to force webview auth dialog to popup
session.openForRead(new Session.OpenRequest(this).setCallback(statusCallback).setLoginBehavior(SessionLoginBehavior.SUPPRESS_SSO));
}
}
...
}
//then put your code in the statusCallback method or keep it in the session state change listener
Otherwise if you don't mind changing the facebook sdk code, you should check this out
Shirley Facebook login is not broken on all 4.1.1 devices, so it is something with your implementation.
Are you sure the Key Hash is the same on that device as what you have configured on developer.facebook.com? If you used a different dev key, or it was installed by a third-party store, it's possible the key hashes don't match.
Turn on debug logging in the Facebook SDK source code and rebuild it. It is generally off by default for security reasons. Depending on your version of the SDK, it may be in Util.java or some other location, and may be a variable called 'ENABLE_LOG'.
I think facebook login error mostly occur so to solve this issue you follow there tutorial step by step again with patience.
Other wise its very difficult to solve your problem here. So you can refer this link.
http://developers.facebook.com/android/
I hope you will success.
There isn't enough info in your question. so, I'm making a few guesses here.
1)First look into Mike Venzke's answer.
2) If this doesn't work then try this:
You need to sign in on you device using SSO (Single Sign On). So here are the steps you can take.
delete the build. reinstall it. and when asked for permissions from your device, allow them.
If you aren't taken back to your app then you need to add these to your manifest file:
<activity
android:name="com.facebook.LoginActivity"
android:label="#string/app_name" >
</activity>
<meta-data android:value="#string/app_id" android:name="com.facebook.sdk.ApplicationId"/>
where app_name and app_id are your respective app Id and app name on your Facebook app page.
Have you added these btw?
you need these permission as well
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
if you post some more info I might be guess the issue.
I think the problem with your Facebook android app in device. So first uninstall the facebook android app from device and check that facebook login working properly or not.
Since Honeycomb you are not able to make internet calls on the main thread, try using an Android AsyncTask or creating a new thread yourself.
http://developer.android.com/reference/android/os/AsyncTask.html
I got this error when using a device with an old version of facebook. Removing facebook completely, or updating the facebook app fixed it.
I'm pretty sure this happens because Facebook for Android used to be just a wrapped WebView of the mobile site.
Also note that some devices (my Incredible 4G LTE) will reinstall the old (webview) version of facebook if you try to remove it.
connect device to eclipse to see logcat. if log cat not running open cmd prompt in windows and run adb restart, (set the adb path first). then you can see logcat running. now open your app and click facebook login button. you can get the correct hash key in yellow colour in log cat. put that key on facebook and now facebook login will work on every device. thanks.
List<String> permissions = new ArrayList<String>();
permissions.add("email");
//start Facebook session
openActiveSession(this, true, new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
if (session.isOpened()) {
//make request to the /me API
Request.executeMeRequestAsync(session, new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser user, Response response) {
if (user != null) {
String firstName = user.getFirstName();
String lastName = user.getLastName();
String id = user.getId();
String email=null;
try {
email = user.getProperty("email").toString();
} catch (Exception e) {
// TODO: handle exception
}
String gender = (String) user.getProperty("gender");
String birthday = user.getBirthday();
//welcome.setText("Hello \n" + firstName+"\n"+lastName+"\n"+email+"\n"+gender+"\n"+birthday+"!");
if(firstName!=null)
{
SharedPreferences.Editor editor = settings.edit();
editor.putString("fligin", "1");
editor.putString("firstName", firstName);
editor.putString("lastName", lastName);
editor.putString("email", email);
editor.putString("gender", gender);
editor.putString("birthday", birthday);
editor.commit();
Intent intent=new Intent(getApplicationContext(), RegistrationOneActivity.class);
startActivity(intent);
//overridePendingTransition( R.anim.slide_in_up, R.anim.slide_out_up );
finish();
}
else {
Toast.makeText(getApplicationContext(),"Person information is null", Toast.LENGTH_SHORT).show();
finish();
}
}
}
});
}
}
}, permissions);
Try inserting this line where you define your login button in the java source code
LoginButton fb_button = (LoginButton)findViewById(//your resource id);
fb_button.setLoginBehavior(SessionLoginBehavior.SUPPRESS_SSO);

Android Facebook API - sending an app invite to a friend

I managed to login to Facebook / get permissions.. retrieve friends data, names/ids etc.
The issue is that I cannot send an app invite to my friends. I'd like to send the invite without a dialog to a single person. But it seems that's wishful thinking. Now I'd settle for anything. It seems nothing will do the job!
I tried the dialog provided by Facebook Graph API but it tells me that the display is not supported (error 103). Also tried the fix modifying the url inside the Facebook SDK to not point to the mobile version and set the display as popup. Still no good (same error);
Any thoughts on this?
Thank you in advance.
(BTW, it seems to me like Facebook is a very unreliable service!)
This code will bring up an app invite dialog (and I don't know how to send an invite without a dialog). Note: assumes that facebook has been successfully authorized/logged in:
Facebook facebook = new Facebook( MY_APP_ID );
...
Bundle parameters = new Bundle();
parameters.putString( "message", "Check this out!" );
facebook.dialog( activity, "apprequests", parameters,
new Facebook.DialogListener()
{
public void onComplete() { ... }
public void onFacebookError( FacebookError e ) { ... }
public void onError(DialogError e) { ... }
public void onCancel() { ... }
} );

Categories

Resources