¿Cómo acceder a las funciones de servicio desde un fragmento, que está vinculado a la actividad principal en Android?

Tengo una actividad de Android con un fragmento de visor. En el método onCreate de la actividad, le ato un servicio que se ejecuta constantemente en segundo plano.

En el fragmento, en una determinada condición, necesito llamar a una función en el servicio que se ocupa de la condición. ¿Cuál es la forma correcta de acceder al servicio y llamar a sus funciones?

MainActivity.java

public class MainActivity extends AppCompatActivity {

private String TAG = "MainActivity";

DbHelper dbHelper;
SessionManager sessionManager;
SessionCache sessionCache;
Map<String, ?> userDetails;
protected SocketListener socketService;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    sessionManager = new SessionManager(getApplicationContext());

    // Connect to background socketlistener service
    Intent serviceIntent = new Intent(MainActivity.this, SocketListener.class);
    startService(serviceIntent);
    .
    .
    .

    TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
    tabLayout.addTab(tabLayout.newTab().setText("").setIcon(getResources().getDrawable(R.drawable.profileicon)));
    tabLayout.addTab(tabLayout.newTab().setText("").setIcon(getResources().getDrawable(R.drawable.homeicon)));
    tabLayout.addTab(tabLayout.newTab().setText("").setIcon(getResources().getDrawable(R.drawable.chaticon)));

    tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
    final NonSwipeableViewPager viewPager = (NonSwipeableViewPager) findViewById(R.id.view_pager);

    final CustomPagerAdapter pagerAdapter = new CustomPagerAdapter
            (getSupportFragmentManager(), tabLayout.getTabCount());

    viewPager.setAdapter(pagerAdapter);
    viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));

    viewPager.setCurrentItem(1);
    tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            viewPager.setCurrentItem(tab.getPosition());
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });
}

    private ServiceConnection serviceConnection = new ServiceConnection() {


@Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
        socketService = ((SocketListener.LocalBinder) iBinder).getService();
    }

    @Override
    public void onServiceDisconnected(ComponentName componentName) {
        socketService = null;
    }
};

}

Este es mi servicio Me conecto a un servidor y escucho constantemente las actualizaciones.

SocketListener.java

    package com.example.gopa2000.mobapps;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

import java.net.URISyntaxException;

import io.socket.client.IO;
import io.socket.client.Socket;
import io.socket.emitter.Emitter;

public class SocketListener extends Service {

private static String TAG = "SocketListener";
private Socket socket;

public SocketListener() { }

@Override
public IBinder onBind(Intent intent) {
    // TODO: Return the communication channel to the service.
    return localBinder;
}

private final IBinder localBinder = new LocalBinder();
public class LocalBinder extends Binder {
    public SocketListener getService(){
        Log.i(TAG, "getService: Sitting in local binder.");
        return SocketListener.this;
    }

    public void sendMessage(String message){
        socket.emit("match", message);
    }
}

@Override
public void onCreate() {
    super.onCreate();
}

public void isBoundable(){
    Log.i(TAG, "Bind like a baller.");
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    super.onStartCommand(intent, flags, startId);

    Runnable connect = new ConnectSocket();
    new Thread(connect).start();
    return START_STICKY;
}

class ConnectSocket implements Runnable {
    @Override
    public void run() {
        try {
            socket = IO.socket(RESTClient.getURL());

            socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
                @Override
                public void call(Object... args) {
                    Log.i(TAG, "call: Connected to backend!");
                }
            });

            socket.connect();
        } catch (URISyntaxException e){
            Log.e(TAG, "run: ", e);
        }
    }
}

public Socket getSocket(){
    return this.socket;
}
}

Y este es el fragmento donde necesitaría llamar alsendMessage(string).

public class MainViewFragment extends Fragment {

private final String TAG = "MVFragment";

private RecyclerView recyclerView;
private RecyclerView.LayoutManager layoutManager;
private RecyclerView.Adapter adapter;
private SessionManager sessionManager;
private ArrayList<CustomCard> cards;
private CardAdapter cardAdapter;
private Button btn;
private SwipeFlingAdapterView flingContainer;
private Map<String, ?> userDetails;
// hax
private static String userEmail;



@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view = inflater.from(getContext()).inflate(R.layout.fragment_main_view, container, false);

            .
            .

    flingContainer.setAdapter(adapter);

    flingContainer.setFlingListener(new SwipeFlingAdapterView.onFlingListener(){
            .
            .

        @Override
        public void onRightCardExit(Object o) {
            .
            .

            if(match){

            // need to call sendMessage from the service here. <------------------------

                sessionCache.addToMatchTable(Liker, Likee);
            }
        }

        @Override
        public void onAdapterAboutToEmpty(int i) {

        }

        @Override
        public void onScroll(float v) {

        }
    });


    flingContainer.setOnItemClickListener(new SwipeFlingAdapterView.OnItemClickListener(){
        @Override
        public void onItemClicked(int itemPosition, Object dataObject){
            Toast.makeText(getActivity(), "Clicked!", Toast.LENGTH_SHORT).show();
            Intent intent = new Intent(getActivity().getApplicationContext(), FullScreenCardLayout.class);
            startActivity(intent);
        }
    });

    return view;
}

Respuestas a la pregunta(1)

Su respuesta a la pregunta