facebook android sdk sharedialog callback is always success - java

Using Facebook android sdk version 4.1.1, I managed to open a shareDialog and share a content using the below code:
if (ShareDialog.canShow(ShareLinkContent.class)) {
ShareLinkContent linkContent = new ShareLinkContent.Builder()
.setContentTitle("Hello Facebook")
.setContentDescription(
"The 'Hello Facebook' sample showcases simple Facebook integration")
.setContentUrl(Uri.parse("http://developers.facebook.com/android"))
.build();
shareDialog.show(linkContent);
shareDialog.registerCallback(callbackManager, new FacebookCallback<Sharer.Result>() {
#Override
public void onSuccess(Result result) {
//always gets called
}
#Override
public void onCancel() {
//do something
}
#Override
public void onError(FacebookException error) {
// TODO Auto-generated method stub
}
});
}
and the callback on ActivityResult code:
#Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
callbackManager.onActivityResult(requestCode, resultCode, data);
}
the resultCode is always -1 which is RESULT_OK regardless whether user pressed back or post button of the dialog. and the callback's onSuccess function is always called and the postId is always null regardless whether the content is posted or cancelled. Anyone know why is it acting this way?

According to THIS which is a reported bug on facebook developers bug section, this is known and according to the answers given, it seems it's in the design that any form of closing the dialog is considered as success.

I'm using SDK 7.1.0 and this no longer appears to be an issue. Both the native and web share dialogs are calling the correct callback methods.

Related

LinkedIn Authentication not working on Fragment in android

I am creating an app that has the LinkedIn login. I am following this documentation. But when I click on the login button, the app redirected to the LinkedIn app and asking for login. When successful login it redirected to my app. But nothing happens. Nothing happens on onActivityResult also.
Below is my code .Login implemented on fragment
LISessionManager.getInstance(getActivity()).init(getActivity(), buildScope(), new AuthListener() {
#Override
public void onAuthSuccess() {
getLinkedInProfile();
Toast.makeText(getApplicationContext(), "success" , Toast.LENGTH_LONG).show();
}
#Override
public void onAuthError(LIAuthError error) {
Toast.makeText(getApplicationContext(), "failed " + error.toString(), Toast.LENGTH_LONG).show();
}
}, true);
//
private static Scope buildScope() {
return Scope.build(Scope.R_BASICPROFILE, Scope.R_EMAILADDRESS);
}
and onActivityResult as follows:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
LISessionManager.getInstance(getActivity()).onActivityResult(getActivity(), requestCode, resultCode, data);
}
Already added hash and package name on LinkedIn developer console. Did I am missing anything? Please help
It is found that the onActivityResult for LinkedIn sdk triggres on the parent activity rather than fragment onActivityResult. So you have to write following code into your parent Activity's onActivityResult for triggering fragment's onActivityResult.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
yourFragment.onActivityResult(requestCode, resultCode, data);
}
Try Log to ensure whether function is called.

GoogleApiClient onConnected callback doesn't get called correctly

I'm trying to use the DriveApi in order to create some folders and upload a text file with some data for a user.
I've tried implementing the quick-start guide from (link), but it has a few fundamental issues:
The api gets connected at onResume so the user will get prompted to give access to the app immediately after he opens the app which is confusing and scary.
If you deny or press the back button at the consent screen, the onResume method will get called again and the consent screen will be shown one more time, leading to an infinite loop.
I would rather like to connect the api when the user actually needs to store data so that will make more sense to the user. I tried doing it like this:
ResultCallback<DriveFolder.DriveFolderResult> folderCreatedCallback = new
ResultCallback<DriveFolder.DriveFolderResult>() {
#Override
public void onResult(#NonNull DriveFolder.DriveFolderResult result) {
clearCurrentAction();
if (!result.getStatus().isSuccess()) {
Log.e(TAG, "Error while trying to create the folder");
return;
}
Log.d(TAG, "Created a folder: " + result.getDriveFolder().getDriveId());
}
};
public DriveApiHelper(GoogleApiClient mGoogleApiClient) {
this.mGoogleApiClient = mGoogleApiClient;
}
public void createBackupsFolder() {
currentAction = DriveActions.CREATING_FOLDER;
if (mGoogleApiClient.isConnected()) {
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle("test").build();
Drive.DriveApi.getRootFolder(mGoogleApiClient).createFolder(
mGoogleApiClient, changeSet).setResultCallback(folderCreatedCallback);
} else {
mGoogleApiClient.connect();
}
}
and this is how my onResume and onConnected methods look like:
#Override
protected void onResume() {
super.onResume();
if (mGoogleApiClient == null) {
// Create the API client and bind it to an instance variable.
// We use this instance as the callback for connection and connection
// failures.
// Since no account name is passed, the user is prompted to choose.
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mDriveHelper = new DriveApiHelper(mGoogleApiClient);
}
//Log.d(TAG, mDriveHelper.getCurrentAction() + "");
Log.d("test", "Connected " + mGoogleApiClient.isConnected());
}
#Override
public void onConnected(Bundle connectionHint) {
Log.i(TAG, "API client connected.");
switch (mDriveHelper.getCurrentAction()) { //resume the last action
case CREATING_FOLDER:
mDriveHelper.createBackupsFolder();
break;
}
}
I was hoping that keeping a reference of what the user tried to do when the api was asked to connect, I can resume that action after the api successfully connected. This is the closest implementation I've got to fit my needs, but after actually clicking the 'Allow' button from the consent screen none of the api callbacks gets called (onConnected, onConnectionFailed).
I actually need to call the connect method one more time in order to get connected and also fire the onConnected successfully resuming the users' action.
Turns out that I forgot about overriding onActivityResult (it wasn't mentioned in the documentation at that time and I don't know if they included it now)
Just add:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == REQUEST_CODE_RESOLUTION) {
mGoogleApiClient.connect();
}
} else {
if (requestCode == REQUEST_CODE_RESOLUTION) {
mDriveHelper.dismissStatusDialog();
}
}
}

Android - Get result from change default SMS app dialog

I am working on restoring SMS on KITKAT. Referring to this article I have added the things which are required to set my app as default app for SMS. After adding all required things in manifest file I have write the following code:
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
{
mDefaultSmsApp = Telephony.Sms.getDefaultSmsPackage(mContext);
Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, mContext.getPackageName());
mContext.startActivity(intent);
}
The above code shows this dialog but I am unable to get the result from this activity/dialog either user clicked on Yes or No because I want to add listener or get any code which should represent that the user clicked on these buttons.
Thanks.
One way to do this is to fire the Intent with startActivityForResult(), and then check the resultCode in the onActivityResult() method. Please note that I've changed the code in the example to run in an Activity's Context.
private static final int DEF_SMS_REQ = 0;
private String mDefaultSmsApp;
...
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
{
mDefaultSmsApp = Telephony.Sms.getDefaultSmsPackage(this);
if (!getPackageName().equals(mDefaultSmsApp))
{
Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, getPackageName());
startActivityForResult(intent, DEF_SMS_REQ);
}
}
...
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
switch (requestCode)
{
case DEF_SMS_REQ:
boolean isDefault = resultCode == Activity.RESULT_OK;
...
}
}
As mentioned in a comment below, apparently checking the result code is not 100% reliable. A safer check is to simply compare your app's package name to the current default in onActivityResult(). There's no need to check the result code at all, like the answer linked in the comment shows.
String currentDefault = Sms.getDefaultSmsPackage(this);
boolean isDefault = getPackageName().equals(currentDefault);
The way you can react on "yes" button click:
private String mDefSmsPackage;
#Override
public void onCreate(#Nullable Bundle state) {
//...
mDefSmsPackage = Telephony.Sms.getDefaultSmsPackage(getActivity())
}
#Override
public void onResume() {
super.onResume();
String newDefSmsPkg = Telephony.Sms.getDefaultSmsPackage(getActivity());
if (!TextUtils.equals(mDefSmsPackage, newDefSmsPkg)) {
mDefSmsPackage = newDefSmsPkg;
//ON DEF SMS APP CAHNGE...
}
}

Callback for Facebook requestNewPublishPermissions - Android

I'm trying to get publish permissions from my users in my Android app and I'm succeeding but when I get the permission I want a callback to tell me just that. Here is my code:
private void requestPublishPermissions(Session session) {
Log.d("", "Requesting Publish Permissions...");
if (session != null) {
List<String> publishPermissions = Arrays.asList("publish_actions", "publish_stream");
final int REAUTH_ACTIVITY_CODE = 100;
Session.NewPermissionsRequest reauthRequest = new Session.NewPermissionsRequest(this, publishPermissions).setRequestCode(REAUTH_ACTIVITY_CODE);
reauthRequest.setLoginBehavior(SessionLoginBehavior.SUPPRESS_SSO);
session.requestNewPublishPermissions(reauthRequest);
}
}
Does the session.requestNewPublishPermissions(reauthRequest); have a callback or something that tells me that the permission was accepted?
Thanks for any input
I don't know of a callback for that request, but there's an easy way to get your desired result.
Just add a conditional to the onSessionStateChanged() callback. If you check for the permission in that method by using session.getPermissions().contains("xxx"), you should be able to check in there. Any time the session state changes, it'll call that method, and I think that includes updating permissions.
You can manually add callbacks to your FB session.
Session.getActiveSession().addCallback(new StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
if (session.getPermissions().contains("publish_actions")) {
//do stuff
}
}
});
Add the StatusCallback to your session.
private Session.StatusCallback statusCallback = new SessionStatusCallback();
private class SessionStatusCallback implements Session.StatusCallback {
#Override
public void call(final Session session, SessionState state, Exception exception) {
if (session.isOpened()) {
switch (state) {
case OPENED_TOKEN_UPDATED:
// Returns here after you request publish permissions
// So call your publishing actions here
break;
}
}
}
}
Implement onActivityResult() which glues things together.
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
}

Android Facebook-Connect button needs to be clicked two times

since hours I am trying to figure out why my facebook-connect is not working properly. I always have to click it two times.. the first time I click it I see that the facbeook dialog is opening but its not calling any kind of callback so my Login-Activity is just "resuming".
public void onClick_fbIcon(View v) {
if(!buttonsEnabled)
return;
buttonsEnabled = false;
tryFacebookConnect();
}
#SuppressWarnings("deprecation")
private void tryFacebookConnect() {
Log.d("debug", "start fbc");
doingFacebooklogin = true;
facebook.authorize(this, new DialogListener() {
public void onComplete(Bundle values) {
end();
toast("Complete");
Log.d("debug", "#0");
// .. continue with main code
}
public void onFacebookError(FacebookError error) {
end();
Log.d("debug", "#1");
}
public void onError(DialogError e) {
end();
Log.d("debug", "#2");
}
public void onCancel() {
end();
Log.d("debug", "#3");
}
private void end() {
Log.d("debug", "fbc complete");
doingFacebooklogin = false;
}
});
}
The first click I only get "start fbc" but nothing after that, so I guess that no callback method is called.
I found out that when the facebook-connect is not working the first time, "onResume is called". The next time onActivityResult is called.
#SuppressWarnings("deprecation")
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d("debug", "Main: onActivityResult");
super.onActivityResult(requestCode, resultCode, data);
facebook.authorizeCallback(requestCode, resultCode, data);
}
My login activity is an intent started by my main activity that is specifing if a login is needed at all:
Intent intent = new Intent(this, Login.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
Sometimes I can see the following error:
11-22 10:23:39.684: D/Facebook-publish(7317): Can NOT get FbInjector instance! Probably because this method was called in ContentProvider's onCreate.
Please take a look at this Tutorial. I just Follow this and I make it all works perfectly.
Hope that it will help you too.
http://www.youtube.com/watch?v=xndi6s9Tn_U
I don't know why but the problem is obviously part of the facebook-sdk. I found out that this problem does not occur if I have no facebook-app installed on my device. So I changed my code like this:
facebook.authorize(a, new String[] { }, **Facebook.FORCE_DIALOG_AUTH**, new DialogListener() {
...

Categories