Question

I am currently using the API Facebook and I try to add one of the Scrumptious app part to my application.

The Scrumptious part :

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
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.Base64;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import com.facebook.AppEventsLogger;
import com.facebook.Session;
import com.facebook.SessionState;
import com.facebook.UiLifecycleHelper;
import com.google.android.gms.maps.SupportMapFragment;


    public class MainActivity2 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;
        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);


            try {
                PackageInfo info = getPackageManager().getPackageInfo(
                        "info.androidhive.tabsswipe", 
                        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) {

            }


            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[SETTINGS] = fm.findFragmentById(R.id.userSettingsFragment);
            SupportMapFragment test = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.mainActivity2);
            fragments[SELECTION] = test;

            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 class that causes the problem "is":

public class MainActivity extends FragmentActivity implements
        ActionBar.TabListener {

And here is the XML:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">

    <fragment 
              class="info.androidhive.tabsswipe.MainActivity"
              android:id="@+id/mainActivity2"
              android:layout_width="match_parent"
              android:layout_height="match_parent" />
    <fragment android:name="info.androidhive.tabsswipe.SplashFragment"
              android:id="@+id/splashFragment"
              android:layout_width="match_parent"
              android:layout_height="match_parent" />
    <fragment android:name="com.facebook.widget.UserSettingsFragment"
              android:id="@+id/userSettingsFragment"
              android:layout_width="match_parent"
              android:layout_height="match_parent" />
</LinearLayout>

I have tried using "class=", "android:name=" and "tag=".

I am extending android.support.v4.app.FragmentActivity with both classes.

Here is the log!

04-02 20:16:33.880: D/KeyHash:(8899): ooZ4+XVqPy+UAL2Sk1NrWojLcIU=
04-02 20:16:33.997: D/AndroidRuntime(8899): Shutting down VM
04-02 20:16:33.997: W/dalvikvm(8899): threadid=1: thread exiting with uncaught exception (group=0x41aaf930)
04-02 20:16:34.028: E/AndroidRuntime(8899): FATAL EXCEPTION: main
04-02 20:16:34.028: E/AndroidRuntime(8899): java.lang.RuntimeException: Unable to start activity ComponentInfo{info.androidhive.tabsswipe/info.androidhive.tabsswipe.MainActivity2}: android.view.InflateException: Binary XML file line #24: Error inflating class fragment
04-02 20:16:34.028: E/AndroidRuntime(8899):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
04-02 20:16:34.028: E/AndroidRuntime(8899):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
04-02 20:16:34.028: E/AndroidRuntime(8899):     at android.app.ActivityThread.access$600(ActivityThread.java:141)
04-02 20:16:34.028: E/AndroidRuntime(8899):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
04-02 20:16:34.028: E/AndroidRuntime(8899):     at android.os.Handler.dispatchMessage(Handler.java:99)
04-02 20:16:34.028: E/AndroidRuntime(8899):     at android.os.Looper.loop(Looper.java:137)
04-02 20:16:34.028: E/AndroidRuntime(8899):     at android.app.ActivityThread.main(ActivityThread.java:5039)
04-02 20:16:34.028: E/AndroidRuntime(8899):     at java.lang.reflect.Method.invokeNative(Native Method)
04-02 20:16:34.028: E/AndroidRuntime(8899):     at java.lang.reflect.Method.invoke(Method.java:511)
04-02 20:16:34.028: E/AndroidRuntime(8899):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
04-02 20:16:34.028: E/AndroidRuntime(8899):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
04-02 20:16:34.028: E/AndroidRuntime(8899):     at dalvik.system.NativeStart.main(Native Method)
04-02 20:16:34.028: E/AndroidRuntime(8899): Caused by: android.view.InflateException: Binary XML file line #24: Error inflating class fragment
04-02 20:16:34.028: E/AndroidRuntime(8899):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
04-02 20:16:34.028: E/AndroidRuntime(8899):     at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
04-02 20:16:34.028: E/AndroidRuntime(8899):     at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
04-02 20:16:34.028: E/AndroidRuntime(8899):     at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
04-02 20:16:34.028: E/AndroidRuntime(8899):     at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
04-02 20:16:34.028: E/AndroidRuntime(8899):     at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:270)
04-02 20:16:34.028: E/AndroidRuntime(8899):     at android.app.Activity.setContentView(Activity.java:1881)
04-02 20:16:34.028: E/AndroidRuntime(8899):     at info.androidhive.tabsswipe.MainActivity2.onCreate(MainActivity2.java:91)
04-02 20:16:34.028: E/AndroidRuntime(8899):     at android.app.Activity.performCreate(Activity.java:5104)
04-02 20:16:34.028: E/AndroidRuntime(8899):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
04-02 20:16:34.028: E/AndroidRuntime(8899):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
04-02 20:16:34.028: E/AndroidRuntime(8899):     ... 11 more
04-02 20:16:34.028: E/AndroidRuntime(8899): Caused by: java.lang.ClassCastException: info.androidhive.tabsswipe.MainActivity cannot be cast to android.app.Fragment
04-02 20:16:34.028: E/AndroidRuntime(8899):     at android.app.Fragment.instantiate(Fragment.java:585)
04-02 20:16:34.028: E/AndroidRuntime(8899):     at android.app.Fragment.instantiate(Fragment.java:560)
04-02 20:16:34.028: E/AndroidRuntime(8899):     at android.app.Activity.onCreateView(Activity.java:4709)
04-02 20:16:34.028: E/AndroidRuntime(8899):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:680)
04-02 20:16:34.028: E/AndroidRuntime(8899):     ... 21 more
04-02 20:16:34.052: D/dalvikvm(8899): GC_CONCURRENT freed 194K, 3% free 9117K/9340K, paused 3ms+2ms, total 30ms

Any idea of what causes this problem? Thank you in advance guys!

Was it helpful?

Solution

ClassCastException means that you try to cast two different things (like an intand a String..). In your case, you try to use a FragmentActivity Class inside your layout as a fragment but it's not, MainActivity is a FragmentActivity and not a Fragment.
According to your LogCat, this line:

java.lang.ClassCastException: info.androidhive.tabsswipe.MainActivity cannot be cast to android.app.Fragment

your problem is here:

 <fragment 
     class="info.androidhive.tabsswipe.MainActivity"
     android:id="@+id/mainActivity2"
     android:layout_width="match_parent"
     android:layout_height="match_parent" />  

info.androidhive.tabsswipe.MainActivity is not a Fragment and cannot be used inside a layout.


UPDATE:
In comments, I'd suggest you to redesign your app. You should first create an Activity to display your login FB and then, call an Intent to display a FragmentActivity with Tabs and display your panel.
You can also try another thing:

  • Create a FragmentActivity, with a layout which contains a FrameLayout (e.g. id container) and inside your Tabs and other views.
  • In your FragmentActivity, at first creation, do a FragmentTransaction and display inside your FrameLayout (container) a single fragment which displays your login FB.
  • Then, when the user is logged, remove this fragment and let the user see the "background" with your Tabs and display your panel inside.

Hope this helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top