so I'm trying to refactor my app that uses the Facebook API to use fragments instead of activities. Before, after logging in with Facebook, I would get taken to a new activity - now, I'm trying to use fragments instead. However, ever since I started using fragments, it's been failing during requests, giving me an error "Session provided to a Request in un-opened state"
I added all the UIHelper lifecycle methods to my fragment, but I'm still getting the error. I basically copied the exact code that the example fragment uses, and I'm still getting this issue. Can anybody help me out? Here's my fragment, and the activity that sets it up (most of it is stock code taken directly from Facebook's example)
Fragment:
public class ConvoFragment extends Fragment {
String name;
ListView convos;
SwipeRefreshLayout rootView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
rootView = (SwipeRefreshLayout)inflater.inflate(R.layout.convos_fragment,
container, false);
convos = (ListView) rootView.findViewById(R.id.conversation_list);
name = getActivity().getSharedPreferences("global", 0).getString("myName", "");
Session session = Session.getActiveSession();
RequestAsyncTask req = new Request(session, "/me/inbox/", null, HttpMethod.GET, new Request.Callback()
{
public void onCompleted(Response response)
{
final Response resp = response;
try
{
if (response != null)
{
GraphObject asdf2 = response.getGraphObject();
Log.i("graphobject", response.toString());
//This logs the Session Provided to Request in unopened state error. Everything below will fail
JSONObject obj = asdf2.getInnerJSONObject();
JSONArray threads= obj.getJSONArray("data");
final ConvoAdapter adapter = new ConvoAdapter(getActivity(), convertArray(threads), name);
convos.setAdapter(adapter);
setupRefreshListener();
setupItemListener(adapter);
}
}
catch (JSONException e)
{
e.printStackTrace();
}
}
}).executeAsync();
return rootView;
}
So it fails right as it makes the request, because the request essentially returns null. Here's my activity that sets up the fragments:
public class LoginActivity extends AppCompatActivity {
private static final String USER_SKIPPED_LOGIN_KEY = "user_skipped_login";
private static final int SPLASH = 0;
public static final int FILE = 1;
public static final int CONVOS = 2;
public static final int SETTINGS = 3;
public static final int ABOUT = 4;
private static final int FRAGMENT_COUNT = ABOUT +1;
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
private Fragment[] fragments = new Fragment[FRAGMENT_COUNT];
private boolean isResumed = false;
private boolean userSkippedLogin = 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);
if (savedInstanceState != null) {
userSkippedLogin = savedInstanceState.getBoolean(USER_SKIPPED_LOGIN_KEY);
}
uiHelper = new UiLifecycleHelper(this, callback);
uiHelper.onCreate(savedInstanceState);
setContentView(R.layout.login_activity);
getSupportActionBar().setLogo(R.drawable.chatstatssmall);
FragmentManager fm = getSupportFragmentManager();
MainFragment splashFragment = (MainFragment) fm.findFragmentById(R.id.splashFragment);
fragments[SPLASH] = splashFragment;
fragments[FILE] = fm.findFragmentById(R.id.fileFragment);
fragments[CONVOS] = fm.findFragmentById(R.id.convoFragment);
fragments[SETTINGS] = fm.findFragmentById(R.id.userSettingsFragment);
fragments[ABOUT] = fm.findFragmentById(R.id.aboutFragment);
FragmentTransaction transaction = fm.beginTransaction();
for(int i = 0; i < fragments.length; i++) {
transaction.hide(fragments[i]);
}
transaction.commit();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
android.support.v7.app.ActionBar act = getSupportActionBar();
act.setTitle("Welcome to ChatStats!");
act.setHomeAsUpIndicator(R.drawable.chatstatssmall);
act.setHomeButtonEnabled(true);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.action_settings:
showFragment(SETTINGS, false);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public final static String extra_msg = "chatstats.passArray";
#Override
public void onResume() {
super.onResume();
uiHelper.onResume();
isResumed = true;
// Call the 'activateApp' method to log an app event for use in analytics and advertising reporting. Do so in
// the onResume methods of the primary Activities that an app may be launched into.
AppEventsLogger.activateApp(this);
}
#Override
public void onPause() {
super.onPause();
uiHelper.onPause();
isResumed = false;
// Call the 'deactivateApp' method to log an app event for use in analytics and advertising
// reporting. Do so in the onPause methods of the primary Activities that an app may be launched into.
AppEventsLogger.deactivateApp(this);
}
#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);
outState.putBoolean(USER_SKIPPED_LOGIN_KEY, userSkippedLogin);
}
#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
userSkippedLogin = false;
showFragment(FILE, false);
} else if (userSkippedLogin) {
showFragment(FILE, false);
} else {
// otherwise present the splash screen and ask the user to login, unless the user explicitly skipped.
showFragment(SPLASH, false);
}
}
public void startMainActivity(){
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
}
private void onSessionStateChange(Session session, SessionState state, Exception exception) {
if (isResumed) {
FragmentManager manager = getSupportFragmentManager();
int backStackSize = manager.getBackStackEntryCount();
for (int i = 0; i < backStackSize; i++) {
manager.popBackStack();
}
// check for the OPENED state instead of session.isOpened() since for the
// OPENED_TOKEN_UPDATED state, the selection fragment should already be showing.
if (state.equals(SessionState.OPENED)) {
showFragment(FILE, false);
} else if (state.isClosed()) {
showFragment(SPLASH, false);
}
}
}
public 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();
}
}
This uiHelper stuff is really confusing me. I'd appreciate if anybody could let me know what I might be doing wrong. I thought I followed the Facebook documentation (available here https://developers.facebook.com/docs/reference/android/3.23.1/class/UiLifecycleHelper/ ) exactly, but I'm still getting this error.
Related
i decide to use AsyncTaskLoader for lifecycle aware when load data.
It successfully created, but i got one problem when rotate my device, my ProgressBar dismissed and not shown again.
I know it because Activity recreate it and execute onCreate() again.
But i don't know where to handle that, i think it already handled by initLoader
public class MainActivity extends AppCompatActivity implements
LoaderManager.LoaderCallbacks<String> {
public static final String TAG = MainActivity.class.getSimpleName();
public static final int LOADER_ID = 92;
public static final String SEARCH_VALUE = "java";
public static final String ARG_GITHUB_URL = "github_search_url";
#BindView(R.id.tv_results) TextView mResultTextView;
#BindView(R.id.pb_loading_indicator) ProgressBar mLoadingIndicatorProgressBar;
Bundle mBundle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
mBundle = new Bundle();
// Initiate Loader at the first time
// when onCreate called (rotate device)
URL searchUrl = NetworkUtils.buildUrl(SEARCH_VALUE);
mBundle.putString(ARG_GITHUB_URL, searchUrl.toString());
getSupportLoaderManager().initLoader(LOADER_ID, mBundle, this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int menuItemId = item.getItemId();
if (menuItemId == R.id.action_reload) {
loadGithubRepository();
}
return super.onOptionsItemSelected(item);
}
private void loadGithubRepository() {
Log.e(TAG, "loadGithubRepository: Start load github repository");
mResultTextView.setText("");
// URL searchUrl = NetworkUtils.buildUrl(repoName);
// new GithubRepositoryTask().execute(searchUrl);
LoaderManager loaderManager = getSupportLoaderManager();
if (null == loaderManager.getLoader(LOADER_ID)) {
getSupportLoaderManager().initLoader(LOADER_ID, mBundle, this);
} else {
getSupportLoaderManager().restartLoader(LOADER_ID, mBundle, this);
}
}
// Implement Loader Callback method
#Override
public Loader<String> onCreateLoader(int id, final Bundle args) {
return new AsyncTaskLoader<String>(this) {
#Override
protected void onStartLoading() {
mLoadingIndicatorProgressBar.setVisibility(View.VISIBLE);
if (args != null)
forceLoad();
}
#Override
public String loadInBackground() {
String response = null;
Log.d(TAG, "loadInBackground: " + (args != null));
if (args != null) {
try {
Log.d(TAG, "loadInBackground: " + args.getString(ARG_GITHUB_URL));
URL url = new URL(args.getString(ARG_GITHUB_URL));
response = NetworkUtils.getResponseFromHttp(url);
} catch (Exception e) {
e.printStackTrace();
}
}
return response;
}
};
}
#Override
public void onLoadFinished(Loader<String> loader, String data) {
mLoadingIndicatorProgressBar.setVisibility(View.INVISIBLE);
if (data != null && !data.equals("")) {
mResultTextView.setText(data);
}
}
#Override
public void onLoaderReset(Loader<String> loader) {
// Do nothing...
}
}
How to handle that?
//inside your activity
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
// in manifest
<activity
android:name=".activities.YourActivity"
android:label="#string/title_activity"
android:configChanges="orientation|screenSize"
android:windowSoftInputMode="stateHidden|adjustResize" />
which not recreates activity layout.
may be helpful
It is happening because your layout is recreated and, as I understood, default ProgressBar is INVISIBLE. You have to save activity's loading state and set visibility for ProgressBar after restoring instance state.
More information about saving/restoring data in activity:
https://stackoverflow.com/a/151940/2504274
I am relatively new to the android Facebook SDK and need help setting up my login activity after spending fruitless days on this. I am unable to resolve the issues and each time I try and import com.facebook.Session (as recommended in the tutorial, it is automatically changed to "SessionState" instead, which again doesn't help resolve the errors. Please can someone help me fix this.
I am using facebook sdk v3.6 and the latest ADT and SDK tools. Also, my facebook SDK is in a different folder (with the android SDK) and the project exists in a seperate workspace (again, as recommeneded by the tutorial, I did not choose to copy the fb sdk into my workspace, simply imported it). All the FB samples are working fine, I tried copying the code from Scrumptious's main activity to get my login working.
Here's the code for reference:
package com.example.myproject;
import android.content.Intent;
import android.os.Bundle;
import android.service.textservice.SpellCheckerService.Session;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.Menu;
import android.view.MenuItem;
import com.facebook.AppEventsLogger;
import com.facebook.Session.StatusCallback;
import com.facebook.SessionState;
import com.facebook.UiLifecycleHelper;
public class FBLoginActivity extends FragmentActivity {
private static final String USER_SKIPPED_LOGIN_KEY = "user_skipped_login";
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;
private boolean isResumed = false;
private boolean userSkippedLogin = false;
private UiLifecycleHelper uiHelper;
/* Errors on the next line:
Multiple markers at this line
- Session.StatusCallback cannot be resolved to a type
- Session.StatusCallback cannot be resolved to a type
- Watchpoint:FBLoginActivity [access and modification] -
callback */
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);
if (savedInstanceState != null) {
userSkippedLogin = savedInstanceState.getBoolean(USER_SKIPPED_LOGIN_KEY);
}
uiHelper = new UiLifecycleHelper(this, callback);
uiHelper.onCreate(savedInstanceState);
setContentView(R.layout.main);
FragmentManager fm = getSupportFragmentManager();
SplashFragment splashFragment = (SplashFragment) fm.findFragmentById(R.id.splashFragment);
fragments[SPLASH] = 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();
splashFragment.setSkipLoginCallback(new SplashFragment.SkipLoginCallback() {
#Override
public void onSkipLoginPressed() {
userSkippedLogin = true;
showFragment(SELECTION, false);
}
});
}
#Override
public void onResume() {
super.onResume();
uiHelper.onResume();
isResumed = true;
// Call the 'activateApp' method to log an app event for use in analytics and advertising reporting. Do so in
// the onResume methods of the primary Activities that an app may be launched into.
AppEventsLogger.activateApp(this);
}
#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);
outState.putBoolean(USER_SKIPPED_LOGIN_KEY, userSkippedLogin);
}
#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);
userSkippedLogin = false;
} else if (userSkippedLogin) {
showFragment(SELECTION, false);
} else {
// otherwise present the splash screen and ask the user to login, unless the user explicitly skipped.
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)) {
showSettingsFragment();
return true;
}
return false;
}
public void showSettingsFragment() {
showFragment(SETTINGS, true);
}
private void onSessionStateChange(Session session, SessionState state, Exception exception) {
if (isResumed) {
FragmentManager manager = getSupportFragmentManager();
int backStackSize = manager.getBackStackEntryCount();
for (int i = 0; i < backStackSize; i++) {
manager.popBackStack();
}
// check for the OPENED state instead of session.isOpened() since for the
// OPENED_TOKEN_UPDATED state, the selection fragment should already be showing.
if (state.equals(SessionState.OPENED)) {
showFragment(SELECTION, false);
} else if (state.isClosed()) {
showFragment(SPLASH, false);
}
}
}
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();
}
}
The error was resolved by removing the statement
import android.service.textservice.SpellCheckerService.Session;
and instead adding:
import com.facebook.Session;
i am working with the facebook sdk for android and i was following a tutorial. When i ran my code it says java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.ftester/com.example.ftester.MainActivity}: java.lang.ClassNotFoundException: Didn't find class "com.example.ftester.MainActivity" on path: DexPathList[[zip file "/data/app/com.example.ftester-2.apk"],nativeLibraryDirectories=[/data/app-lib/com.example.ftester-2, /vendor/lib, /system/lib]]
public class MainActivity extends FragmentActivity {
private static final int SPLASH = 0;
private static final int SELECTION = 1;
private static final int FRAGMENT_COUNT = SELECTION +1;
private boolean isResumed = false;
private UiLifecycleHelper uiHelper;
private Fragment[] fragments = new Fragment[FRAGMENT_COUNT];
private Session.StatusCallback callback =
new Session.StatusCallback() {
#Override
public void call(Session session,
SessionState state, Exception exception) {
onSessionStateChange(session, state, exception);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
uiHelper = new UiLifecycleHelper(this, callback);
uiHelper.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fm = getSupportFragmentManager();
fragments[SPLASH] = fm.findFragmentById(R.id.splashFragment);
fragments[SELECTION] = fm.findFragmentById(R.id.selectionFragment);
FragmentTransaction transaction = fm.beginTransaction();
for(int i = 0; i < fragments.length; i++) {
transaction.hide(fragments[i]);
}
transaction.commit();
}
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();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#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);
}
}
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
public void onResume() {
super.onResume();
uiHelper.onResume();
isResumed = true;
}
#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);
}
#Override
public void onPause() {
super.onPause();
uiHelper.onPause();
isResumed = false;
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.ftester"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.ftester.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
There's a possibility that your MainActivity.java file is not being compiled and not available in the apk file. Check and try this solution https://stackoverflow.com/a/18533212/3025732
I am new to android and was trying the Facebook login tutorial on following URl: https://developers.facebook.com/docs/android/scrumptious/authenticate/
I have created app exactly as explained in the tutorial. However, when i try to authenticate using facebook it fails. No error is shown in logcat. Everything seems fine, not even a single error, still its not authenticating.
Here is the code, its exactly same as in tutorial.
package com.l****.n****;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import com.facebook.Session;
import com.facebook.SessionState;
import com.facebook.UiLifecycleHelper;
public class MainActivity extends FragmentActivity {
private static final int SPLASH = 0;
private static final int SELECTION = 1;
private static final int FRAGMENT_COUNT = SELECTION +1;
private static final String TAG = null;
private Fragment[] fragments = new Fragment[FRAGMENT_COUNT];
private boolean isResumed = false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
uiHelper = new UiLifecycleHelper(this, callback);
uiHelper.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fm = getSupportFragmentManager();
fragments[SPLASH] = fm.findFragmentById(R.id.splashFragment);
fragments[SELECTION] = fm.findFragmentById(R.id.selectionFragment);
FragmentTransaction transaction = fm.beginTransaction();
for(int i = 0; i < fragments.length; i++) {
transaction.hide(fragments[i]);
}
transaction.commit();
}
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();
}
#Override
public void onResume() {
super.onResume();
uiHelper.onResume();
isResumed = true;
}
#Override
public void onPause() {
super.onPause();
uiHelper.onPause();
isResumed = false;
}
#Override
public void onDestroy() {
super.onDestroy();
uiHelper.onDestroy();
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
uiHelper.onSaveInstanceState(outState);
}
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
Log.i(TAG, "Logged in...");
showFragment(SELECTION, false);
} else if (state.isClosed()) {
// If the session state is closed:
// Show the login fragment
Log.i(TAG, "Logged out...");
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);
}
}
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 onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
uiHelper.onActivityResult(requestCode, resultCode, data);
}
}
Please help as i have no clue what is wrong with the code. Thanks in advance.
P.S: I am running it on real device android version 4.2.2
Check app Id and key hash are correct. If not, i would just download folder into eclipse as an existing android project.
I have a android application through which i have to login to facebook.
I am using the session object of facebook sdk to login.
However the login does not work if the device has the actual facebook application installed in it.
Below is my code
public class FacebookSettings extends FragmentActivity{
/** Called when the activity is first created. */
private static final int LOGIN = 0;
private static final int LOGGED_IN = 1;
private static final int FRAGMENT_COUNT = LOGGED_IN +1;
private Button publishButton;
private Fragment[] fragments = new Fragment[FRAGMENT_COUNT];
private Session mSession;
private boolean isResumed = false;
#Override
public void onPause() {
// TODO Auto-generated method stub
super.onPause();
uiHelper.onPause();
isResumed=false;
}
#Override
public void onResume() {
// TODO Auto-generated method stub
super.onResume();
uiHelper.onResume();
isResumed=true;
}
protected static final String LOG_TAG = "FACEBOOK_TEST";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fb_settings);
publishButton=(Button) findViewById(R.id.publishButton);
android.support.v4.app.FragmentManager fm = getSupportFragmentManager();
fragments[LOGIN] = fm.findFragmentById(R.id.Login_Fragment);
fragments[LOGGED_IN] = fm.findFragmentById(R.id.Logged_in_Fragment);
android.support.v4.app.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) {
android.support.v4.app.FragmentManager fm = getSupportFragmentManager();
android.support.v4.app.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) {
Log.d("facebook","isResumed \n\n\n\n"+state.name());
android.support.v4.app.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()) {
Log.d("facebook","State isOpened in on session state changed");
// If the session state is open:
// Show the authenticated fragment
publishButton.setVisibility(View.VISIBLE);
showFragment(LOGGED_IN, false);
} else if (state.isClosed()) {
Log.d("facebook","State isClosed in on session state changed");
// If the session state is closed:
// Show the login fragment
publishButton.setVisibility(View.INVISIBLE);
showFragment(LOGIN, false);
}
}
}
#Override
protected void onResumeFragments() {
// TODO Auto-generated method stub
super.onResumeFragments();
Session session = Session.getActiveSession();
if (session != null && session.isOpened()) {
// if the session is already open,
// try to show the selection fragment
Log.d("facebook","State isOpened in resume fragments\n\n\n");
publishButton.setVisibility(View.VISIBLE);
showFragment(LOGGED_IN, false);
} else {
// otherwise present the splash screen
// and ask the user to login.
Log.d("facebook","State isClosed in resume fragments\n\n\n");
publishButton.setVisibility(View.INVISIBLE);
showFragment(LOGIN, false);
}
}
private UiLifecycleHelper uiHelper;
private Session.StatusCallback callBack=new StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
// TODO Auto-generated method stub
Log.d("facebook","in status call back \n\n\n\n");
Log.d("facebook","state\n\n\n\n"+session.isClosed());
Log.d("facebook","state\n\n\n\n"+session.isOpened());
Log.d("facebook","state\n\n\n\n"+state.isClosed());
Log.d("facebook","state\n\n\n\n"+state.isOpened());
onSessionStateChange(session,state,exception);
}
};
#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
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
uiHelper.onSaveInstanceState(outState);
}
}
pls help
thanks
I think you are looking for this :
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="#string/applicationId" />
This metadata is used by the facebook sdk to attach session to your application.
You can also set it while creating a session using the builder
new Session.Builder(this).setApplicationId(Constants.Facebook.APP_ID)
Refer to the AndroidManifest.xml in HelloFacebookSample
I think the problem is that key hash, which you have entered on Facebook page is different from key hash, which is sent by Facebook application. One of the solutions is to add following code in onCreate() method:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
PackageInfo info = getPackageManager().getPackageInfo(
"com.facebook.samples.loginhowto",
PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
Log.d("KeyHash:", Base64.encodeToString(md.digest(), Base64.DEFAULT));
}
} catch (NameNotFoundException e) {
} catch (NoSuchAlgorithmException e) {
}
...
Replace com.facebook.samples.loginhowto with your package information. Look in a log for the KeyHash and add it in your developer page.
Additional information you can find on Facebook Developer page facebook.
But remember, this is temporary solution and will most likely work only for account, from which you got key hash with Facebook application.
We have faced the same kind of issue, but it was in IPhone app. When we develop a facbook application in IPhone, login does not work , if have intalled fb application itself.
We resolver it, put Iphone app bundle identifier in which I was created facebook app in facebook developer page.
I hope that this kind of similar feild missing when you was created a fb app for android in db developer page. Please check it.