I am using the latest facebook sdk , I tried to follow the offical sample to create a own login button , however, I found a strange behavior in my app.
After I logined, a permission dialog is pop up, even though I clicked on accept , it is still fall into the authorization exception and show permission not found, how to fix it ?
Thanks
public class SharePicForm extends Activity implements LoginListener,
UploadImageListener {
private final String TAG = "SharePicForm";
public ImageView photoArea;
public ImageView sharePhotoBtn;
public TextView shareTitle;
public EditText shareContent;
public Bitmap mBitmap;
public Context ctx;
public String shareTxt;
public String fileUri;
public static boolean isShowForm = true;
public EasyTracker tracker = null;
public SharedPreferences prefs;
public String catId;
public File savedBitmap;
public Editor editor;
public ProgressDialog pd;
// Facebook share
private PendingAction pendingAction = PendingAction.NONE;
private enum PendingAction {
NONE, POST_PHOTO
}
private Session.StatusCallback callback = new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state,
Exception exception) {
onSessionStateChange(session, state, exception);
}
};
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.share_pic_form);
ctx = this;
prefs = ctx.getSharedPreferences("userInfo", 0);
editor = prefs.edit();
tracker = EasyTracker.getInstance(this);
Utility.setHeader(this, "selfie", false);
Session session = Session.getActiveSession();
if (session == null) {
if (savedInstanceState != null) {
session = Session.restoreSession(this, null, callback,
savedInstanceState);
}
if (session == null) {
session = new Session(this);
}
Session.setActiveSession(session);
if (session.getState().equals(SessionState.CREATED_TOKEN_LOADED)) {
session.openForRead(new Session.OpenRequest(this).setPermissions(Arrays.asList("basic_info","email")).setCallback(callback));
}
}
photoArea = (ImageView) findViewById(R.id.photo_area);
int size = (int) (Utility.getScreenWidth(this) - 220);
RelativeLayout.LayoutParams imgParams = new RelativeLayout.LayoutParams(size, size);
imgParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
imgParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
// imgParams.addRule(RelativeLayout.ABOVE, R.id.share_title);
photoArea.setAdjustViewBounds(true);
photoArea.setLayoutParams(imgParams);
photoArea.setBackgroundResource(android.R.color.darker_gray);
photoArea.getBackground().setAlpha(204); // = 0.8 alpha
shareTitle = (TextView) findViewById(R.id.share_title);
shareContent = (EditText) findViewById(R.id.share_content);
shareContent.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (v.getId() == R.id.share_content) {
v.getParent().requestDisallowInterceptTouchEvent(true);
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_UP:
v.getParent().requestDisallowInterceptTouchEvent(false);
break;
}
}
return false;
}
});
if (getIntent() != null) {
Intent intent = getIntent();
fileUri = (String) intent.getStringExtra("photo");
catId = (String) intent.getStringExtra("catId");
} else if (savedInstanceState != null) {
mBitmap = (Bitmap) savedInstanceState.getParcelable("bitmap") == null ? null
: (Bitmap) savedInstanceState.getParcelable("bitmap");
catId = (String) savedInstanceState.getString("catId");
}
savedBitmap = new File(fileUri);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap beforeScale = BitmapFactory.decodeFile(fileUri, options);
if (beforeScale.getWidth() > 1280) {
mBitmap = ThumbnailUtils.extractThumbnail(beforeScale, 1280, 1280);
FileOutputStream fos;
try {
fos = new FileOutputStream(savedBitmap);
mBitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
mBitmap = beforeScale;
}
if (mBitmap == null) {
Toast.makeText(ctx,ctx.getResources().getString(R.string.get_photo_error),Toast.LENGTH_SHORT).show();
finish();
} else {
photoArea.setImageBitmap(mBitmap);
sharePhotoBtn = (ImageView) findViewById(R.id.share_submit);
sharePhotoBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
tracker.send(MapBuilder.createEvent("form_button",
"Category_form",
"SubmitnShare_" + Utility.getLocale(ctx), null)
.build());
performPublish(PendingAction.POST_PHOTO);
}
});
}
}
// Facebook share
#SuppressWarnings("deprecation")
private void onSessionStateChange(final Session session,
SessionState state, Exception exception) {
Log.d(TAG, "" + exception);
if (pendingAction != PendingAction.NONE && exception != null) {
if (!session.isClosed())
session.closeAndClearTokenInformation(); // reset session
if (exception instanceof FacebookAuthorizationException) {
new AlertDialog.Builder(SharePicForm.this)
.setTitle(ctx.getResources().getString(R.string.error))
.setMessage(
ctx.getResources().getString(
R.string.facebook_permission_missing))
.setPositiveButton(
ctx.getResources().getString(R.string.close),
null).show();
}
pendingAction = PendingAction.NONE;
} else if (state == SessionState.OPENED_TOKEN_UPDATED) {
Request.executeMeRequestAsync(session,
new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser user,
Response response) {
// TODO Auto-generated method stub
if (user != null) {
if (!user.getId().equals(
prefs.getString("fbId", ""))) {
editor.putString("fbId", user.getId());
editor.putString("fName",
user.getFirstName());
editor.putString("lName",
user.getLastName());
if (user.getProperty("email") != null) {
editor.putString("email", user.getProperty("email").toString());
}
editor.commit();
}
if (prefs.getString("memId", "").equals("")
|| prefs.getString("token", "").equals(
"")
|| !user.getId().equals(
prefs.getString("fbId", ""))) {
pd = ProgressDialog.show(
ctx,
getResources().getString(
R.string.sys_info),
getResources().getString(
R.string.loading));
new APIHandler(ctx, tracker, "login", pd)
.execute(ctx,
session.getAccessToken());
} else {
onLoginComplete("", "");
}
}
}
});
} else if (session != null && session.isOpened()) {
session.requestNewPublishPermissions(new Session.NewPermissionsRequest(
this, "publish_actions")); // login complete
}
}
private boolean hasPublishPermission() {
Session session = Session.getActiveSession();
return session != null
&& session.getPermissions().contains("publish_actions");
}
private void handlePendingAction() {
PendingAction previouslyPendingAction = pendingAction;
// These actions may re-set pendingAction if they are still pending, but
// we assume they will succeed.
pendingAction = PendingAction.NONE;
if (previouslyPendingAction == PendingAction.POST_PHOTO) {
MyApp appState = ((MyApp) getApplicationContext());
boolean isGameClose = appState.getState();
if (isGameClose) {
Toast.makeText(this,
getResources().getString(R.string.game_close),
Toast.LENGTH_LONG).show();
} else {
pd = ProgressDialog.show(ctx,
getResources().getString(R.string.sys_info),
getResources().getString(R.string.publishing));
postPhoto();
}
}
}
private void performPublish(PendingAction action) {
Log.d(TAG, "Perform publish");
Session session = Session.getActiveSession();
if (session != null) {
Log.d(TAG, "Session != null");
pendingAction = action;
if (hasPublishPermission()) {
Log.d(TAG, "Has permission");
// We can do the action right away.
handlePendingAction();
return;
} else if (session.isOpened()) {
Log.d(TAG, "Open session");
// We need to get new permissions, then complete the action when
// we get called back.
session.requestNewPublishPermissions(new Session.NewPermissionsRequest(this, "publish_actions"));
return;
} else {
onClickLogin();
}
} else {
Log.d(TAG, "Session == null");
}
}
private void onClickLogin() {
Session session = Session.getActiveSession();
if (!session.isOpened() && !session.isClosed()) {
session.openForRead(new Session.OpenRequest(this).setPermissions(Arrays.asList("basic_info","email")).setCallback(callback));
} else {
Session.openActiveSession(this, true, callback);
}
}
private void postPhoto() {
Log.d(TAG, "postPhoto: " + hasPublishPermission());
if (hasPublishPermission()) {
Request request = Request.newUploadPhotoRequest(
Session.getActiveSession(), mBitmap,
new Request.Callback() {
#Override
public void onCompleted(Response response) {
if (response.getError() == null
&& savedBitmap != null) {
new APIHandler(ctx, tracker, "uploadImg", pd)
.execute(ctx, shareTxt, savedBitmap,
catId);
} else {
if (pd != null)
pd.dismiss();
Log.d(TAG, response.getError()
.getErrorMessage());
Toast.makeText(ctx,
response.getError().getErrorMessage(),
Toast.LENGTH_LONG).show();
Utility.showDialog(ctx, "error", tracker);
}
}
});
Bundle params = request.getParameters();
shareTxt = shareContent.getText().toString().equals("") ? getResources().getString(R.string.default_msg) : shareContent.getText().toString();
params.putString("message", shareTxt);
request.setParameters(params);
request.executeAsync();
} else {
if (pd != null)
pd.dismiss();
pendingAction = PendingAction.POST_PHOTO;
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (mBitmap != null) {
outState.putParcelable("bitmap", mBitmap);
}
if (catId != null) {
outState.putString("catId", catId);
}
Session session = Session.getActiveSession();
Session.saveSession(session, outState);
}
#Override
public void onStart() {
super.onStart();
Session.getActiveSession().addCallback(callback);
EasyTracker.getInstance(this).activityStart(this);
tracker.set(Fields.SCREEN_NAME, "hk7app/CX/" + Utility.getLocale(this)
+ "/Image_entryForm");
tracker.send(MapBuilder.createAppView().build());
}
#Override
public void onStop() {
if (pd != null)
pd.dismiss();
super.onStop();
Session.getActiveSession().removeCallback(callback);
EasyTracker.getInstance(this).activityStop(this);
}
#Override
public void onDestroy() {
if (savedBitmap != null && savedBitmap.exists())
savedBitmap.delete();
super.onDestroy();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Session.getActiveSession().onActivityResult(this, requestCode,
resultCode, data);
}
#Override
public void onResume() {
super.onResume();
AppEventsLogger.activateApp(this,
getResources().getString(R.string.app_id));
}
#Override
public void onLoginComplete(String memberId, String token) {
if (pd != null)
pd.dismiss();
if (!memberId.equals("") && !token.equals("")) {
editor.putString("memId", memberId);
editor.putString("token", token);
editor.commit();
}
handlePendingAction();
}
#Override
public void onLoginFailure(String errorMsg) {
if (pd != null)
pd.dismiss();
Toast.makeText(this, errorMsg, Toast.LENGTH_LONG).show();
}
#Override
public void onImageUploadComplete(int isFormCompleted) {
if (pd != null)
pd.dismiss();
if (isFormCompleted == 1) {
Utility.showDialog(ctx, "success", tracker);
} else {
Intent intent = new Intent(ctx, PersonalInfoForm.class);
ctx.startActivity(intent);
finish();
}
}
#Override
public void onImageUploadFailure(String errorMsg) {
if (pd != null)
pd.dismiss();
Toast.makeText(this, errorMsg, Toast.LENGTH_LONG).show();
}
}
My suggestion would be to use separate Session.StatusCallback implementations for 'login' and 'requestPostPermission'.
private Session.StatusCallback callbackLogin = new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state,
Exception exception) {
session.removeCallback( this );
if ( session.isOpen() ) {
...
} else if ( session.isClosed() ) {
...
}
}
};
and for postPermissions:
private Session.StatusCallback callbackPostPermission = new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state,
Exception exception) {
session.removeCallback( this );
if ( session.isOpen() ) {
if ( session.getPermissions().contains( "publish_actions" ) {
...
} else {
...
}
...
} else if ( session.isClosed() ) {
...
}
}
};
Related
I am new to android and now I am creating a app with splash screen as a launcher activity.
When I am trying to open the app it shows unable to add window token is not valid is your activity running.But if I open the app second time then it is working fine
My code is here:
public class SplashScreenActivity extends Activity {
private String mSavedEmail;
private String mSavedPassword;
public static SplashScreenActivity sInstance = null;
private User mUser;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
setContentView(R.layout.activity_splash_screen);
SplashScreenActivity.sInstance = SplashScreenActivity.this;
/* Initiate Crittercism */
Crittercism.initialize(SplashScreenActivity.this, Const.CRITTERCISM_APP_ID);
new Thread(new Runnable() {
#Override
public void run() {
new CouchDB();
}
}).start();
// new UsersManagement();
String language = SampleApp.getPreferences().getGuiLanguage();
if (!language.equals("")) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
}
if (SampleApp.hasNetworkConnection()) {
if (checkIfUserSignIn()) {
boolean isLinked = false;
mSavedEmail = SampleApp.getPreferences().getUserEmail();
mSavedPassword = SampleApp.getPreferences().getUserPassword();
if (mSavedPassword.equals("")) {
isLinked = true;
mSavedPassword = SampleApp.getPreferences().getUserLinkedPassword();
}
mUser = new User();
CouchDB.authAsync(mSavedEmail, mSavedPassword, isLinked, new AuthListener(), SplashScreenActivity.this, false);
} else {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
startActivity(new Intent(SplashScreenActivity.this,
SignInActivity.class));
//finish();
}
}, 2000);
}
} else {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent intent = new Intent(SplashScreenActivity.this,
SignInActivity.class);
intent.putExtra(Const.SIGN_IN, true);
SplashScreenActivity.this.startActivity(intent);
Log.v("sample", "SplashScreenActivity starts SignInActivity");
Toast.makeText(SplashScreenActivity.this,
getString(R.string.no_internet_connection),
Toast.LENGTH_LONG).show();
}
}, 2000);
}
}
catch (Exception e){
}
}
#Override
protected void onResume() {
super.onResume();
overridePendingTransition(0, 0);
}
private boolean checkIfUserSignIn() {
boolean isSessionSaved = false;
Preferences prefs = LasteekApp.getPreferences();
if (prefs.getUserEmail() == null
|| (prefs.getUserPassword() == null && prefs.getUserLinkedPassword() == null)) {
isSessionSaved = false;
} else if (prefs.getUserEmail().equals("")
&& (prefs.getUserPassword() != null && prefs.getUserPassword().equals(""))) {
isSessionSaved = false;
}
else if (prefs.getUserEmail().equals("")
&& (prefs.getUserLinkedPassword() != null && prefs.getUserLinkedPassword().equals(""))) {
isSessionSaved = false;
}
else {
isSessionSaved = true;
}
return isSessionSaved;
}
private void signIn(User u) {
UsersManagement.setLoginUser(u);
UsersManagement.setToUser(u);
UsersManagement.setToGroup(null);
Log.d("User", "GetEmail "+u.getEmail());
boolean openPushNotification = getIntent().getBooleanExtra(
Const.PUSH_INTENT, false);
Intent intent = new Intent(SplashScreenActivity.this,
MyProfileActivity.class);
if (openPushNotification) {
intent = getIntent();
intent.setClass(SplashScreenActivity.this,
MyProfileActivity.class);
}
//parse URI hookup://user/[ime korisnika] and hookup://group/[ime grupe]
Uri userUri = getIntent().getData();
//If opened from link
if (userUri != null) {
String scheme = userUri.getScheme(); // "hookup"
String host = userUri.getHost(); // "user" or "group"
if (host.equals("user")) {
List<String> params = userUri.getPathSegments();
String userName = params.get(0); // "ime korisnika"
intent.putExtra(Const.USER_URI_INTENT, true);
intent.putExtra(Const.USER_URI_NAME, userName);
} else if (host.equals("group")) {
List<String> params = userUri.getPathSegments();
String groupName = params.get(0); // "ime grupe"
intent.putExtra(Const.GROUP_URI_INTENT, true);
intent.putExtra(Const.GROUP_URI_NAME, groupName);
}
}
intent.putExtra(Const.SIGN_IN, true);
try{
if(u.getName().toString().equals("")||u.getName().toString()==null){
Log.v("lasteek", "SplashScreenActivity starts EditProfileActivity 1");
intent.putExtra(Const.NEWLY_SIGNED_UP, true);
SplashScreenActivity.this.startActivity(intent);
} else if (u.getTitlePosition().toString().equals("")||u.getTitlePosition().toString()==null) {
Log.v("sample", "SplashScreenActivity starts EditProfileActivity 2");
intent.putExtra(Const.NEWLY_SIGNED_UP, true);
SplashScreenActivity.this.startActivity(intent);
} else if (u.getFunction()==null) {
Log.v("sample", "SplashScreenActivity starts EditProfileActivity 3");
intent.putExtra(Const.NEWLY_SIGNED_UP, true);
SplashScreenActivity.this.startActivity(intent);
} else if (u.getIndustry()==null) {
Log.v("sample", "SplashScreenActivity starts EditProfileActivity 4");
intent.putExtra(Const.NEWLY_SIGNED_UP, true);
SplashScreenActivity.this.startActivity(intent);
} else {
Log.v("sample", "SplashScreenActivity starts MyProfileActivity");
SplashScreenActivity.this.startActivity(intent);
}
} catch (Exception e){
Log.e("Exception",e.toString());
}
//finish();
}
private void checkPassProtect (User user) {
if (sample.getPreferences().getPasscodeProtect())
{
Intent passcode = new Intent(SplashScreenActivity.this,
PasscodeActivity.class);
passcode.putExtra("protect", true);
SplashScreenActivity.this.startActivityForResult(passcode, 0);
}
else
{
signIn(user);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
signIn(mUser);
}
else {
startActivity(new Intent(SplashScreenActivity.this,
SignInActivity.class));
//finish();
}
super.onActivityResult(requestCode, resultCode, data);
}
private boolean authentificationOk(User user) {
boolean authentificationOk = false;
if (user.getEmail() != null && !user.getEmail().equals("")) {
if (user.getEmail().equals(mSavedEmail)) {
authentificationOk = true;
}
}
return authentificationOk;
}
private class AuthListener implements ResultListener<String>
{
#Override
public void onResultsSucceded(String result) {
boolean tokenOk = result.equals(Const.LOGIN_SUCCESS);
mUser = UsersManagement.getLoginUser();
if (tokenOk && mUser!=null) {
if (authentificationOk(mUser)) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
checkPassProtect(mUser);
}
}, 2000);
}
} else {
SideBarActivity.appLogout(false, false, true, false);
}
}
#Override
public void onResultsFail() {
SideBarActivity.appLogout(false, false, false, true);
}
}
public void onStart() {
super.onStart();
try {
if (SharedData.runningActivities == 0) {
// app enters foreground
}
SharedData.runningActivities++;
Log.v("sample.activitymonitor", "SplashScreenActivity enters foreground");
Log.v("sample.activitymonitor", "runningActivities=" + SharedData.runningActivities);
}
catch (Exception e){
}
}
public void onStop() {
super.onStop();
SharedData.runningActivities--;
if (SharedData.runningActivities == 0) {
// app goes to background
}
Log.v("sample.activitymonitor", "SplashScreenActivity enters background");
Log.v("sample.activitymonitor", "runningActivities=" + SharedData.runningActivities);
}
}
There are two activity in my app to handle the 1) login 2)share image (if not login , login first then share)
The problem is when I include all code in one activity it works. But when I put the login in a fragment , the share image in another activity, then the login is work , but the share image activity behave incorrectly (Ask me to login even it is logined , and will not trigger the share image action)
Login Fragment:
public class Home extends Fragment {
public View rootView;
public ImageView HomeBg;
public ImageView buttonLoginLogout;
public TextView chi;
public TextView eng;
public ColorStateList oldColor;
public SharedPreferences prefs;
//Facebook login
private Session.StatusCallback statusCallback = new SessionStatusCallback();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
getActivity().getActionBar().hide();
rootView = inflater.inflate(R.layout.home, container, false);
buttonLoginLogout = (ImageView) rootView.findViewById(R.id.home_connectFB);
eng = (TextView) rootView.findViewById(R.id.btn_eng);
chi = (TextView) rootView.findViewById(R.id.btn_chi);
if (getActivity().getResources().getConfiguration().locale
.equals(Locale.TRADITIONAL_CHINESE)) {
chi.setTextColor(getActivity().getResources().getColor(
android.R.color.white));
oldColor = eng.getTextColors();
} else {
eng.setTextColor(getActivity().getResources().getColor(
android.R.color.white));
oldColor = chi.getTextColors();
}
eng.setOnClickListener(setChangeLangListener("en"));
chi.setOnClickListener(setChangeLangListener("zh"));
//Facebook login
Settings.addLoggingBehavior(LoggingBehavior.INCLUDE_ACCESS_TOKENS);
Session session = Session.getActiveSession();
if (session == null) {
if (savedInstanceState != null) {
session = Session.restoreSession(getActivity(), null, statusCallback, savedInstanceState);
}
if (session == null) {
session = new Session(getActivity());
}
Session.setActiveSession(session);
if (session.getState().equals(SessionState.CREATED_TOKEN_LOADED)) {
session.openForRead(new Session.OpenRequest(this).setCallback(statusCallback));
}
}
updateView();
return rootView;
}
#Override
public void onStart() {
super.onStart();
Session.getActiveSession().addCallback(statusCallback);
}
#Override
public void onStop() {
super.onStop();
Session.getActiveSession().removeCallback(statusCallback);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Session.getActiveSession().onActivityResult(getActivity(), requestCode, resultCode, data);
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Session session = Session.getActiveSession();
Session.saveSession(session, outState);
}
private void updateView() {
Session session = Session.getActiveSession();
if (session.isOpened()) {
buttonLoginLogout.setImageResource(R.drawable.landing_btn_take_a_selfie);
buttonLoginLogout.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
((LandingPage)getActivity()).tabHost.setCurrentTab(2);
}
});
} else {
buttonLoginLogout.setImageResource(R.drawable.landing_btn_connect_facebook);
buttonLoginLogout.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) { onClickLogin(); }
});
}
}
private void onClickLogin() {
Session session = Session.getActiveSession();
if (!session.isOpened() && !session.isClosed()) {
session.openForRead(new Session.OpenRequest(this).setCallback(statusCallback));
} else {
Session.openActiveSession(getActivity(), this, true, statusCallback);
}
}
private class SessionStatusCallback implements Session.StatusCallback {
#Override
public void call(Session session, SessionState state, Exception exception) {
updateView();
}
}
public OnClickListener setChangeLangListener(final String lang) {
OnClickListener changeLangListener = new OnClickListener() {
#Override
public void onClick(View arg0) {
Configuration config = new Configuration(getResources()
.getConfiguration());
if (lang.equals("en")) {
config.locale = Locale.ENGLISH;
chi.setTextColor(oldColor);
eng.setTextColor(getActivity().getResources().getColor(
android.R.color.white));
} else {
config.locale = Locale.TRADITIONAL_CHINESE;
eng.setTextColor(oldColor);
chi.setTextColor(getActivity().getResources().getColor(
android.R.color.white));
}
getResources().updateConfiguration(config,getResources().getDisplayMetrics());
onConfigurationChanged(config);
}
};
return changeLangListener;
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Intent intent = getActivity().getIntent();
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
getActivity().finish();
startActivity(intent);
}
}
Image Share Activity:
public class SharePicForm extends Activity {
private final String TAG = "SharePicForm";
public ImageView photoArea;
public ImageView sharePhotoBtn;
public EditText shareContent;
public Bitmap mBitmap;
public Context ctx;
public String shareTxt;
//Facebook share
private Session.StatusCallback statusCallback = new SessionStatusCallback();
private PendingAction pendingAction = PendingAction.NONE;
private enum PendingAction {
NONE, POST_PHOTO
}
public static boolean isShowForm = true;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.share_pic_form);
ctx = this;
Utility.setHeader(this,R.string.selfie_header,false);
photoArea = (ImageView) findViewById(R.id.photo_area);
shareContent = (EditText) findViewById(R.id.share_content);
Intent intent = getIntent();
String fileUri = (String) intent.getStringExtra("photo");
FileInputStream inputStream;
try {
File imgSelected = new File(fileUri);
if (imgSelected.exists()) {
inputStream = new FileInputStream(imgSelected);
mBitmap = Utility.decodeBitmap(inputStream, 1280, 960);
photoArea.setImageBitmap(mBitmap);
sharePhotoBtn = (ImageView) findViewById(R.id.share_submit);
sharePhotoBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (mBitmap != null && FormValidation.hasText(shareContent)) {
try {
File imageToShare = saveBitmapToStorage();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
shareTxt = shareContent.getText().toString();
Session session = Session.getActiveSession();
if (session.isOpened()) {
Log.d(TAG,"logined");
performPublish(PendingAction.POST_PHOTO);
} else {
Log.d(TAG,"not logined");
onClickLogin();
}
//new FormSubmit(ctx).execute("shareImg",imageToShare, textToShare);
}
}
});
} else {
Utility.showDialog(ctx,"error");
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private File saveBitmapToStorage () throws IOException{
String path = Environment.getExternalStorageDirectory().toString();
File outputFile = new File(path, "temp.jpg");
FileOutputStream out = new FileOutputStream(outputFile);
mBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
return outputFile;
}
//Facebook share
private void onClickLogin() {
Session session = Session.getActiveSession();
if (!session.isOpened() && !session.isClosed()) {
session.openForRead(new Session.OpenRequest(this).setCallback(statusCallback));
} else {
Session.openActiveSession(this, true, statusCallback);
}
}
private class SessionStatusCallback implements Session.StatusCallback {
#Override
public void call(Session session, SessionState state, Exception exception) {
if (pendingAction != PendingAction.NONE &&
(exception instanceof FacebookOperationCanceledException ||
exception instanceof FacebookAuthorizationException)) {
new AlertDialog.Builder(ctx)
.setTitle("Cancel")
.setMessage("No grant permission")
.setPositiveButton("ok", null)
.show();
pendingAction = PendingAction.NONE;
} else if (state == SessionState.OPENED_TOKEN_UPDATED) {
handlePendingAction();
}
performPublish(PendingAction.POST_PHOTO);
}
}
private boolean hasPublishPermission() {
Session session = Session.getActiveSession();
return session != null
&& session.getPermissions().contains("publish_actions");
}
private void handlePendingAction() {
PendingAction previouslyPendingAction = pendingAction;
// These actions may re-set pendingAction if they are still pending, but we assume they will succeed.
pendingAction = PendingAction.NONE;
if (previouslyPendingAction == PendingAction.POST_PHOTO)
postPhoto();
}
private void performPublish(PendingAction action) {
Session session = Session.getActiveSession();
if (session != null) {
Log.d(TAG,"session != null");
pendingAction = action;
if (hasPublishPermission()) {
Log.d(TAG,"Has permission");
// We can do the action right away.
handlePendingAction();
return;
} else if (session.isOpened()) {
Log.d(TAG,"No permission");
// We need to get new permissions, then complete the action when we get called back.
session.requestNewPublishPermissions(new Session.NewPermissionsRequest(this, "publish_actions"));
return;
}
Log.d(TAG,"Session not open");
}
Log.d(TAG,"Session null");
}
private void postPhoto() {
Log.d(TAG,"postPhoto: " + hasPublishPermission());
if (hasPublishPermission()) {
if (mBitmap != null) {
Request request = Request.newUploadPhotoRequest(
Session.getActiveSession(),mBitmap, new Request.Callback() {
#Override
public void onCompleted(Response response) {
showPublishResult(response.getError());
}
});
Bundle params = request.getParameters();
if (shareTxt != null)
params.putString("message", shareTxt);
request.setParameters(params);
request.executeAsync();
}
} else {
pendingAction = PendingAction.POST_PHOTO;
}
}
private void showPublishResult(FacebookRequestError error) {
if (error == null) {
Utility.showDialog(ctx,"success_photo");
} else {
Utility.showDialog(ctx,"error");
}
}
}
Thanks for helping. Any help is appreciate thanks.
Log for the share image activity
02-11 02:18:17.914: D/SharePicForm(21646): logined
02-11 02:18:17.914: D/SharePicForm(21646): session != null
02-11 02:18:17.914: D/SharePicForm(21646): No permission
You are missing the 'UiLifecycleHelper's' implementation in your Fragment:
private UiLifecycleHelper uiHelper;
private Session.StatusCallback callback = new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
//Do what ever you want to do here
}
};
onCreate(....)
{
uiHelper = new UiLifecycleHelper(VideoShareActivity.this, callback);
uiHelper.onCreate(savedInstanceState);
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
uiHelper.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
uiHelper.onDestroy();
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
uiHelper.onSaveInstanceState(outState);
}
Now your Session.getActiveSession() should not return null.
I hope this helps.
I am working on Facebook integration on my Android app. It's working fine on some device, but on some device it's not working and give me error message:
Below is the code :
private UiLifecycleHelper uiHelper;
private Session.StatusCallback callback = new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
onSessionStateChange(session, state, exception);
}
};
private void onSessionStateChange(Session session, SessionState state, Exception exception) {
if ( exception instanceof FacebookOperationCanceledException ||
exception instanceof FacebookAuthorizationException)
{
new AlertDialog.Builder(MainWindow.this)
.setTitle("cancel")
.setMessage("your permission has expired.")
.setPositiveButton("ok", null)
.show();
}
}
private void onClickFacebookRequest()
{
if (session.isOpened())
{
sendRequests();
} else {
StatusCallback callback = new StatusCallback() {
public void call(Session session, SessionState state, Exception exception) {
if (exception != null) {
new AlertDialog.Builder(MainWindow.this)
.setTitle(R.string.login_failed_dialog_title)
.setMessage(exception.getMessage())
.setPositiveButton(R.string.ok_button, null)
.show();
session = createSession();
}
}
};
pendingRequest = true;
session.openForRead(new Session.OpenRequest(this).setCallback(callback));
}
}
private static final List<String> PERMISSIONS = Arrays.asList("publish_actions");
private static final String PENDING_PUBLISH_KEY = "pendingPublishReauthorization";
private void sendRequests()
{
List<String> permissions = quytechApps.getSession().getPermissions();
if (!isSubsetOf(PERMISSIONS, permissions)) {
pendingRequest = true;
Session.NewPermissionsRequest newPermissionsRequest = new Session
.NewPermissionsRequest(this, PERMISSIONS);
session.requestNewPublishPermissions(newPermissionsRequest);
return;
}
showValidationDialog("Please Wait.posting Data on Facebook");
Bitmap image = BitmapFactory.decodeResource(this.getResources(), R.drawable.splash_screen_final4);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
Bundle postParams=new Bundle();
postParams.putByteArray("photo",byteArray);
postParams.putString("message", "Hi Friends I am using Twinqli Chat App.");
Request request = new Request(Session.getActiveSession(), "me/photos", postParams, HttpMethod.POST, new Request.Callback()
{
#Override
public void onCompleted(Response response) {
// TODO Auto-generated method stub
// showPublishResult(getString(R.string.photo_post), response.getGraphObject(), response.getError());
if(response.getError() == null)
{
Log.d("GraphApiSample.java Sucesses","sucess");
dismissValidatingDialog();
}
else
{
dismissValidatingDialog();
session.closeAndClearTokenInformation();
//quytechApps.getSession().
//quytechApps.setSession(null);
// Log.d("GraphApiSample.java",""+response.getError().getErrorMessage());
}
}
});
request.executeAsync();
}
private boolean isSubsetOf(Collection<String> subset, Collection<String> superset) {
for (String string : subset) {
if (!superset.contains(string)) {
return false;
}
}
return true;
}
static final String applicationId = "390611174384274";
boolean pendingRequest;
static final String PENDING_REQUEST_BUNDLE_KEY = "com.facebook.samples.graphapi:PendingRequest";
private Session createSession()
{
Session activeSession = Session.getActiveSession();
if (activeSession == null || activeSession.getState().isClosed())
{
activeSession = new Session.Builder(this).setApplicationId(applicationId).build();
Session.setActiveSession(activeSession);
}
return activeSession;
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (qsession.onActivityResult(this, requestCode, resultCode, data) &&
pendingRequest &&
session.getState().isOpened()) {
sendRequests();
}
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
pendingRequest = savedInstanceState.getBoolean(PENDING_REQUEST_BUNDLE_KEY, pendingRequest);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(PENDING_REQUEST_BUNDLE_KEY, pendingRequest);
}
Can anyone tell me what's wrong in my code?
This problem normally occurs when the facebook app in your phone is not updated so please update it and then check.
It worked for me hope it will work for you also.
EDIT:
To check the hash key put this in your onCreate Method
PackageInfo info;
try {
info = getPackageManager().getPackageInfo("com.example.yourpackagename", PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md;
md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
String something = new String(Base64.encode(md.digest(), 0));
//String something = new String(Base64.encodeBytes(md.digest()));
Log.e("hash key", something);
}
} catch (NameNotFoundException e1) {
Log.e("name not found", e1.toString());
} catch (NoSuchAlgorithmException e) {
Log.e("no such an algorithm", e.toString());
} catch (Exception e) {
Log.e("exception", e.toString());
}
I am using Facebook in my android app and it work just fine.
However, i realize that useless screen appears when i login every time saying that "you have already-authorized to this app" with OK and Cancel option.
How can i avoid or remove this screen from my app.
I searched on Google and i found some answer for older Facebook SDK But how to achieve it with new Facebook SDK(3.0 and above)?
this is my code,
public void onClick(View v)
{
Bundle myParams = new Bundle();
myParams.putString("message", " DOWNLOAD THE 'Saragama' ANDROID APP FROM " + url_android.toString()
+ ". Fully integrated with Facebook and Twitter.");
myParams.putString("name", mSharingText.getText().toString());
myParams.putString("caption", "www.saragama.com");
myParams.putString("description", "Various religios music, chants, mantras, christian songs, islamic music, quran and more on saragama");
myParams.putString("link", "http://android.saragama.com");
myParams.putString("picture", albumImageURL);
if (PlusUtilities.isInternetConnected())
{
// ~post your data
Session session = Session.getActiveSession();
if (session != null)
{
MyLog.w("session state", session.getState().toString());
if (session.getState().equals(SessionState.OPENED) || session.getState().equals(SessionState.OPENED_TOKEN_UPDATED))
{
publishStory(myParams);
}
else
{
plusUtilities1.showAlertDialog("Please login first!");
}
}
else
{
plusUtilities1.showAlertDialog("Please login first!");
}
}
else
{
plusUtilities1.showAlertDialog("Problem occured with your internet connection!");
}
}
// Facebook Login-------------------------------------------------------------------------------------
private void loginToFacebook()
{
if (PlusUtilities.isInternetConnected())
{
Session session = Session.getActiveSession();
// if session is in exceptional state
if (session.getState() == SessionState.CLOSED_LOGIN_FAILED || session.getState() == SessionState.OPENING)
{
session.closeAndClearTokenInformation();
}
if (!session.isOpened() && !session.isClosed())
{
String[] PERMISSION_ARRAY_PUBLISH =
{"publish_actions" };
List<String> PERMISSION_LIST = Arrays.asList(PERMISSION_ARRAY_PUBLISH);
session.openForPublish(new Session.OpenRequest(FacebookActivity.this).setPermissions(PERMISSION_LIST).setCallback(
statusCallback1));
}
else
{
Session.openActiveSession(this, true, statusCallback1);
}
}
else
{
plusUtilities1.showAlertDialog("Please check your internet connection!");
}
}
#Override
protected void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
Session session = Session.getActiveSession();
Session.saveSession(session, outState);
}
#Override
protected void onActivityResult(int requestCode, int responseCode, Intent data)
{
super.onActivityResult(requestCode, responseCode, data);
// plusUtilities1.ShowToast("onActivityResult");
MyLog.i("onActivityResult requestCode :responsecode:session state", requestCode + ":" + responseCode + ":"
+ Session.getActiveSession().getState().toString());
switch (requestCode)
{
case MyRaagaLoginActivity.REQUEST_CODE_FACEBOOK_LOGIN:
if (responseCode == RESULT_OK)
{
MyLog.e("Login", "trying to facebook Login");
Session.getActiveSession().onActivityResult(Act1, requestCode, responseCode, data);
}
else
{
plusUtilities1.ShowToast("User access denied!");
}
break;
default:
MyLog.i("case:", "default");
break;
}
}
/**
* function to get active facebook session if already exist or create the new session
*
* #param savedInstanceState
* =check if Session exist and restored in bundle during onSaveInstanceState() system call
* #author DeepakD
*/
public void GetOrCreateFacebookActiveSession(Bundle savedInstanceState)
{
Settings.addLoggingBehavior(LoggingBehavior.INCLUDE_ACCESS_TOKENS);
Settings.addLoggingBehavior(LoggingBehavior.REQUESTS);
Session session = Session.getActiveSession();
// if session is null try to find if session is saved previously
if (session == null)
{
if (savedInstanceState != null)
{
session = Session.restoreSession(this, null, statusCallback1, savedInstanceState);
}
// if still session is null then create the new session
if (session == null)
{
session = new Session(this);
}
// set the created session as active session
Session.setActiveSession(session);
}
updateFBbutton();
}
/**
* set login or logout button
*/
private void updateFBbutton()
{
Session session = Session.getActiveSession();
if (session.isOpened())
{
FbLoginbtn.setText("FBLogout");
FbLoginbtn.setOnClickListener(new OnClickListener()
{
public void onClick(View view)
{
onClickFBLogout();
}
});
}
else
{
FbLoginbtn.setText("FBLogin");
FbLoginbtn.setOnClickListener(new OnClickListener()
{
public void onClick(View view)
{
loginToFacebook();
}
});
}
}
/**
* Logout from facebook
*/
private void onClickFBLogout()
{
Session session = Session.getActiveSession();
if (!session.isClosed())
{
session.closeAndClearTokenInformation();
plusUtilities1.ShowToast("Logout successful");
}
}
/**
* This class is used to fetch the current status of active session
*
* #author DeepakD
*
*/
private class SessionStatusCallback1 implements Session.StatusCallback
{
#Override
public void call(Session session, SessionState state, Exception exception)
{
updateFBbutton();
plusUtilities1.DissmissPD();
MyLog.w("session state", session.getState().toString());
if(session.getState()==SessionState.CLOSED_LOGIN_FAILED)
{
//login failed
plusUtilities1.ShowToast("Unable to connect,please try later..");
session.closeAndClearTokenInformation();
}
if (session.getState()== SessionState.OPENED)
{
//login successful
plusUtilities1.ShowToast("Login successful");
}
}
}
/**
* actually post the data on facebook
*
* #param myParams
* Bundle of parameters to be post
*/
private void publishStory(Bundle myParams)
{
plusUtilities1.ShowPD("Sharing data...");
Session session = Session.getActiveSession();
if (session != null)
{
// Check for publish permissions
List<String> permissions = session.getPermissions();
try
{
if (!isSubsetOf(PERMISSIONS, permissions))
{
Session.NewPermissionsRequest newPermissionsRequest = new Session.NewPermissionsRequest(this, PERMISSIONS);
session.requestNewPublishPermissions(newPermissionsRequest);
}
}
catch (Exception e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
Request.Callback callback = new Request.Callback()
{
public void onCompleted(Response response)
{
plusUtilities1.DissmissPD();
MyLog.w("post response", "" + response.toString());
if (response.getError() == null)
{
JSONObject graphResponse = response.getGraphObject().getInnerJSONObject();
String postId = null;
try
{
postId = graphResponse.getString("id");
}
catch (JSONException e)
{
Toast.makeText(FacebookActivity.this, "JSON error " + e.getMessage(), Toast.LENGTH_LONG)
.show();
}
catch (Exception e)
{
e.printStackTrace();
Toast.makeText(FacebookActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
}
FacebookRequestError error = response.getError();
Log.e("post response", response.toString());
if (error != null)
{
Toast.makeText(FacebookActivity.this, error.getErrorMessage(), Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(FacebookActivity.this, "Posted successfully!",
Toast.LENGTH_LONG).show();
FlurryAgent.logEvent("Audio Facebook share -" + EventName);
}
}
else
{
plusUtilities1.showAlertDialog("Something went wrong while posting!");
}
}
};
MyLog.w("BUNDLE TO BE POSTED;", myParams.toString());
Request request = new Request(session, "/me/feed", myParams, HttpMethod.POST, callback);
RequestAsyncTask task = new RequestAsyncTask(request);
task.execute();
}
}
public static boolean isSubsetOf(Collection<String> subset, Collection<String> superset)
{
for (String string : subset)
{
if (!superset.contains(string))
{
return false;
}
}
return true;
}
protected void onStart()
{
super.onStart();
MyLog.i("FacebookActivity", "onStart");
FlurryAgent.onStartSession(this, KeysCls.Flurry_Analytics_Key);
FlurryAds.displayAd(this, "AppCircle_Ads", linlayAdLayout);
if (PlusUtilities.isInternetConnected())
{
Session.getActiveSession().addCallback(statusCallback1);
}
else
{
plusUtilities1.showAlertDialog("Please check your internet connection and try again!");
}
}
/**
* convert post's simple text to text with links
*
* #param Name
* #param Link
* #return
*/
String wallpostWithLink(String Name, String Link)
{
jo = new JSONObject();
try
{
jo.put("name", Name);
jo.put("link", Link);
}
catch (Exception e)
{
e.printStackTrace();
}
return jo.toString();
}
#Override
protected void onStop()
{
super.onStop();
FlurryAgent.onEndSession(this);
}
Go to developers.facebook.com and in Settings-> Basic->Single Sign On -> YES
In facebook sdk 4.0 try to activate and deactivate app in onResume and onPause like this:
#Override
protected void onResume() {
super.onResume();
// update your UI
// Logs 'install' and 'app activate' App Events.
AppEventsLogger.activateApp(this);
}
#Override
protected void onPause() {
super.onPause();
// Logs 'app deactivate' App Event.
AppEventsLogger.deactivateApp(this);
}
I am new to the facebook sdk, so I am not really too sure why I am getting this error. I have narrowed it down to this section:
List<String> permissions = session.getPermissions();
if (!isSubsetOf(PERMISSIONS, permissions)) {
pendingPublishReauthorization = true;
Session.NewPermissionsRequest newPermissionsRequest = new Session
.NewPermissionsRequest(this, PERMISSIONS);
Here>> session.requestNewPublishPermissions(newPermissionsRequest); <<Here
return;
} //this code is located below in the publishStory() method
I followed both the Authenticate tutorial, and the Publish Feed tutorial exactly as is, with a bit of reordering to suit my needs. I am not sure what I could have possibly missed. I will post the SelectionFragment class, which I put the post status stuff to because its where a user is logged in. Just to make sure this is clear, logging in works perfectly. But when I try to click post status it does nothing. The second time I click it, it crashes. Any explanation would be most appreciated.
public class SelectionFragment extends Fragment{
private static final int REAUTH_ACTIVITY_CODE = 100;
private ProfilePictureView profilePictureView;
private TextView userNameView;
private UiLifecycleHelper uiHelper;
private Button shareButton;
private static final List<String> PERMISSIONS = Arrays.asList("publish_actions");
private static final String PENDING_PUBLISH_KEY = "pendingPublishReauthorization";
protected static final String TAG = "SelectionFragment.java";
private boolean pendingPublishReauthorization = false;
private Session.StatusCallback callback = new Session.StatusCallback() {
#Override
public void call(final Session session, final SessionState state, final Exception exception) {
onSessionStateChange(session, state, exception);
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
uiHelper = new UiLifecycleHelper(getActivity(), callback);
uiHelper.onCreate(savedInstanceState);
}//end of onCreate()
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.selection, container, false);
// Find the user's profile picture custom view
profilePictureView = (ProfilePictureView) view.findViewById(R.id.selection_profile_pic);
profilePictureView.setCropped(true);
// Find the user's name view
userNameView = (TextView) view.findViewById(R.id.selection_user_name);
//find the share button
shareButton = (Button) view.findViewById(R.id.shareButton);
shareButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
publishStory();
}
});
// Check for an open session
Session session = Session.getActiveSession();
if (session != null && session.isOpened()) {
// Get the user's data
makeMeRequest(session);
}
if (savedInstanceState != null) {
pendingPublishReauthorization =
savedInstanceState.getBoolean(PENDING_PUBLISH_KEY, false);
}
return view;
}//end of onCreateView
/*
* Private method that requests users data
* */
private void makeMeRequest(final Session session) {
// Make an API call to get user data and define a
// new callback to handle the response.
Request request = Request.newMeRequest(session,
new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser user, Response response) {
// If the response is successful
if (session == Session.getActiveSession()) {
if (user != null) {
// Set the id for the ProfilePictureView
// view that in turn displays the profile picture.
profilePictureView.setProfileId(user.getId());
// Set the Textview's text to the user's name.
userNameView.setText(user.getName());
}
}
if (response.getError() != null) {
// Handle errors, will do so later.
}
}
});
request.executeAsync();
}
/*
* private method that will respond to session changes and call
* the makeMeRequest() method if the session's open
* */
private void onSessionStateChange(final Session session, SessionState state, Exception exception) {
if (session != null && session.isOpened()) {
// Get the user's data.
makeMeRequest(session);
}
/*The following checks if user is logged in and hides or shows the share button*/
if (state.isOpened()) {
shareButton.setVisibility(View.VISIBLE);
if (pendingPublishReauthorization &&
state.equals(SessionState.OPENED_TOKEN_UPDATED)) {
pendingPublishReauthorization = false;
publishStory();
}
} else if (state.isClosed()) {
shareButton.setVisibility(View.INVISIBLE);
}
}//end of onSessionStateChanged
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REAUTH_ACTIVITY_CODE) {
uiHelper.onActivityResult(requestCode, resultCode, data);
}
}
#Override
public void onResume() {
super.onResume();
uiHelper.onResume();
}
#Override
public void onSaveInstanceState(Bundle bundle) {
super.onSaveInstanceState(bundle);
bundle.putBoolean(PENDING_PUBLISH_KEY, pendingPublishReauthorization);
uiHelper.onSaveInstanceState(bundle);
}
#Override
public void onPause() {
super.onPause();
uiHelper.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
uiHelper.onDestroy();
}
/*
* What actually publishes the status update
* */
private void publishStory() {
Session session = Session.getActiveSession();
if (session != null){
// Check for publish permissions
List<String> permissions = session.getPermissions();
if (!isSubsetOf(PERMISSIONS, permissions)) {
pendingPublishReauthorization = true;
Session.NewPermissionsRequest newPermissionsRequest = new Session
.NewPermissionsRequest(this, PERMISSIONS);
session.requestNewPublishPermissions(newPermissionsRequest);
return;
}
Bundle postParams = new Bundle();
postParams.putString("name", "Facebook SDK for Android");
postParams.putString("caption", "Build great social apps and get more installs.");
postParams.putString("description", "The Facebook SDK for Android makes it easier and faster to develop Facebook integrated Android apps.");
postParams.putString("link", "https://developers.facebook.com/android");
postParams.putString("picture", "https://raw.github.com/fbsamples/ios-3.x-howtos/master/Images/iossdk_logo.png");
Request.Callback callback= new Request.Callback() {
public void onCompleted(Response response) {
JSONObject graphResponse = response
.getGraphObject()
.getInnerJSONObject();
String postId = null;
try {
postId = graphResponse.getString("id");
} catch (JSONException e) {
Log.i(TAG,
"JSON error "+ e.getMessage());
}
FacebookRequestError error = response.getError();
if (error != null) {
Toast.makeText(getActivity()
.getApplicationContext(),
error.getErrorMessage(),
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getActivity()
.getApplicationContext(),
postId,
Toast.LENGTH_LONG).show();
}
}
};
Request request = new Request(session, "me/feed", postParams,
HttpMethod.POST, callback);
RequestAsyncTask task = new RequestAsyncTask(request);
task.execute();
}
}//end of publishStory
private boolean isSubsetOf(Collection<String> subset, Collection<String> superset) {
for (String string : subset) {
if (!superset.contains(string)) {
return false;
}
}
return true;
}
}//end of class
Edit
Ok so I was able to finally post, but now I have figured out why its crashing still. The last method in the above class, isSubset seems to always return false, meaning it will always run, even if the publish permission was already created.
Edit 2
public class FacebookFrag extends FragmentActivity {
private static final int SPLASH = 0;
private static final int SELECTION = 1;
private static final int SETTINGS = 2;
private static final int FRAGMENT_COUNT = SETTINGS +1;
private Fragment[] fragments = new Fragment[FRAGMENT_COUNT];
private MenuItem settings;
//flag that indicates a visible activity
private boolean isResumed = false;
private UiLifecycleHelper uiHelper;
private Session.StatusCallback callback =
new Session.StatusCallback() {
#Override
public void call(Session session,
SessionState state, Exception exception) {
onSessionStateChange(session, state, exception);
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.facebook_layout);
FragmentManager fm = getSupportFragmentManager();
fragments[SPLASH] = fm.findFragmentById(R.id.splashFragment);
fragments[SELECTION] = fm.findFragmentById(R.id.selectionFragment);
fragments[SETTINGS] = fm.findFragmentById(R.id.userSettingsFragment);
FragmentTransaction transaction = fm.beginTransaction();
for(int i = 0; i < fragments.length; i++) {
transaction.hide(fragments[i]);
}
transaction.commit();
uiHelper = new UiLifecycleHelper(this, callback);
uiHelper.onCreate(savedInstanceState);
}
private void showFragment(int fragmentIndex, boolean addToBackStack) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
for (int i = 0; i < fragments.length; i++) {
if (i == fragmentIndex) {
transaction.show(fragments[i]);
} else {
transaction.hide(fragments[i]);
}
}
if (addToBackStack) {
transaction.addToBackStack(null);
}
transaction.commit();
}
private void onSessionStateChange(Session session, SessionState state, Exception exception) {
// Only make changes if the activity is visible
if (isResumed) {
FragmentManager manager = getSupportFragmentManager();
// Get the number of entries in the back stack
int backStackSize = manager.getBackStackEntryCount();
// Clear the back stack
for (int i = 0; i < backStackSize; i++) {
manager.popBackStack();
}
if (state.isOpened()) {
// If the session state is open:
// Show the authenticated fragment
showFragment(SELECTION, false);
} else if (state.isClosed()) {
// If the session state is closed:
// Show the login fragment
showFragment(SPLASH, false);
}
}
}
#Override
protected void onResumeFragments() {
super.onResumeFragments();
Session session = Session.getActiveSession();
if (session != null && session.isOpened()) {
// if the session is already open,
// try to show the selection fragment
showFragment(SELECTION, false);
} else {
// otherwise present the splash screen
// and ask the person to login.
showFragment(SPLASH, false);
}
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// only add the menu when the selection fragment is showing
if (fragments[SELECTION].isVisible()) {
if (menu.size() == 0) {
settings = menu.add(R.string.settings);
}
return true;
} else {
menu.clear();
settings = null;
}
return false;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.equals(settings)) {
showFragment(SETTINGS, true);
return true;
}
return false;
}
#Override
public void onResume() {
super.onResume();
uiHelper.onResume();
isResumed = true;
}
#Override
public void onPause() {
super.onPause();
uiHelper.onPause();
isResumed = false;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
uiHelper.onActivityResult(requestCode, resultCode, data);
}
#Override
public void onDestroy() {
super.onDestroy();
uiHelper.onDestroy();
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
uiHelper.onSaveInstanceState(outState);
}
}//end of class
just remove the return from your publishstory();And make sure that your session is in OPEN state when you call publishstory().
//
if(isNetworkAvailable()){
/* ~post your data only if session is in OPEN state also check
for login and internet connection*/
Session session=Session.getActiveSession();
if(session!=null){
MyLog.w("session state",session.getState().toString());
if(session.getState()==SessionState.OPENED){
publishStory();
}else{
showAlertDialog("Unable to Share");
}
}else{
showAlertDialog("Please login first!");
}
}else{
showAlertDialog("Problem occured with your internet connection");
}
remove return statement
if (!isSubsetOf(PERMISSIONS, permissions)) {
pendingPublishReauthorization = true;
Session.NewPermissionsRequest newPermissionsRequest = new Session
.NewPermissionsRequest(this, PERMISSIONS);
session.requestNewPublishPermissions(newPermissionsRequest);
`Remove this===>` return;
}
Normally, when you got UnsupportedOperationException, it means that the device cannot find the method that used in your app.
Something you need to check:
The Android version of emulator or test device must be greater than the Min SDK?
All the library is included and exported correctly?