1

Hi everyone,

[Introduction] I have created a ScreenSlide Pager (extending FragmentActivity) to handle 4 fragments in MainActivity. I also have a service, handling a bluetooth communication socket (with a RPI). This service can notify MainActivity which receives it through a Handler.

Here it is, placed in MainActivity:

class IncomingHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case BtCommunication.MSG_SET_VALUE:
                    Log.d("SERVICE", "Received from service: " + msg.arg1);
                    break;
                case BtCommunication.MSG_GET_SOCKET_STATE:
                    if(msg.arg1 == 1){
                        Log.d("SERVICE", "Socket state: UP");
                        onSocketUp();
                    } else {
                        Log.d("SERVICE", "Socket state: DOWN");}
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }

I have a fragment (MainFragment) that is called first before any other fragment in the OnCreate():

if(savedInstanceState == null){
            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
            ft.add(R.id.pager, new MainFragment());
            ft.commit();
        }

Then, the fragments are handled this way in the ScreenSlidePagerAdapter of the MainActivity.

@Override
        public Fragment getItem(int position) {
            Log.d("mPager.getCurrentItem", "" + mPager.getCurrentItem());
            if(position == 0){
                actionBar.setTitle("Accueil - Connexion");
                Log.d("Fragment", "MainFragment");
                return new MainFragment();
            }else if(position == 1){
                actionBar.setTitle("Second fragment");
                Log.d("Fragment", "SecondFragment");
                return new SecondFragment();
            }else if(position == 2){
                Log.d("Fragment", "ThirdFragment");
                return new ThirdFragment();
            }else if(position == 3){
                Log.d("Fragment", "ItemFragment");
                return new ItemFragment();
            }else{
                Log.d("Fragment", "ElseFragment (MainFragment)");
                return new MainFragment();
            }
        }

While the socket isn't up, I want him to display a loading animation (animation is working well) : animation loader

Once the connection socket is UP,I have a method in this fragment to set invisible/gone the loading animation. [/Introduction]

public void onSocketUp(){
        ArcLoader.setVisibility(View.GONE);
        Log.d("MAIN FRAGMENT","Arc Loader GONE");
    }

I assume you guessed it: I want to call that method from the activity whenever the socket state switches from DOWN to UP.

The following is the activity's method I'm having a brawl with. She's correctly called once the Handler detects a notification from the service, but i can't call the fragment's method because the findfragmentbyId returns mFrag as a null fragment (?!).

It shouldn't since it's the first fragment called and I don't destroy it staying on it).

Besides, the creation of a new fragment with the transaction fails (Can not perform this action after onSaveInstanceState).

private void onSocketUp()
    {
        //Fragment mainFrag = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":" + mPager.getCurrentItem());
        Fragment  mainFrag = getSupportFragmentManager().findFragmentById(R.id.mainfragment);
        Log.d("MAIN ACTIVITY", "onSocketUp()");
        if (mPager.getCurrentItem() == 0 && mainFrag != null) {
            mainFrag.onSocketUp();
            Log.d("SERVICE", "onSocketUp() called - Main Fragment instantiated");
        }
        else {

            MainFragment newFragment = new MainFragment();
            Bundle args = new Bundle();
            args.putString(MainFragment.ARG_SOCKET_UP, "UP");
            newFragment.setArguments(args);

            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

            transaction.replace(R.id.pager, newFragment);
            transaction.addToBackStack(null);
            transaction.commit();
        }
    }

I hope i gave you all the enough information to get where does my problem come from, don't hesitate if you want me to supply any additional code.

All the other topics i could have read haven't helped until now.

Thanks you in advance.

Amesys
  • 816
  • 2
  • 10
  • 19
  • In "onSocketUp()" you declare a "mainFrag", but what you use afterwards is "mFrag.onSocketUp()". mFrag isn't what you instantiated. Maybe the problem comes from here. – Xema Mar 26 '16 at 12:10
  • edited but that wasn't the source of the problem. – Amesys Mar 26 '16 at 15:20

1 Answers1

0

If you want to call a fragment method from activity just do the following :

Fragment  fragment = getSupportFragmentManager().findFragmentById(R.id.mainfragment);

if (fragment instanceof MainFragment){
  ((MainFragment)fragment).onSocketUp();
}
Mehdi Sakout
  • 773
  • 5
  • 8
  • The if condition isn't fulfilled. Though, the findFragmentbyId is called. I don't understand why. – Amesys Mar 26 '16 at 01:20
  • I've posted the generic way on how to do it but for your example, I think your architecture need to be reviewed. If your `onSocketUp` is necessary for whole your fragments so extract it to your main activity – Mehdi Sakout Mar 26 '16 at 12:00
  • How will i then perform an action on the fragment from the activity? – Amesys Mar 26 '16 at 12:14
  • You could implement callbacks between activity and fragment like in this example : https://gist.github.com/butelo/8729891 (recommended) Or just by calling ((MyActivity)getActivity()).something() from your fragment – Mehdi Sakout Mar 26 '16 at 12:27