0

The program sends data via bluetooth at each button clicked. It works on the MainActivity, but how could I achieve the same result if the Button is inside a Fragment?

I have this in Main Acitivity:

    btnTimeMinus.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (Connection) {
                connectedThread.sendData("TurnOnLedMinus");
            }
            else {
                Toast.makeText(getApplicationContext(), "Bluetooh not conneceted", Toast.LENGTH_LONG).show();
            }
        }
    });

In which this is called:

    public void sendData(String DataSend) {
        byte[] msgBuffer = DataSend.getBytes();
        try {
            mmOutStream.write(msgBuffer);
        }
        catch (IOException e) {
            Toast.makeText(getApplicationContext(), "Error: " + erro, Toast.LENGTH_LONG).show();
        }
    }

In other words I think I have to call "SendData" with the proper String, just like on "connectedThread.sendData("TurnOnLedMinus");" but put it inside the fragment. The problem is that there is no "Connection" or "connectThread" inside the fragment. That can only be called inside the MainActivity.

EDITED:

public class frag_light extends Fragment {

    Button btAmanMenos;
    ChecaBotaoClicado checaBotaoClicado;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view;
        view = inflater.inflate(R.layout.fragment_frag_light, container, false);
        btAmanMenos.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                checaBotaoClicado.BotaoClicado("AmanhecerMenos");
            }
        });

        checaBotaoClicado.BotaoClicado("AmanhecerMenos");
        return view;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            checaBotaoClicado = (ChecaBotaoClicado)activity;
        }
        catch(Exception erro) {}
    }

    public interface ChecaBotaoClicado {
        public void BotaoClicado(String DadosBotao);
    }
}

The interface is working fine. If I put the "checaBotaoClicado.BotaoClicado("AmanhecerMenos");" inside the OnAttach it sends correctly. But I have plenty of buttons to add, with all sort of messages to send through Bluetooth. Why is it not working just inside a OnClick?

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • Why don't you declare those variables in the Fragment? That seems like the obvious solution – OneCricketeer Jun 18 '17 at 15:05
  • Well I have three fragments, and all the connection stuff happens on the MainActivity. Could I just "Send" the variables values from the MainActivity into the fragments? How? Thanks! – Raphael Amin Jun 18 '17 at 15:16
  • Ideally, you should extract any logical components such as this "Bluetooth socket connection" object into its own class that can be used between all classes (see: singleton pattern) – OneCricketeer Jun 18 '17 at 15:20

1 Answers1

0

Could I just "Send" the variables values from the MainActivity into the fragments?

I think you're looking for the other way around.

Ideally, you would send data back to the Activity containing the required variables.

How to implement OnFragmentInteractionListener

Android documentation - Fragment event callbacks

EDIT

Why is it not working just inside a OnClick?

Your code has a NullPointerException since you never assigned the button / findViewById-d for it.
You don't really need to assign a Button, since you can directly assign the click listener to the found view, though.

public class LightFragment extends Fragment {

    // Button btAmanMenos;
    private ChecaBotaoClicado checaBotaoClicado;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_frag_light, container, false);
        view.findViewById(R.id.btAmanMenos).setOnClickListener(new View.OnClickListener() { 
             @Override
             public void onClick(View v) {
                 if ( null != checaBotaoClicado) {
                     checaBotaoClicado.BotaoClicado("AmanhecerMenos");
                 } else {
                     Log.e("LightFragment ERR", "checaBotaoClicado not assigned!");
                 }
             } 
        });

        // This doesn't need called here
        // checaBotaoClicado.BotaoClicado("AmanhecerMenos");

        return view;
    }

Or you can cast getActivity() and call some method from there. For example,

((BluetoothActivity) getActivity()).send("data") ;
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • I will take a look on that! Thank you very much! – Raphael Amin Jun 18 '17 at 15:36
  • I've put "((MainActivity) getActivity()).send("data") ;" inside the OnClick of the fragment button. But what is that "send"? Where is it in the program? Thanks! – Raphael Amin Jun 18 '17 at 21:19
  • Errr... Obviously you need to actually create the method. It was an example, not the recommendation. Why didn't you use the interface, as described in the documentation? – OneCricketeer Jun 18 '17 at 21:56
  • I'm trying to use the interface. On Fragment I've put the button click: " btnTimeMinus.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { checkButtonClick.ButtonClicked("SunsetMinus"); } });" But this is giving me "Unreacheble statement". – Raphael Amin Jun 19 '17 at 19:31
  • "Unreacheble statement" means you put code after a `return` somewhere, such as under the `return inflater.inflate` or `return rootView` – OneCricketeer Jun 19 '17 at 19:50
  • Yes! Precisely! I was putting it on OnCreateView under return inflater... Should I put it over the return inflater, or inside the OnAttach? – Raphael Amin Jun 19 '17 at 21:24
  • You need to assign the inflated view to an actual view object... How did you manage to initialize your button without a view? – OneCricketeer Jun 19 '17 at 21:26
  • You ask very good and also difficult questions, sir. I have 3 fragments that are inflating just fine. They are like tabs, with a Header above. The header comes from the MainActivity. Doesn't that mean that I have a view? – Raphael Amin Jun 19 '17 at 22:04
  • Let me rephrase, then how did you manage to do `btnTimeMinus = (Button) view.findViewById`? Can you show just one Fragment in your question? You don't need tabs immeadiately for what you are asking for – OneCricketeer Jun 19 '17 at 22:07
  • I've added the fragment on the question. I have three tabs. They are to control Light, Temperature, and Water Changes. Each one has "-" and "+" on some parameters. The arduino are listening to bluetooth, if a certain String is read, it acts (Example: Setting the Sunset time backwards 30 minutes). I don't actually need three tabs. I could just put all of buttons on the MainActivity, but I found that this is a nice solution. – Raphael Amin Jun 19 '17 at 22:41
  • Personally, I would have started with one Fragment in one Activity. You can add the tabs easily later. I have updated my answer with what I think is wrong with your code – OneCricketeer Jun 19 '17 at 22:55
  • 1
    Perfect my friend! My Arduino Due just received the expected string when the button was pressed. Thank you VERY much for your patience and promptitude helping me! I think I cannot express my gratitude in English so: Muito obrigado! – Raphael Amin Jun 20 '17 at 00:42