0

I followed this tutorial to implement facebook into my application. All I want is to post a text on the user's wall. I imported all the necessary files like RyanM said here.

Problem: when I do not provide an app id, facebook starts loading, then says an error occurred. Then I click OKAY in the top-right corner and facebook loads. Why?

There is another button for posting on wall. I do not want any buttons for this, where should I put the postOnWall("Testing from Android"); line? I want the post to appear on the users wall right after they log in.

When I provide my app id, facebook starts loading then exits. Why?

PostActivity:

package com.bfarago.af2;

import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

public class PostActivity extends FacebookActivity {
    /** Called when the activity is first created. */
    private TextView txtUserName;
    private ProgressBar pbLogin;
    private Button btnLogin;
    private Button btnWall;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        txtUserName = (TextView) findViewById(R.id.textFacebook);
        pbLogin = (ProgressBar) findViewById(R.id.progressLogin);
        btnLogin = (Button) findViewById(R.id.buttonLogin);
        btnWall = (Button) findViewById(R.id.buttonWall);

        btnLogin.setOnClickListener(listener);
        btnWall.setOnClickListener(listener1);
    }

    OnClickListener listener = new OnClickListener(){
        @Override
        public void onClick(View v) {
            // pbLogin.setVisibility(ProgressBar.VISIBLE);
            setConnection();
            getID(txtUserName, pbLogin);
            postOnWall("Testing from Android");
        }
    };

    OnClickListener listener1 = new OnClickListener(){
        @Override
        public void onClick(View v) {
        // postOnWall("Testing from Android");
        }
    };
}

FacebookActivity:

package com.bfarago.af2;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.facebook.android.AsyncFacebookRunner;
import com.facebook.android.AsyncFacebookRunner.RequestListener;
import com.facebook.android.DialogError;
import com.facebook.android.Facebook;
import com.facebook.android.Facebook.DialogListener;
import com.facebook.android.FacebookError;
import com.facebook.android.Util;

public abstract class FacebookActivity extends Activity {
    public static final String TAG = "FACEBOOK";
    private Facebook mFacebook;
    public static final String APP_ID = "394196520626466"; //the API Key for your Facebook APPs
    private AsyncFacebookRunner mAsyncRunner;
    private static final String[] PERMS = new String[] { "publish_stream" };
    private SharedPreferences sharedPrefs;
    private Context mContext;

    private TextView username;
    private ProgressBar pb;

    public void setConnection() {
            mContext = this;
            mFacebook = new Facebook(APP_ID);
            mAsyncRunner = new AsyncFacebookRunner(mFacebook);
    }

    public void getID(TextView txtUserName, ProgressBar progbar) {
            username = txtUserName;
            pb = progbar;
            if (isSession()) {
                    Log.d(TAG, "sessionValid");
                    mAsyncRunner.request("me", new IDRequestListener());
            } else {
                    // no logged in, so relogin
                    Log.d(TAG, "sessionNOTValid, relogin");
                    mFacebook.authorize(this, PERMS, new LoginDialogListener());
            }
    }



    public boolean isSession() {
            sharedPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
            String access_token = sharedPrefs.getString("access_token", "x");
            Long expires = sharedPrefs.getLong("access_expires", -1);
            Log.d(TAG, access_token);

            if (access_token != null && expires != -1) {
                    mFacebook.setAccessToken(access_token);
                    mFacebook.setAccessExpires(expires);
            }
            return mFacebook.isSessionValid();
    }

    private class LoginDialogListener implements DialogListener {

            @Override
            public void onComplete(Bundle values) {
                    Log.d(TAG, "LoginONComplete");
                    String token = mFacebook.getAccessToken();
                    long token_expires = mFacebook.getAccessExpires();
                    Log.d(TAG, "AccessToken: " + token);
                    Log.d(TAG, "AccessExpires: " + token_expires);
                    sharedPrefs = PreferenceManager
                                    .getDefaultSharedPreferences(mContext);
                    sharedPrefs.edit().putLong("access_expires", token_expires)
                                    .commit();
                    sharedPrefs.edit().putString("access_token", token).commit();
                    mAsyncRunner.request("me", new IDRequestListener());
            }

            @Override
            public void onFacebookError(FacebookError e) {
                    Log.d(TAG, "FacebookError: " + e.getMessage());
            }

            @Override
            public void onError(DialogError e) {
                    Log.d(TAG, "Error: " + e.getMessage());
            }

            @Override
            public void onCancel() {
                    Log.d(TAG, "OnCancel");
            }
    }

    private class IDRequestListener implements RequestListener {

            @Override
            public void onComplete(String response, Object state) {
                    try {
                            Log.d(TAG, "IDRequestONComplete");
                            Log.d(TAG, "Response: " + response.toString());
                            JSONObject json = Util.parseJson(response);

                            final String id = json.getString("id");
                            final String name = json.getString("name");
                            FacebookActivity.this.runOnUiThread(new Runnable() {
                                    public void run() {
                                            username.setText("Welcome: " + name+"\n ID: "+id);
                                            pb.setVisibility(ProgressBar.GONE);

                                    }
                            });
                    } catch (JSONException e) {
                            Log.d(TAG, "JSONException: " + e.getMessage());
                    } catch (FacebookError e) {
                            Log.d(TAG, "FacebookError: " + e.getMessage());
                    }
            }

            @Override
            public void onIOException(IOException e, Object state) {
                    Log.d(TAG, "IOException: " + e.getMessage());
            }

            @Override
            public void onFileNotFoundException(FileNotFoundException e,
                            Object state) {
                    Log.d(TAG, "FileNotFoundException: " + e.getMessage());
            }

            @Override
            public void onMalformedURLException(MalformedURLException e,
                            Object state) {
                    Log.d(TAG, "MalformedURLException: " + e.getMessage());
            }

            @Override
            public void onFacebookError(FacebookError e, Object state) {
                    Log.d(TAG, "FacebookError: " + e.getMessage());
            }

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            mFacebook.authorizeCallback(requestCode, resultCode, data);
    }

    public void postOnWall(String msg) {
        Log.d("Tests graph API %%%%%$$$$%%%", msg);
         try {
                String response = mFacebook.request("me");
                Bundle parameters = new Bundle();
                parameters.putString("message", msg);
                parameters.putString("description", "test test test");
                response = mFacebook.request("me/feed", parameters, 
                        "POST");
                Log.d("Tests", "got response: " + response);
                if (response == null || response.equals("") || 
                        response.equals("false")) {
                   Log.v("Error", "Blank response");
                }
         } catch(Exception e) {
             e.printStackTrace();
         }
    }

}

What I want:

enter image description here

Community
  • 1
  • 1
erdomester
  • 11,789
  • 32
  • 132
  • 234

1 Answers1

0

Here's what happens with your code:

User clicks any button which calls the OnClickListener.onClick method.
This method calls the setConnection method of the activity which constructs the facebook objects and return.
Then the getID method is invoked which checks if the user is authorized or not.

If the user is authorized you make an asynchronous request for /me, and then the method returns which immediately calls postOnWall.
The problem is that the request to /me/feed is sent before the asynchronous request returns with the data.

If the user is not authorized then you call mFacebook.authorize, and here in the onComplete method you again make an asynchronous request for /me but don't wait for it to complete before calling postOnWall.

In both cases you need to wait for the asynchronous request to complete, something like:

OnClickListener listener = new OnClickListener(){
    @Override
    public void onClick(View v) {
        // pbLogin.setVisibility(ProgressBar.VISIBLE);
        setConnection();
        getID(txtUserName, pbLogin);
    }
};

And (notice that I move the postOnWall invocation to the onComplete here):

private class IDRequestListener implements RequestListener {
    @Override
    public void onComplete(String response, Object state) {
            try {
                    Log.d(TAG, "IDRequestONComplete");
                    Log.d(TAG, "Response: " + response.toString());
                    JSONObject json = Util.parseJson(response);

                    final String id = json.getString("id");
                    final String name = json.getString("name");
                    FacebookActivity.this.runOnUiThread(new Runnable() {
                            public void run() {
                                    username.setText("Welcome: " + name+"\n ID: "+id);
                                    pb.setVisibility(ProgressBar.GONE);

                            }
                    });
                    postOnWall("Testing from Android");
            } catch (JSONException e) {
                    Log.d(TAG, "JSONException: " + e.getMessage());
            } catch (FacebookError e) {
                    Log.d(TAG, "FacebookError: " + e.getMessage());
            }
    }

    ...
Nitzan Tomer
  • 155,636
  • 47
  • 315
  • 299
  • Thank you! One more question: When I paste an url to the "What's on your mind?" box on FB, a logo and name of the webpage appears. Then I delete the url to post something else and the logo and name stays. How can I achieve this? I added the url in the postOnWall() method, and the result was posting the url, but no logo, no text. Is it possible what I want? I hope you understand what I mean. I add an img to the main post – erdomester Jun 13 '12 at 17:42
  • Adding this: `parameters.putString("link", "http://www.cnn.com");` does not do the trick? – Nitzan Tomer Jun 13 '12 at 18:03
  • Yes it does. One issue is that the image is some other image (play.google.com?), I posted my app's url – erdomester Jun 13 '12 at 20:47
  • Are you trying to post the url of your app on google play? If so, it won't work, from what I know they don't add the og meta tags to the html response, and you have no way to control it, because of that facebook just uses some random picture the scrapper finds. It should not also work when trying to post it from the normal facebook web interface, or you can check it in the [debugger](http://developers.facebook.com/tools/debug). In any case, these are completely unrelated questions which you can find answers to if you search here on SO. – Nitzan Tomer Jun 13 '12 at 20:55
  • I managed to do with this: parameters.putString("picture", "imgurl"); – erdomester Jun 13 '12 at 21:13
  • Right! I'm sorry, for some reason I was thinking you wanted a solution using open graph tags, I'm glad you found the solution. – Nitzan Tomer Jun 13 '12 at 21:48