Android Post Image to Facebook - android

I have this code running in my app and it is trying to post text and an image to a users wall. At the moment it is only posting the text. I think I have missed something simple, but would appreciate another pair of eyes check everything or another sample.
Any help is greatly appreciated.
Bundle bundle = new Bundle();
bundle.putString("message", "test update"); //'message' tells facebook that you're updating your status
bundle.putString(Facebook.TOKEN,accessToken);
bundle.putString("attachment", "{\"name\":\"My Test Image\","
+"\"href\":\""+"http://www.google.com"+"\","
+"\"media\":[{\"type\":\"image\",\"src\":\""+"http://www.google.com/logos/mucha10-hp.jpg"+"\",\"href\":\""+"http://www.google.com"+"\"}]"
+"}");
+"}");
//tells facebook that you're performing this action on the authenticated users wall, thus
// it becomes an update. POST tells that the method being used is POST
String response = facebook.request("me/feed",bundle,"POST");

Hope this will be work for you
Create class for facebook varible utility
import android.app.Application;
import com.facebook.android.AsyncFacebookRunner;
import com.facebook.android.Facebook;
public class Utility extends Application{
public static Facebook mFacebook;
public static AsyncFacebookRunner mAsyncRunner;
public static String userUID;
public static final String ICON_URL = "http://i.imgur.com/6G1b7.png";
}
Now mathod used to post image to facebook wall
public void postOnFacebookPicture(final Bitmap bitmap) {
String access_token = mPrefs.getString("access_token", null);
long expires = mPrefs.getLong("access_expires", 0);
if (access_token != null) {
Utility.mFacebook.setAccessToken(access_token);
}
if (expires != 0) {
Utility.mFacebook.setAccessExpires(expires);
}
if (!Utility.mFacebook.isSessionValid()) {
showErrorDialog(
"Facebook Account is not configure,Setting Facebook Account?",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
try {
// Move to setting the facebook account
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
} else {
new Thread() {
#Override
public void run() {
int what = 0;
try {
String accessToken = mPrefs.getString("access_token",
null);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.PNG, 0, bos);
byte[] pictureData = bos.toByteArray();
Bundle bundle = new Bundle();
bundle.putByteArray("facebookPictureData", pictureData);
bundle.putString(Facebook.TOKEN, accessToken);
Utility.mFacebook.request("me/photos", bundle, "POST");
} catch (Exception e) {
what = 1;
}
mHandler.sendMessage(mHandler.obtainMessage(what));
}
}.start();
}
}

For Posting Text and Image in Facebook wall, check this link:
You can insert Image using Media attachment.

Related

Publish photo on facebook

I'm trying to share a photo from my Andoid application, on Facebook using the FaceBook SDK. I have done
Facebook fb;
String APP_ID="xxxxx";//xxxxx: is my app id
private static final String[] PERMISSIONS = new String[] { "publish_stream" };
private static final String TOKEN = "access_token";
private static final String EXPIRES = "expires_in";
private static final String KEY = "facebook-credentials";
mShareButton= (Button) findViewById(R.id.share_button);
mShareButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
restoreCredentials(fb);
messageToPost = "Hello Everyone.";
if (!fb.isSessionValid()) {
loginAndPostToWall();
}
public boolean restoreCredentials(Facebook facebook) {
SharedPreferences sharedPreferences = getApplicationContext()
.getSharedPreferences(KEY, Context.MODE_PRIVATE);
facebook.setAccessToken(sharedPreferences.getString(TOKEN, null));
facebook.setAccessExpires(sharedPreferences.getLong(EXPIRES, 0));
return facebook.isSessionValid();
}
public void loginAndPostToWall() {
fb.authorize(this, PERMISSIONS, Facebook.FORCE_DIALOG_AUTH,
new LoginDialogListener());
}
public void postPhotoToWall() {
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.melody);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
final byte[] data = stream.toByteArray();
Bundle parameters = new Bundle();
parameters.putString("message", "Message");
parameters.putByteArray("picture", data);
parameters.putString("caption", "test");
try {
Log.i("Tests", "got response: " );
fb.request("me/feed");
Log.i("Tests", "got response: " );
String response = fb.request("me/feed", parameters, "POST");
Log.d("Tests", "got response: " + response);
if (response == null || response.equals("") || response.equals("false")) {
showToast("Blank response.");
} else {
showToast("Photo posted to your facebook wall!");
}
} catch (Exception e) {
showToast("Failed to post photo to your facebook wall!");
e.printStackTrace();
}
}
When I click on the share button I can connect just with my account from which I get the App ID. Also I can't post the photo on the wall: I just get "Failed to post photo to your facebook wall!". I can't figure out the problem.Any help please.

how to post text image into twitter same time in android

Hi i did one application here i need to share my score on twiter,i did using below code my score is posing fine,but now i need to share score along with app icon.but i dont know how to share that image along with text can any one help me,thankyou
TestPost.class:
public class TestPost extends Activity {
String review;
private TwitterApp mTwitter;
private String username = "";
private boolean postToTwitter = false;
private static final String twitter_consumer_key = "";
private static final String twitter_secret_key = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.post);
Button postBtn = (Button) findViewById(R.id.button1);
final EditText reviewEdit = (EditText) findViewById(R.id.revieew);
postBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
review = reviewEdit.getText().toString();
postToTwitter = true;
onTwitterClick();
}
});
mTwitter = new TwitterApp(this, twitter_consumer_key,twitter_secret_key);
mTwitter.setListener(mTwLoginDialogListener);
if (mTwitter.hasAccessToken()) {
username = mTwitter.getUsername();
username = (username.equals("")) ? "No Name" : username;
}
}
private void postToTwitter(final String review) {
new Thread() {
#Override
public void run() {
int what = 0;
try {
mTwitter.updateStatus(review);
} catch (Exception e) {
what = 1;
}
mHandler.sendMessage(mHandler.obtainMessage(what));
}
}.start();
}
private Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
String text = (msg.what == 0) ? "Posted to Twitter" : "Post to Twitter failed";
Toast.makeText(TestPost.this, text, Toast.LENGTH_SHORT).show();
}
};
private final TwDialogListener mTwLoginDialogListener = new TwDialogListener() {
#Override
public void onComplete(String value) {
username = mTwitter.getUsername();
username = (username.equals("")) ? "No Name" : username;
postToTwitter = true;
postToTwitter(review);
Toast.makeText(TestPost.this, "Connected to Twitter as " + username, Toast.LENGTH_LONG).show();
}
#Override
public void onError(String value) {
Toast.makeText(TestPost.this, "Twitter connection failed", Toast.LENGTH_LONG).show();
}
};
private void onTwitterClick() {
if (mTwitter.hasAccessToken()) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Delete current Twitter connection?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mTwitter.resetAccessToken();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
final AlertDialog alert = builder.create();
alert.show();
} else {
mTwitter.authorize();
}
}
}
This is how I upload an Image along with text to the logged in Twitter User's account. I make use of the TwitPic API for that. You will have to login and register a developer account there.
The solution can be thought of as a two step solution.
First, when the user clicks the post button, I first grab the Image and upload to TwitPic. From there, I grab the URL that is returned by TwitPic (String url = upload.upload(finalFile);).
In step two of this code, in a String instance (String finalStatusWithURL), I grab the content of an EditText and then append the URL from step 1 to it. With this done, the post is finally posted to Twitter.
Configuration conf = new ConfigurationBuilder()
.setOAuthConsumerKey(TWITTER_CONSUMER_KEY)
.setOAuthConsumerSecret(TWITTER_CONSUMER_SECRET)
.setOAuthAccessToken(twit_access_token)
.setOAuthAccessTokenSecret(twit_access_token_secret)
.setMediaProviderAPIKey(TWIT_PIC_API)
.build();
// SET THE FILE PATH
File finalFile = new File(getRealPathFromURI(initialURI));
// THIS IS IMPORTANT. TWITPIC NEEDS THE ACTUAL PATH ON THE DEVICE. JUST THE URI DOES NOT WORK!!!!
ImageUpload upload = new ImageUploadFactory(conf).getInstance(MediaProvider.TWITPIC);
String url = upload.upload(finalFile);
Log.e("TWITTER URL RESPONSE", url);
// NOW, UPLOAD TO TWITTER
ConfigurationBuilder builder = new ConfigurationBuilder();
builder.setOAuthConsumerKey(YOUR_TWITTER_CONSUMER_KEY);
builder.setOAuthConsumerSecret(YOUR_TWITTER_CONSUMER_SECRET);
AccessToken accessToken = new AccessToken(your_twit_access_token, your_twit_access_token_secret);
Twitter twitter = new TwitterFactory(builder.build()).getInstance(accessToken);
String finalStatusWithURL = null;
if (finalStatusMessage.trim().length() > 0) {
finalStatusMessage = editStatusUpdate.getText().toString();
finalStatusWithURL = finalStatusMessage + ":\n " + url;
} else {
finalStatusWithURL = url;
}
twitter4j.Status response = twitter.updateStatus(finalStatusWithURL);
Log.e("TWITTER RESPONSE", response.getText());
This is a method to get the real path of the image you want to upload:
// HELPER METHOD TO GET REAL PATH FOR THE SELECTED IMAGE
public String getRealPathFromURI(Uri uri) {
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
return cursor.getString(idx);
}
Hope this helps. This is production code from an app of mine.
UPDATED:
Change this in the code:
File finalFile = new File(getRealPathFromURI(initialURI));
To this:
Uri tempUri = getImageUri(getApplicationContext(), icon);
File finalFile = new File(getRealPathFromURI(tempUri));
And the helper method for Uri tempUri = getImageUri(getApplicationContext(), bmpFinal);:
public Uri getImageUri(Context inContext, Bitmap inImage) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
return Uri.parse(path);
}
You will still need to pass a Bitmap object. To convert your app icon to a Bitmap, use this:
Bitmap icon = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher);
UPDATED 2:
A little while after you asking and me answering your question, Twitter wrapped up a developer meet in SF. They have introduced a few new Cards which I think may be of use to your specific use-case. It is fresh off the block and I haven't gotten around to testing/using it. But if it fits your purpose, take a look at these links:
http://www.engadget.com/2013/04/02/twitter-cards-apps-products-photo-galleries/ (Where I found out about the new feature)
https://dev.twitter.com/blog/mobile-app-deep-linking-and-new-cards (The official Twitter blog)
https://dev.twitter.com/cards (Developer page for details of the features and how to use them)

Posting in Facebook wall using graph API not Working

I'm trying to post something to Facebook wall using graph API but its not working for me.
It has no error but it also not posting anything on my wall.
Here is the Codes:
public class ActivityName extends Activity{
Dialog dialog;
Facebook fb;
SharedPreferences sp;
String access_token, name, email;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.success);
String APP_ID = "MY_ID";
fb = new Facebook(APP_ID);
sp = getPreferences(MODE_PRIVATE);
access_token = sp.getString("access_token", null);
long expires = sp.getLong("access_expires", 0);
if(access_token!= null){
fb.setAccessToken(access_token);
}
if(expires != 0){
fb.setAccessExpires(expires);
}
((Button) findViewById(R.id.btn_home)).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
openContextMenu(v);
}
});
((Button) findViewById(R.id.btn_home)).setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
// TODO Auto-generated method stub
menu.setHeaderTitle("Tell the world!");
menu.add(0, 0, 0, "Facebook");
menu.add(0, 1, 0, "Twitter");
menu.add(0, 2, 0, "Skip");
}
});
}
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
.getMenuInfo();
switch (item.getItemId()) {
case 1:
break;
case 0:
fb.authorize(SuccessActivity.this, new String[]{ "photo_upload,user_photos,publish_checkins,publish_actions,publish_stream"},new DialogListener() {
public void onComplete(Bundle values) {
postToWall();
}
public void onFacebookError(FacebookError error) {
}
public void onError(DialogError e) {
}
public void onCancel() {
}
});
break;
case 2:
Intent i = new Intent(getApplicationContext(),MainActivity.class);
startActivity(i);
overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
break;
}
return true;
}
public void onBackPressed() {
}
#SuppressLint("SdCardPath")
public void postToWall() {
// post on user's wall.
try {
if (fb.isSessionValid()) {
byte[] data = null;
Bitmap bi = BitmapFactory.decodeFile("/sdcard/Asa.jpg");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bi.compress(Bitmap.CompressFormat.JPEG, 100, baos);
data = baos.toByteArray();
Bundle params = new Bundle();
params.putString(Facebook.TOKEN, fb.getAccessToken());
params.putString("message", "Test from Android AVD");
params.putByteArray("picture", data);
AsyncFacebookRunner mAsyncRunner = new AsyncFacebookRunner(fb);
mAsyncRunner.request("/me/feed", params,"POST", new SampleUploadListener(),null);
}
}catch(Exception e){
e.printStackTrace();
}
}
public class SampleUploadListener extends BaseRequestListener {
public void onComplete(final String response, final Object state) {
try {
// process the response here: (executed in background thread)
Log.d("Facebook-Example", "Response: " + response.toString());
JSONObject json = Util.parseJson(response);
final String src = json.getString("src");
// then post the processed result back to the UI thread
// if we do not do this, an runtime exception will be generated
// e.g. "CalledFromWrongThreadException: Only the original
// thread that created a view hierarchy can touch its views."
} catch (JSONException e) {
Log.w("Facebook-Example", "JSON Error in response");
} catch (FacebookError e) {
Log.w("Facebook-Example", "Facebook Error: " + e.getMessage());
}
}
#Override
public void onFacebookError(FacebookError e, Object state) {
}
}
}
Can anyone pint what missing or wrong in this codes?
any thoughts will be highly appreciated.
Here's some code I used a little while back to do something similar:
function publishPost(session) {
var $title = $('#title').val(),
$story = $('#story').val(),
publish = {
method: 'stream.publish',
message: 'I just entered the Your Perfect Kent Day Competition.',
picture : 'http://apps.facebook.com/perfect-kent-day/',
link : 'http://apps.facebook.com/perfect-kent-day/',
name: 'Enter to win or vote for your faourite story here!',
caption: $title,
description: $story,
actions : { name : 'Apply for Kent Teach Jobs...', link : 'http://www.kent- teach.com/'}
};
FB.api('/me/feed', 'POST', publish, function(response) {
//alert('A post had just been published into the stream on your wall.');
$('#before-submit').hide();
$('#after-submit').show();
$('#loading').fadeOut();
});
};
And then I called the publishPost() function once a form on the page was submitted with AJAX. Hope this help!

Easy Facebook Android SDK - NetworkOnMainThreadException

I have been Using this SDK http://www.easyfacebookandroidsdk.com/ to integrate Facebook in my App.
I only want to update a statur from my App. It worked great using this class in Android API 10. Running it on phone with API 15 gives me a android.os.NetworkOnMainThreadException. here my code:
package com.my.wod;
import android.app.Activity;
import android.content.Context;
import com.main.xfit.R;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.Toast;
import com.facebook.android.*;
import com.facebook.android.Facebook.DialogListener;
public class PostFaceBookStatus extends Activity {
private static final String APP_ID = "ID OF MY APP";
private static final String[] PERMISSIONS = {"publish_stream" };
private static final String TOKEN = "access_token";
private static final String EXPIRES = "expires_in";
private static final String KEY = "facebook-credentials";
private Facebook facebook;
private String messageToPost;
public boolean saveCredentials(Facebook facebook) {
Editor editor = getApplicationContext().getSharedPreferences(KEY, Context.MODE_PRIVATE).edit();
editor.putString(TOKEN, facebook.getAccessToken());
editor.putLong(EXPIRES, facebook.getAccessExpires());
return editor.commit();
}
public boolean restoreCredentials(Facebook facebook) {
SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences(KEY, Context.MODE_PRIVATE);
facebook.setAccessToken(sharedPreferences.getString(TOKEN, null));
facebook.setAccessExpires(sharedPreferences.getLong(EXPIRES, 0));
return facebook.isSessionValid();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
facebook = new Facebook(APP_ID);
restoreCredentials(facebook);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.facebook);
String facebookMessage = getIntent().getStringExtra("facebookMessage");
Toast.makeText(getApplicationContext(), facebookMessage, Toast.LENGTH_LONG).show();
if (facebookMessage == null){
facebookMessage = "SUNDAY 120506 2012 CrossFit Games Regional: Individual Event 4 For time: 135 pound Back squat, 50 reps 40 Pull-ups 135 pound Shoulder-to-overhead, 30 reps 85 pound Front squat, 50 reps 40 Pull-ups 85 pound Shoulder-to-overhead, 30 reps 65 pound Overhead squat, 50 reps 40 Pull-ups 65 pound Shoulder-to-overhead, 30 reps";
}
//messageToPost = facebookMessage;
messageToPost = "Post random shit" ;
}
public void doNotShare(View button){
finish();
}
public void share(View button){
if (! facebook.isSessionValid()) {
loginAndPostToWall();
}
else {
postToWall(messageToPost);
}
}
public void loginAndPostToWall(){
facebook.authorize(this, PERMISSIONS, Facebook.FORCE_DIALOG_AUTH, new LoginDialogListener());
}
public void postToWall(String message){
Bundle parameters = new Bundle();
parameters.putString("message", message);
parameters.putString("description", "topic share");
try {
facebook.request("me");
String response = facebook.request("me/feed", parameters, "POST");
Log.d("Tests", "got response: " + response);
if (response == null || response.equals("") ||
response.equals("false")) {
showToast("Blank response.");
}
else {
showToast("Message posted to your facebook wall!");
}
finish();
} catch (Exception e) {
showToast("Failed to post to wall!");
e.printStackTrace();
finish();
}
}
class LoginDialogListener implements DialogListener {
public void onComplete(Bundle values) {
saveCredentials(facebook);
if (messageToPost != null){
postToWall(messageToPost);
}
}
public void onFacebookError(FacebookError error) {
showToast("Authentication with Facebook failed!");
finish();
}
public void onError(DialogError error) {
showToast("Authentication with Facebook failed!");
finish();
}
public void onCancel() {
showToast("Authentication with Facebook cancelled!");
finish();
}
}
private void showToast(String message){
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
}
}
Any ideas?
You can't run network operations on the UI thread, and if you think it is is the API code doing it, then you'll have to wrap the API call's in a Thread.
Looks like this line is using the network:
String response = facebook.request("me/feed", parameters, "POST");
You need to do long running tasks on a worker thread.
You used to get an ANR (Activity Not Responsding) but ICS is a little cleverer and kicks you off before this happens.
Get reading:
http://developer.android.com/guide/practices/responsiveness.html
http://developer.android.com/training/basics/network-ops/connecting.html#AsyncTask < This is one possible alternative answer
To make it work for API level 10 and higher i just employed and AsyncTask and it Worked!!
Use the below code:
//make this global declaration
private Facebook mFacebook;
private class FbLoginAsync extends AsyncTask<Void, Void, User> {
#Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(ConstantsCtc.DIALOG_PROGRESS);
}
#Override
protected User doInBackground(Void... params) {
// facebooklogin();
return getFacebookData();
}
#Override
protected void onPostExecute(User u) {
super.onPostExecute(u);
// your facebook information is in User bean 'u'.
}
}
public User getFacebookData() {
User u = new User();
try {
JSONObject jsonME = null;
JSONObject jsonfrnd = null;
try {
jsonME = Util.parseJson(mFacebook.request("me"));
// jsonfrnd =
// Util.parseJson(mFacebook
// .request("me/friends"));
} catch (FacebookError e) {
e.printStackTrace();
u = null;
}
Log.w("fbjsonMe", " *\n " + jsonME);
// Log.e("fbjsonfrnds", " *\n " + jsonfrnd);
String mUserId = jsonME.getString("id");
String mUserName = jsonME.getString("first_name");
String mUseremail = jsonME.getString("email");
String birthday = jsonME.getString("birthday");
String gender = jsonME.getString("gender");
String full_name = jsonME.getString("name");
// Log.w("UserName", mUserName + " * " + mUseremail + " *\n "
// + jsonME);
// calculate age
String ag[] = birthday.split("/");
int y = Integer.parseInt(ag[2]);// get birth year
final Calendar cal = Calendar.getInstance();
int currentyear = cal.get(Calendar.YEAR);
int age = currentyear - y;
if (gender.equalsIgnoreCase("male"))
gender = "0";
else
gender = "1";
u.setUserId(mUserId);
u.setUserFullName(full_name);
u.setEmail(mUseremail);
u.setAge(age + "");
u.setGender(gender);
} catch (Exception e) {
e.printStackTrace();
u = null;
}
return u;
}
// then make a call to below method form your activity's button click or
// else
public void facebookLogin() {
this.mFacebook = new Facebook(appId);// give your appId
if (mFacebook.isSessionValid()) {
new FbLoginAsync().execute();
} else {
SessionEvents.AuthListener listener = new SessionEvents.AuthListener() {
#Override
public void onAuthSucceed() {
new FbLoginAsync().execute();
}
#Override
public void onAuthFail(String error) {
showDialogCustome("Error in Facebook Login, please try again later");
Log.e("onAuthFail", "onAuthFail");
}
};
SessionEvents.addAuthListener(listener);
mFacebook.authorize(this.activity, this.permissions,
Facebook.FORCE_DIALOG_AUTH, new LoginDialogListener());
}
}
I hope this solves your problem. let me know

Handling a facebook-object through multiple activities

Currently I'm writing an adapter class to provide a convenient way for communication with the facebook API.
The way I thought about using it is to run the authentication when the app is starting up, downloading user's private picture, and later in the app publishing updates on users facebook wall using an AsyncFacebookRunner.
However flipping through the documentation it seems for every authorize() implementation the first parameter have to be an activity.
void authorize(Activity activity, final DialogListener listener):
And here I begin to wonder.
Thinking about activities and life cycles what will happen when the activity I threw in will be destroyed? Wouldn't the reference for this object Facebook.mAuthActivity become invalid as well.
I see the logout() method "only" asks for a context.
String logout(Context context) throws ...:
context - The Android context in which the logout should be called: it should be the same context in which the login occurred in order to clear any stored cookies
From what I see I can not guarantee the "login-activity" will still be present as app's uptime increases - actually the opposite is more likely.
Are there any special situations I should consider to prevent the app form total crashing in a later state?
You can try use my FBHelper class.
public class FBHelper {
private SharedPreferences mPrefs;
private Context context;
private final String ACCES_TOKEN = "access_token";
private final String ACCES_EXPIRES = "access_expires";
private Facebook facebook;
private FBHelperCallbacks callback;
public FBHelper(Context context, Facebook facebook)
{
this.context = context;
this.facebook = facebook;
}
public void setSignInFinishListener(FBHelperCallbacks callback)
{
this.callback = callback;
}
public void FacebookSingleSignIn() {
mPrefs = ((Activity)context).getPreferences(Context.MODE_PRIVATE);
String access_token = mPrefs.getString(ACCES_TOKEN, null);
long expires = mPrefs.getLong(ACCES_EXPIRES, 0);
if(access_token != null) {
facebook.setAccessToken(access_token);
}
if(expires != 0) {
facebook.setAccessExpires(expires);
}
/*
* Only call authorize if the access_token has expired.
*/
if(!facebook.isSessionValid()) {
Log.i("Facebook","Facebook session is not valid based on acces token... authorizing again");
facebook.authorize((Activity)context, new String[] {"user_about_me"},new DialogListener() {
#Override
public void onFacebookError(FacebookError e) {
e.printStackTrace();
callback.onError(e.toString());
}
#Override
public void onError(DialogError e) {
Log.i("Facebook","onError inner");
callback.onError(e.toString());
}
#Override
public void onComplete(Bundle values) {
SharedPreferences.Editor editor = mPrefs.edit();
editor.putString(ACCES_TOKEN, facebook.getAccessToken());
Log.i("Facebook","Saving acces token:"+facebook.getAccessToken());
editor.putLong(ACCES_EXPIRES, facebook.getAccessExpires());
editor.commit();
callback.onSignedInFinished(facebook.getAccessToken());
}
#Override
public void onCancel() {
callback.onError("onCancel");
}
});
}
else
{
Log.i("Facebook","Accces token read form preferencesno no need to authorize");
callback.onSignedInFinished(facebook.getAccessToken());
}
}
public String LogOut()
{
try {
//set ACCES_TOKEN to null
mPrefs = ((Activity)context).getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = mPrefs.edit();
editor.putString(ACCES_TOKEN, null);
editor.putLong(ACCES_EXPIRES, 0);
editor.commit();
return facebook.logout(context);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "Error";
}
public static abstract class FBHelperCallbacks{
public abstract void onSignedInFinished(String accesToken);
public abstract void onError(String message);
}
}
This is how you use this class.
public class LogInActivity extends Activity {
private static final String TAG = "LogInActivity";
public static final int REQUEST_CODE = 1;
private Context context;
private Facebook facebook;
private FBHelper fbhelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_log_in);
this.context = this;
Handler pauser = new Handler();
pauser.postDelayed (new Runnable() {
public void run() {
facebook = new Facebook(context.getString(R.string.FACEBOOK_APP_ID));
fbhelper = new FBHelper(context, facebook);
if (aHelper.isLogedIn())
{
//log out
fbhelper.LogOut();
}
else
{
//facebook login
fbhelper.setSignInFinishListener(fbcallback);
fbhelper.FacebookSingleSignIn();
}
}
}, 100);
}
FBHelperCallbacks fbcallback = new FBHelperCallbacks() {
#Override
public void onSignedInFinished(String accesToken) {
Log.d(TAG,"log in finish");
}
#Override
public void onError(String message) {
setResult(RESULT_CANCELED);
finish();
}
};
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
facebook.authorizeCallback(requestCode, resultCode, data);
}
}
aHelper is object that hold some application specific data. Basically you should decide here if you want to log in or log out.
using facebook API for the android is easy and in your case you don't need to save the Facebook instance the only thing you need is to save the authKey of the facebook on the first login then you can use it anywhere.
this means that you can create more than one instance of the facebook object in mutiple activities based on the authKey.
Otherwise you need to put this facebook object in a singleton handler to save it among the application :
class x {
private Facebook obj;
private static x instance;
private x (){
}
public static x getX(){
if(instance == null){
instance = new x();
}
return instance;
}
public void setIt(Facebook obj){
this.obj = obj;
}
public Facebook getIt(){
return obj;
}
}
but this way is not the best way to implement the code you need to create a Facebook instance for each activity using the authKy.

Categories

Resources