I am using facebook connect in my android app. It is basically a form. There is a facebook login button on the page. I want the information on the form to be filled in when thee user logs in using Facebook login.
I am trying the following code:
public void loginFB() {
facebook.authorize(this, new String[] { "email", "read_stream" }, new DialogListener() {
#Override
public void onComplete(Bundle values) {}
#Override
public void onFacebookError(FacebookError error) {}
#Override
public void onError(DialogError e) {}
#Override
public void onCancel() {}
});
getlogininfo();
}
public void getlogininfo(){
mAsyncRunner.request("me", new RequestListener(){
#Override
public void onComplete(String response, Object state) {
try{
Log.d("Profile", response.toString());
JSONObject json = Util.parseJson(response);
final String fname1 = json.getString("first_name");
final String lname1 = json.getString("last_name");
final String email = json.getString("email");
MintPaymentsActivity.this.runOnUiThread(new Runnable(){
public void run() {
fname.setText(fname1);
lname.setText(lname1);
emailadd.setText(email);
}
});
}
catch(JSONException e){
Log.w("This", "eror");
}
}
#Override
public void onIOException(IOException e, Object state) {
// TODO Auto-generated method stub
}
#Override
public void onFileNotFoundException(FileNotFoundException e, Object state) {
// TODO Auto-generated method stub
}
#Override
public void onMalformedURLException(MalformedURLException e, Object state) {
// TODO Auto-generated method stub
}
#Override
public void onFacebookError(FacebookError e, Object state) {
// TODO Auto-generated method stub
}
});
}
/*FB --- */
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
facebook.authorizeCallback(requestCode, resultCode, data);
}
basically, when the user clicks the button, faceboook asks for login and then collects the JSON data to display the name and email of the logged in user.
It gives me the following error:
05-30 21:52:40.598: E/AndroidRuntime(665): FATAL EXCEPTION: Thread-13
05-30 21:52:40.598: E/AndroidRuntime(665): com.facebook.android.FacebookError: An active access token must be used to query information about the current user.
05-30 21:52:40.598: E/AndroidRuntime(665): at com.facebook.android.Util.parseJson(Util.java:279)
05-30 21:52:40.598: E/AndroidRuntime(665): at com.Myapp.Myapp$2.onComplete(Myapp.java:117)
05-30 21:52:40.598: E/AndroidRuntime(665): at com.facebook.android.AsyncFacebookRunner$2.run(AsyncFacebookRunner.java:254)
When I put an extra button to fill in the details, so that the getlogininfo() is implemented on a button click (after logging in) it works fine. But i want it to be filled in as soon as the user clicks the facebook login button.
It should be:
public void loginFB() {
facebook.authorize(this, new String[] { "email", "read_stream" }, new DialogListener() {
#Override
public void onComplete(Bundle values) {
this.getlogininfo();
}
#Override
public void onFacebookError(FacebookError error) {}
#Override
public void onError(DialogError e) {}
#Override
public void onCancel() {}
});
}
You want to execute getLogininfo only after the authentication has completed.
Also, I suggest that you handle the errors as well, at least log it so you'll know when developing.
Related
I'm developing android app and i want user to connect Facebook when he open the app for the first time using Facebook SDK.
Then i want to post to the Facebook wall with specific message from my app. I try to use Facebook sdk with my app.I have made integration between mp app and Facebook sdk but i don't know how to do the task that log in to Facebook and post to the wall with the specific message.I search stackoverflow for this task and i found this code but i can't understand it
and it doesn't for me
public class MainActivity extends Activity {
Facebook facebookClient;
SharedPreferences mPrefs;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
facebookClient=new Facebook("fb_App_id");
ImageButton facebookButton = (ImageButton) findViewById(R.id.button_FacebookShare);
facebookButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
loginToFacebook();
if (facebookClient.isSessionValid()) {
postToWall();
}
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
facebookClient.authorizeCallback(requestCode, resultCode, data);
}
public void loginToFacebook() {
mPrefs = getPreferences(MODE_PRIVATE);
String access_token = mPrefs.getString("access_token", null);
long expires = mPrefs.getLong("access_expires", 0);
if (access_token != null) {
facebookClient.setAccessToken(access_token);
}
if (expires != 0) {
facebookClient.setAccessExpires(expires);
}
if (!facebookClient.isSessionValid()) {
facebookClient.authorize(this, new String[] { "publish_stream" }, new DialogListener() {
#Override
public void onCancel() {
// Function to handle cancel event
}
#Override
public void onComplete(Bundle values) {
// Function to handle complete event
// Edit Preferences and update facebook acess_token
SharedPreferences.Editor editor = mPrefs.edit();
editor.putString("access_token", facebookClient.getAccessToken());
editor.putLong("access_expires", facebookClient.getAccessExpires());
editor.commit();
postToWall();
}
#Override
public void onError(DialogError error) {
// Function to handle error
}
#Override
public void onFacebookError(FacebookError fberror) {
// Function to handle Facebook errors
}
});
}
}
private void postToWall() {
Bundle parameters = new Bundle();
parameters.putString("name", "Battery Monitor");
parameters.putString("link", "https://play.google.com/store/apps/details?id=com.ck.batterymonitor");
parameters.putString("picture", "link to the picture");
parameters.putString("display", "page");
// parameters.putString("app_id", "228476323938322");
facebookClient.dialog(MainActivity.this, "feed", parameters, new DialogListener() {
#Override
public void onFacebookError(FacebookError e) {
// TODO Auto-generated method stub
}
#Override
public void onError(DialogError e) {
// TODO Auto-generated method stub
}
#Override
public void onComplete(Bundle values) {
// TODO Auto-generated method stub
}
#Override
public void onCancel() {
// TODO Auto-generated method stub
}
});
}
}
You should refer to the following question on SO.
Facebook login and post
This code works. It will definitely solve your problem.
Try to use Android Simple Facebook (https://github.com/sromku/android-simple-facebook) - it's a layer to make the usage of Facebook SDK easier. According to the documentation, the login process would be something like this:
Initialize callback listener:
OnLoginListener onLoginListener = new OnLoginListener() {
#Override
public void onLogin() {
// change the state of the button or do whatever you want
Log.i(TAG, "Logged in");
}
#Override
public void onNotAcceptingPermissions(Permission.Type type) {
// user didn't accept READ or WRITE permission
Log.w(TAG, String.format("You didn't accept %s permissions", type.name()));
}
/*
* You can override other methods here:
* onThinking(), onFail(String reason), onException(Throwable throwable)
*/
};
Login:
mSimpleFacebook.login(onLoginListener);
I am trying to retrieve my facebook pages information.But when I install and run the app first time it gives me.
{"error":{"message":"An active access token must be used to query information about the current user.","type":"OAuthException","code":2500}}
and the next time when I run the application it returns me the correct result.Why this is happening.I want it to return the data the first time i run the app after installation.
Here's my facebook sdk code:
private String access_Token="";
private final String APP_ID="MY_APP_ID";
private final String[] PERMS = new String[] { "publish_stream","manage_pages" };
private Bundle params=new Bundle();
private SharedPreferences sharedPrefs;
private AsyncFacebookRunner mAsyncRunner;
private Facebook mfacebook;
private TextView view;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
view=(TextView)findViewById(R.id.Mozi);
this.SetConnection(); //Initialize Fb
this.getAccessToken(); //GetAccessToken
this.CheckSessionExpiry(); //Create Session with permissions if expired
this.RetrieveUserPages();
// this.EnableFBLogout();
}
public void onResume() {
super.onResume();
mfacebook.extendAccessTokenIfNeeded(this, null);
}
private void EnableFBLogout()
{
mAsyncRunner.logout(getApplicationContext(), new RequestListener() {
#Override
public void onComplete(String response, Object state) {
String method = "DELETE";
Bundle params = new Bundle();
/*
* this will revoke 'publish_stream' permission
* Note: If you don't specify a permission then this will de-authorize the application completely.
*/
params.putString("permission", "publish_stream");
mAsyncRunner.request("/me/permissions", params, method,new RequestListener() {
#Override
public void onMalformedURLException(MalformedURLException e, Object state) {
// TODO Auto-generated method stub
Log.e("PerMalform",e.getMessage());
}
#Override
public void onIOException(IOException e, Object state) {
// TODO Auto-generated method stub
Log.e("PerMalform",e.getMessage());
}
#Override
public void onFileNotFoundException(FileNotFoundException e, Object state) {
// TODO Auto-generated method stub
Log.e("PerMalform",e.getMessage());
}
#Override
public void onFacebookError(FacebookError e, Object state) {
// TODO Auto-generated method stub
Log.e("PerMalform",e.getMessage());
}
#Override
public void onComplete(String response, Object state) {
// TODO Auto-generated method stub
Log.e("PerMalform",response);
}
}, null);
}
#Override
public void onIOException(IOException e, Object state) {}
#Override
public void onFileNotFoundException(FileNotFoundException e,
Object state) {}
#Override
public void onMalformedURLException(MalformedURLException e,
Object state) {}
#Override
public void onFacebookError(FacebookError e, Object state) {}
});
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
this.mfacebook.authorizeCallback(requestCode, resultCode, data);
}
private void getAccessToken()
{
sharedPrefs= getPreferences(MODE_PRIVATE);
String access_token = sharedPrefs.getString("access_token", null);
long expires = sharedPrefs.getLong("access_expires", 0);
if(access_token != null) {
mfacebook.setAccessToken(access_token);
}
if(expires != 0) {
mfacebook.setAccessExpires(expires);
}
}
private void CheckSessionExpiry()
{
if(!mfacebook.isSessionValid()) {
mfacebook.authorize(this, this.PERMS , new DialogListener() {
#Override
public void onComplete(Bundle values) {
SharedPreferences.Editor editor = sharedPrefs.edit();
editor.putString("access_token", mfacebook.getAccessToken());
editor.putLong("access_expires", mfacebook.getAccessExpires());
editor.commit();
}
#Override
public void onFacebookError(FacebookError error) {
Log.e("mozi1",error.toString());
}
#Override
public void onError(DialogError e) {
Log.e("mozi2",e.toString());
}
#Override
public void onCancel() {
Log.e("sad","ww");
}
});
}
}
private void SetConnection()
{
this.mfacebook=new Facebook(this.APP_ID);
this.mAsyncRunner=new AsyncFacebookRunner(mfacebook);
}
private void RetrieveUserPages()
{
this.params.putString(Facebook.TOKEN, mfacebook.getAccessToken());
this.mAsyncRunner.request("me/accounts", this.params, "GET", new RequestListener() {
#Override
public void onMalformedURLException(MalformedURLException e, Object state) {
// TODO Auto-generated method stub
Log.e("Malformed",e.getMessage());
}
#Override
public void onIOException(IOException e, Object state) {
// TODO Auto-generated method stub
Log.e("IO",e.getMessage());
}
#Override
public void onFileNotFoundException(FileNotFoundException e, Object state) {
// TODO Auto-generated method stub
Log.e("FNF",e.getMessage());
}
#Override
public void onFacebookError(FacebookError e, Object state) {
// TODO Auto-generated method stub
Log.e("FBERR",e.getMessage());
}
#Override
public void onComplete(String response, Object state) {
// TODO Auto-generated method stub
Log.i("responsefromFB",response); //here the response is an error for the first time and data the second time.
// view.setText(response);
}
}, null);
}
mfacebook.authorize() is asynchronous, which means that code after the authorize() method is run even though authorize() is not completed. Because you call this.RetrieveUserPages() right after mfacebook.authorize(), you are calling
this.params.putString(Facebook.TOKEN, mfacebook.getAccessToken());
before mfacebook.authorize() has completed, so mfacebook.getAcessToken() returns null.
The answer to your issue is to only call this.RetrieveUserPages() in the onComplete method of mfacebook.authorize() to ensure that your access token is set before trying to retrieve it.
Let me know if that helps!
I am trying to integrate Facebook ** into my android app. I want to implement **like and share ** facility on **facebook. But i am getting error.
please help me to solve this.
Also I want to know the process of creating New App on Facebook.
I am using code from GitHub. My code is -
public class MyGreatActivity extends Activity {
Facebook facebook = new Facebook("333778590046892");
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
facebook.authorize(this, new String[] { "offline_access", "publish_stream", "raj21kadam#gmail.com" },
new DialogListener() {
#Override
public void onComplete(Bundle values) {
String token=facebook.getAccessToken(); //get access token
// Toast.makeText(this, "token", Toast.LENGTH_LONG).
save(token);
}
#Override
public void onFacebookError(FacebookError error) {}
#Override
public void onError(DialogError e) {}
#Override
public void onCancel() {}
});
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
facebook.authorizeCallback(requestCode, resultCode, data);
}
private void save(String token){
Toast.makeText(this, "token"+token, Toast.LENGTH_LONG).show();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.edit().putString("Token", token).commit();
}
}
I am getting the following error while running the above code -
Dialog Errorcom.facebook.android.DialogError: The connection to the server was unsuccessful.
try this Single Sign On (SSO) Using Android Native Client For Facebook .
paste this
facebook.authorize(this, new DialogListener() {
#Override
public void onComplete(Bundle values) {
String token=facebook.getAccessToken(); //get access token
// Toast.makeText(this, "token", Toast.LENGTH_LONG).
save(token);
}
public void onFacebookError(FacebookError error) {}
#Override
public void onError(DialogError e) {}
#Override
public void onCancel() {}
});
}
instead of this
facebook.authorize(this, new String[] { "offline_access", "publish_stream", "raj21kadam#gmail.com" },
new DialogListener() {
#Override
public void onComplete(Bundle values) {
String token=facebook.getAccessToken(); //get access token
}
#Override
public void onFacebookError(FacebookError error) {}
#Override
public void onError(DialogError e) {}
#Override
public void onCancel() {}
});
}
I have 2 activities in my android application. On the first one, I ask the user to login with facebook. after the user logs in, i collect the user data such as email, name and call a new activity passing these parameters to it. below is my facebook authorize method:
public void loginFB(final View v)
{
facebook.authorize(this, new String[] { "email", "read_stream" }, new DialogListener() {
#Override
public void onComplete(Bundle values) {
this.getlogininfo(v);
}
private void getlogininfo(View v) {
// TODO Auto-generated method stub
logininfo(v);
}
#Override
public void onFacebookError(FacebookError error) {}
#Override
public void onError(DialogError e) {}
#Override
public void onCancel() {}
});
}
Below is my logininfo() method:
public void logininfo(final View v){
mAsyncRunner.request("me", new RequestListener(){
#Override
public void onComplete(String response, Object state) {
try{
Log.d("Profile", response.toString());
JSONObject json = Util.parseJson(response);
final String fname1 = json.getString("first_name");
final String lname1 = json.getString("last_name");
final String email = json.getString("email");
Intent fbLogged = new Intent();
Bundle passData = new Bundle();
passData.putString("fname", fname1);
passData.putString("lname", lname1);
passData.putString("email", email);
fbLogged.putExtras(passData);
fbLogged.setClass(v.getContext(), RequestFb.class);
startActivity(fbLogged);
}
catch(JSONException e){
Log.w("This", "eror");
}
}
#Override
public void onIOException(IOException e, Object state) {
// TODO Auto-generated method stub
}
#Override
public void onFileNotFoundException(FileNotFoundException e,
Object state) {
// TODO Auto-generated method stub
}
#Override
public void onMalformedURLException(MalformedURLException e,
Object state) {
// TODO Auto-generated method stub
}
#Override
public void onFacebookError(FacebookError e, Object state) {
// TODO Auto-generated method stub
}
});
}
So, my new activity is starting on OnComplete() of getting the user data.
This works perfectly, but when the user clicks login, and logs in with facebook, the first activity page remains on the screen for a few seconds and then the next activity is called. there is a lag. How can I fix the lag? When the user clicks login and after the login is authorized, it should take the user to directly the second activity. Any suggestions?
Thanks!
It's simple, you are running the fb graph request in a new thread (using the AsyncRunner) but only when that request is completed you start the new activity and that's why you get that "lag".
You should run the graph request in the new activity instead of the first one, something like:
public void loginFB(final View v) {
facebook.authorize(this, new String[] { "email", "read_stream" }, new DialogListener() {
#Override
public void onComplete(Bundle values) {
Intent fbLogged = new Intent(v.getContext(), RequestFb.class);
startActivity(fbLogged);
}
#Override
public void onFacebookError(FacebookError error) {}
#Override
public void onError(DialogError e) {}
#Override
public void onCancel() {}
});
}
public class RequestFb extend Activity {
protected void onCreate(Bundle savedInstanceState) {
Facebook facebook = new Facebook("YOUR_APP_ID");
AsyncFacebookRunner asyncRunner = new AsyncFacebookRunner(facebook);
asyncRunner.request("me", new RequestListener(){
try {
final JSONObject json = Util.parseJson(response);
final String fname1 = json.getString("first_name");
final String lname1 = json.getString("last_name");
final String email = json.getString("email");
runOnUiThread(new Runnable() {
public void run() {
// use the data
}
});
}
catch(JSONException e) {
Log.w("This", "eror");
}
});
}
}
I look all the internet and couldn't find how do I post link with a specific picture on facebook wall using fb sdk\api.
I know that this is part of the code that I need to use:
Facebook facebookClient = new Facebook("fb_App_id");
Bundle parameters = new Bundle();
parameters.putString("message", "Test Photo");
parameters.putString("link", "https://www.google.com");
parameters.putString("picture", "link to some pictrue");
facebookClient.dialog(MainActivity.this, "stream.publish", parameters, new DialogListener() {
#Override
public void onFacebookError(FacebookError e) {
// TODO Auto-generated method stub
}
#Override
public void onError(DialogError e) {
// TODO Auto-generated method stub
}
#Override
public void onComplete(Bundle values) {
// TODO Auto-generated method stub
}
#Override
public void onCancel() {
// TODO Auto-generated method stub
}
});
When I try to use this code I get "Source not found" error.
I think that I'm missing the connect\verification step...
How can I make it work?
Another thing: In case I use FB SDK in my personal app that I share on Google Play and this app is FREE but has Ads on it, Is it legal to use FB SDK in my app?
Finally I found how to do it.
You need to declare this two:
Facebook facebookClient;
SharedPreferences mPrefs;
In the onCreate function I initialize facebookClient with the facebook AppID.
The class that lunches the facebook share must be Activity
There are three functions that I added to the activity:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
facebookClient.authorizeCallback(requestCode, resultCode, data);
}
public void loginToFacebook() {
mPrefs = getPreferences(MODE_PRIVATE);
String access_token = mPrefs.getString("access_token", null);
long expires = mPrefs.getLong("access_expires", 0);
if (access_token != null) {
facebookClient.setAccessToken(access_token);
}
if (expires != 0) {
facebookClient.setAccessExpires(expires);
}
if (!facebookClient.isSessionValid()) {
facebookClient.authorize(this, new String[] { "publish_stream" }, new DialogListener() {
#Override
public void onCancel() {
// Function to handle cancel event
}
#Override
public void onComplete(Bundle values) {
// Function to handle complete event
// Edit Preferences and update facebook acess_token
SharedPreferences.Editor editor = mPrefs.edit();
editor.putString("access_token", facebookClient.getAccessToken());
editor.putLong("access_expires", facebookClient.getAccessExpires());
editor.commit();
postToWall();
}
#Override
public void onError(DialogError error) {
// Function to handle error
}
#Override
public void onFacebookError(FacebookError fberror) {
// Function to handle Facebook errors
}
});
}
}
private void postToWall() {
Bundle parameters = new Bundle();
parameters.putString("name", "Battery Monitor");
parameters.putString("link", "https://play.google.com/store/apps/details?id=com.ck.batterymonitor");
parameters.putString("picture", "link to the picture");
parameters.putString("display", "page");
// parameters.putString("app_id", "228476323938322");
facebookClient.dialog(MainActivity.this, "feed", parameters, new DialogListener() {
#Override
public void onFacebookError(FacebookError e) {
// TODO Auto-generated method stub
}
#Override
public void onError(DialogError e) {
// TODO Auto-generated method stub
}
#Override
public void onComplete(Bundle values) {
// TODO Auto-generated method stub
}
#Override
public void onCancel() {
// TODO Auto-generated method stub
}
});
}
and at last:
ImageButton facebookButton = (ImageButton) findViewById(R.id.button_FacebookShare);
facebookButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
loginToFacebook();
if (facebookClient.isSessionValid()) {
postToWall();
}
}
});
It does an auto login to facebook and then displaies facebook share\post dialog.
The code was taken from this tutorial
I'm guessing that your problem is that you are using the stream.publish path which got deprecated:
Please note: We are in the process of deprecating the REST API, so if
you are building a new application you shouldn't use this function.
Instead use the Graph API and POST a Post object to the feed
connection of the User object
instead do this:
facebookClient.dialog(MainActivity.this, "feed", parameters, new DialogListener() {
...
});