-3

I have read questions related to this question and I have come to the conclusion that my variable which is of reference type has not been initialized or its object has not been created to be used for dereferencing. However I am not sure of how to initialize my variable of type String with the way it's being used. Here is part of the codes:

public class ManualControlsFragment extends Fragment {
    private MqttAndroidClient client;
    String payload1;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {



        View view = inflater.inflate(R.layout.fragment_manual_controls, container, false);
        switchLed = (Switch) view.findViewById(R.id.LEDManControl);
        switchLed.setChecked(true);

        switchLed.setTextOn("On");
        switchLed.setTextOff("Off");

        String clientId = MqttClient.generateClientId();
        client =
                new MqttAndroidClient(this.getActivity(), "tcp://192.168.100.6:1883",
                        clientId);
        //Start of Manual Automation

        try {
            IMqttToken token = client.connect();
            token.setActionCallback(new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {

                    String topic = "rpi/gpio";

                     switchLed.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

                        @Override
                        public void onCheckedChanged(CompoundButton buttonView,
                                                     boolean isChecked) {

                            // If ischecked means if it is ON the it will show true else
                            // show false
                            if (isChecked) {
                                /*Toast.makeText(getActivity().getApplicationContext(),
                                        "Switch is : " + isChecked, Toast.LENGTH_SHORT)
                                        .show();*/
                                payload1 ="ledOn";

                            } else {
                                /*Toast.makeText(getActivity().getApplicationContext(),
                                        "Switch is : " + isChecked, Toast.LENGTH_SHORT)
                                        .show();*/
                                payload1 ="ledOff";
                            }

                        }
                    });

 try {
                        /*if(payload1!=null){
                              MqttMessage message1 = new MqttMessage(payload1.getBytes());
                        client.publish(topic, message1);
                        }*/

                        MqttMessage message1 = new MqttMessage(payload1.getBytes());
                        client.publish(topic, message1);

This is what appears on the logcat:

 java.lang.NullPointerException: Attempt to invoke virtual method 'byte[] java.lang.String.getBytes()' on a null object reference
                                                                                           at com.example.teerna.smartagriculturev5.ManualControlsFragment$1.onSuccess(ManualControlsFragment.java:294)
                                                                                           at org.eclipse.paho.android.service.MqttTokenAndroid.notifyComplete(MqttTokenAndroid.java:124)
                                                                                           at org.eclipse.paho.android.service.MqttAndroidClient.simpleAction(MqttAndroidClient.java:1497)
                                                                                           at org.eclipse.paho.android.service.MqttAndroidClient.connectAction(MqttAndroidClient.java:1439)
                                                                                           at org.eclipse.paho.android.service.MqttAndroidClient.onReceive(MqttAndroidClient.java:1368)
                                                                                           at android.support.v4.content.LocalBroadcastManager.executePendingBroadcasts(LocalBroadcastManager.java:308)
                                                                                           at android.support.v4.content.LocalBroadcastManager.access$000(LocalBroadcastManager.java:46)
                                                                                           at android.support.v4.content.LocalBroadcastManager$1.handleMessage(LocalBroadcastManager.java:118)
                                                                                           at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                           at android.os.Looper.loop(Looper.java:135)
                                                                                           at android.app.ActivityThread.main(ActivityThread.java:5912)
                                                                                           at java.lang.reflect.Method.invoke(Native Method)
                                                                                           at java.lang.reflect.Method.invoke(Method.java:372)
                                                                                           at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405)
                                                                                           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)

The error appears at this line: MqttMessage message1 = new MqttMessage(payload1.getBytes());

I tried the following but they didn't work:

if (isChecked) {
    payload1 = new String("ledOn");

} else {                            
    payload1 = new String("ledOff");
    }

And I tried to see if the payload is null. That stopped the app from crashing (and displaying the NullPointException) and it didn't send the payload:

try {
      if(payload1!=null){
           MqttMessage message1 = new MqttMessage(payload1.getBytes());
           client.publish(topic, message1);
  }

I suppose the cause of the error lies in the payload not being initialized which makes it null. I would like to know where I should initialize it or how I should use it because putting the variable inside the try block gives me errors such it should be declared final and when I declare it as final I am not able to assign a value to it as it cannot be changed after I make it final.

Would greatly appreciate any help.

Thanks for all the answers.

I actually reconsidered the approach I used to send the payload and I realized that the reason why the server was not getting the payload was because a null payload was being sent and it was not sending the payload based on the changes in the switch. The aim of the switch was to send a payload to a server to tell my microcontroller to turn a LED on or off based on the status of the switch. I rewrote it as I have posted below and it worked perfectly fine:

     switchLed.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

                @Override
                public void onCheckedChanged(CompoundButton buttonView,
                                             boolean isChecked) {

                    // If ischecked means if it is ON the it will show true else
                    // show false
                    if (isChecked) {

                        String payload1="ledOn";
                        MqttMessage message1 = new MqttMessage(payload1.getBytes());
                        try {
                            client.publish(topic, message1);
                        } catch (MqttException e) {
                            e.printStackTrace();
                        }


                    } else {

                        String payload2 = "ledOff";
                        MqttMessage message2 = new MqttMessage(payload2.getBytes());
                        try {
                            client.publish(topic, message2);
                        } catch (MqttException e) {
                            e.printStackTrace();
                        }


                    }

                }
            });
Tia
  • 1,220
  • 5
  • 22
  • 47
  • 1
    `payload1` is `null` try to initialize it like this `String payload1="";` – AskNilesh May 21 '18 at 12:23
  • can you please put a log inside your token.setActionCallback... and tell us if you get any feedback there ? maybe you are not entering at the setActionCallback and that will not set the values for the payload, also you can set String payload1 = "" ; at first – Gastón Saillén May 21 '18 at 12:25
  • @NileshRathod That solved it. Thanks – Tia May 21 '18 at 12:43
  • 1
    @Tia happy to hear that – AskNilesh May 21 '18 at 12:44
  • @GastónSaillén I printed a `Toast` message under the `if` and `else` statement when the switch is toggled and it did display the `Toast` correctly. Setting the `payload` to "" solved it. Thanks – Tia May 21 '18 at 12:45
  • 1
    glad its working , have a nice day ! – Gastón Saillén May 21 '18 at 12:58
  • @GastónSaillén Have a nice day :) – Tia May 21 '18 at 13:27
  • But "payload1" is still getting the value of " " in the following line ` MqttMessage message1 = new MqttMessage(payload1.getBytes()); ` as the payload is not being sent to the server and when I displayed a toast above that line to print `payload1`, nothing is being displayed. – Tia May 21 '18 at 14:38
  • I edited my post with the actual solution I found.. Thanks for all the answers! Have a good day – Tia May 22 '18 at 10:51

2 Answers2

1

Before your onCreateView you declare your variable String payload1; but it isn't initialized.

This will only work when you change the switch, if it's never changed your variable will never be initialized.

if (isChecked) {
    payload1 = new String("ledOn");

} else {                            
    payload1 = new String("ledOff");
}

What I advise you to do is to initialized it with one of those two states, or with an empty string. That way it will never be null:

String payload1 = "ledOn";
Levi Moreira
  • 11,917
  • 4
  • 32
  • 46
  • 1
    Downvotes should be explained for improvement in the community, downvoting with no explanation isn't nice – Levi Moreira May 21 '18 at 12:29
  • But "payload1" is still getting the value of " " in the following line ` MqttMessage message1 = new MqttMessage(payload1.getBytes()); ` as the payload is not being sent to the server and when I displayed a toast above that line to print `payload1`, nothing is being displayed. – Tia May 21 '18 at 14:38
  • that's because you're not changing the switch and it is sending the value with which the variable was initialized. Try initializing the variable with either ledOn or ledOff depeding on the initial value of the switch – Levi Moreira May 21 '18 at 14:40
  • Thanks.. I'll do that – Tia May 21 '18 at 14:44
  • I didn't understand what you meant by "that's because you're not changing the switch and it is sending the value with which the variable was initialized." and what you mentioned about that in your answer above. Would be grateful if you could explain it again.. I am making the change you suggested – Tia May 21 '18 at 15:07
  • You have a "switchLed" switch, if you don't touch it it won't call the onCheckedChanged method and therefore won't add either ledOn or ledOff to the variable. – Levi Moreira May 21 '18 at 15:13
0

You just declare your variable String payload1; If you want to use payload1.getBytes() you just need to initialize String variable. IN your case i don't no why but switchLed.setOnCheckedChangeListener is not call so variable is not initialized. That's why you have an error in your code