-1

I have this android app which connects to an mqtt broker and listens for instructions to play/pause a ringtone or open/close the flashlight.

It runs as supposed to until i change my settings and call the function flashOnOff after this. Then i get a null pointer exception but i can not understand why.

This is my code (i did not include my imports to save some space):

public class MainActivity extends AppCompatActivity {

//    Layout related parameters
Toolbar myToolbar;
Spinner mySpinner;
ImageButton flashlightButton;
Button ringtone;
EditText message;

//  Camera/flashlight related parameters
Camera camera;
Camera.Parameters parameters;

//    MQTT related parameters
private String BrokerIp = "tcp://192.168.1.3:1883";
private int qos = 2;
static String Username = "user1";
static String Password = "user1";
String topicStr = "commands";
String clientId = "AndroidClient";
MqttConnectOptions options;
MqttAndroidClient client;
Vibrator vibrator;


//  Ringtone related parameters
Ringtone myRingtone;
MediaPlayer ringtoneMP ;


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


    vibrator = (Vibrator)getSystemService(VIBRATOR_SERVICE);

    Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    myRingtone = RingtoneManager.getRingtone(getApplicationContext(),uri);

    myToolbar = (Toolbar) findViewById(R.id.toolbar);
    mySpinner = (Spinner) findViewById(R.id.spinner);
    flashlightButton = (ImageButton) findViewById(R.id.image);

    myToolbar.setLogo(R.drawable.twoguyswatchmrrobot);
    myToolbar.setTitle(getResources().getString(R.string.app_name));

    ArrayAdapter<String> myAdapter = new ArrayAdapter<String>(MainActivity.this,
            R.layout.custom_spinner_itam,
            getResources().getStringArray(R.array.Toolbar_dropdown_entries));
    myAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    mySpinner.setAdapter(myAdapter);

    ringtoneMP = MediaPlayer.create(this,R.raw.games_of_thrones);
    ringtone = (Button) this.findViewById(R.id.ringtone);

    message = (EditText)findViewById(R.id.messagePublish);

    mySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
            Toast.makeText(MainActivity.this,
                    mySpinner.getSelectedItem().toString(),
                    Toast.LENGTH_SHORT)
                    .show();

            if (mySpinner.getSelectedItem().toString().equals("Exit App")){
                exit();
            }else if(mySpinner.getSelectedItem().toString().equals("Settings"))
            {
                Intent intent;
                intent = new Intent(MainActivity.this, SettingsActivity.class);
                intent.putExtra("CURRENT_IP",client.getServerURI());
                intent.putExtra("CURRENT_QOS", Integer.toString(qos));
                intent.putExtra("CURRENT_TOPIC",topicStr);
                startActivityForResult(intent,1);   //  this is so we can take the results back to mainActivity later
            }else{
                System.out.println("ara3e, den exw diale3ei tipota");
            }

        }

        @Override
        public void onNothingSelected(AdapterView<?> adapterView) {

        }

    });

    //Flashlight on Create start
    if(isFlashAvailable())   //  check if flash is available on this device, if it is open camera (module) and make button clickable
    {
        camera = Camera.open();
        parameters = camera.getParameters();

    }else
    {  //  if flashlight is not supported dont let the user click the button

        flashlightButton.setEnabled(false);
        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
        builder.setTitle("Error.");
        builder.setMessage("Flashlight not available on this device. \nExit?");   //  inform the user and let him choose how to continue
        builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                dialogInterface.dismiss();
                exit();
            }
        });
        builder.setNegativeButton("Stay without flashlight", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                dialogInterface.dismiss();

            }
        });
        AlertDialog alertDialog = builder.create();
        alertDialog.show();
    }

    flashlightButton.setOnClickListener(new View.OnClickListener() { //  listen for flash button clicks
        @Override
        public void onClick(View view) {
            flashOnOff();
        }
    });

    ringtone.setOnClickListener(new View.OnClickListener() {    //  Ringtone listener
        @Override
        public void onClick(View view) {
            ringtoneOnOff(ringtoneMP);
        }
    });


    client = new MqttAndroidClient(MainActivity.this, BrokerIp, clientId);
//        client = pahoMqttClient.getMqttClient(MainActivity.this,BrokerIp,clientId);


    options = new MqttConnectOptions();
    options.setUserName(Username);
    options.setPassword(Password.toCharArray());

    try {
        IMqttToken token = client.connect(options);
        token.setActionCallback(new IMqttActionListener() {
            @Override
            public void onSuccess(IMqttToken asyncActionToken) {
                // We are connected
                Toast.makeText(MainActivity.this, "connected", Toast.LENGTH_SHORT).show();
                setSubscription(client,topicStr,qos);
            }
            @Override
            public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                // Something went wrong e.g. connection timeout or firewall problems
                Log.w("Mqtt","Failed to connect to:"+ BrokerIp + exception.toString());
                Toast.makeText(MainActivity.this, "Failed to connect to:" +exception.toString(), Toast.LENGTH_SHORT).show();
            }
        });
    } catch (MqttException e) {
        e.printStackTrace();
    }

    client.setCallback(new MqttCallback() {
        @Override
        public void connectionLost(Throwable throwable) {
            Log.d("Connection:"," Lost");
        }

        @Override
        public void messageArrived(String s, MqttMessage mqttMessage) throws Exception {
            myMessageArrived(s,mqttMessage);
        }
        @Override
        public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
            Log.d("Delivery"," completed with iMqttDeliveryToken: " + iMqttDeliveryToken);
        }
    });

}

//Flashlight start
@Override
protected void onStop() {
    super.onStop();
    if(camera!=null)
    {
        camera.release();
        camera = null;
    }
}
//Flashlight end

//Backkey exit confirmation
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        exitByBackKey();
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

protected void exitByBackKey() {

    AlertDialog alertbox = new AlertDialog.Builder(this)
            .setMessage("Do you want to exit application?")
            .setPositiveButton("Yes", new
                    DialogInterface.OnClickListener() {

                        // when yes is clicked exit the application
                        public void onClick(DialogInterface arg0, int arg1) {
                            exit();
                        }
                    })
            .setNegativeButton("No", new
                    DialogInterface.OnClickListener() {

                        // when no is clicked do nothing
                        public void onClick(DialogInterface arg0, int arg1) {
                        }
                    })
            .show();

}
//Backkey end

// PUBLISH MESSAGE
private void setSubscription(MqttAndroidClient client, String topic, int qos){
    try{
        client.subscribe(topic, qos);
    }
    catch (MqttException e){
        e.printStackTrace();
    }
}

private void unsetSubscription(MqttAndroidClient client,String topic){
    try{
        client.unsubscribe(topic);
    }catch (MqttException e){
        e.printStackTrace();
    }
}

public void conn(View v){
    try {
        IMqttToken token = client.connect(options);
        token.setActionCallback(new IMqttActionListener() {
            @Override
            public void onSuccess(IMqttToken asyncActionToken) {
                // We are connected
                Toast.makeText(MainActivity.this, "connected", Toast.LENGTH_SHORT).show();
                setSubscription(client,topicStr,qos);
//                    pub();
            }
            @Override
            public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                // Something went wrong e.g. connection timeout or firewall problems
                Toast.makeText(MainActivity.this, "not connected", Toast.LENGTH_SHORT).show();
            }
        });
    } catch (MqttException e) {
        e.printStackTrace();
    }
}

public void disconn(View v){
    if (client.isConnected()) {
        try {
            IMqttToken token = client.disconnect();
            token.setActionCallback(new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {
                    // We are connected
                    Toast.makeText(MainActivity.this, "disconnected", Toast.LENGTH_SHORT).show();
                }

                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                    // Something went wrong e.g. connection timeout or firewall problems
                    Toast.makeText(MainActivity.this, "could not disconnect", Toast.LENGTH_SHORT).show();
                }
            });
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }else {
        Toast.makeText(MainActivity.this, "Client is already disconnected", Toast.LENGTH_LONG).show();
    }
}


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

public void pub(View v) {
    String topic = topicStr;
    try {

        client.publish(topic, String.valueOf(message.getText()).getBytes(),qos,false);
    } catch (MqttException e) {
        e.printStackTrace();
    }
}

private void ringtoneOnOff(MediaPlayer ringtoneMP){
    if (ringtoneMP.isPlaying()){
        ringtoneMP.pause();
    }else{
        ringtoneMP.start();
    }
}

private void myMessageArrived(String s,MqttMessage mqttMessage){
    if ((mqttMessage.toString()).equals("Flash on")) {
        if (isFlashOn()) {
            Toast.makeText(MainActivity.this, "Flashlight already on", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(MainActivity.this, "Turning flashlight on", Toast.LENGTH_SHORT).show();
            flashOnOff();
        }
    } else if ((mqttMessage.toString()).equals("Flash off")) {
        if (isFlashOn()) {
            Toast.makeText(MainActivity.this, "Turning flashlight off", Toast.LENGTH_SHORT).show();
            flashOnOff();
        } else {
            Toast.makeText(MainActivity.this, "Flashlight already off", Toast.LENGTH_SHORT).show();
        }
    } else if ((mqttMessage.toString()).equals("Ringtone on")) {
        if (ringtoneMP.isPlaying()) {
            Toast.makeText(MainActivity.this, "Ringtone already playing", Toast.LENGTH_SHORT).show();

        } else {
            Toast.makeText(MainActivity.this, "Playing ringtone", Toast.LENGTH_SHORT).show();
            ringtoneMP.start();
        }
    } else if ((mqttMessage.toString()).equals("Ringtone off")) {
        if (ringtoneMP.isPlaying()) {
            ringtoneMP.pause();
        } else {
            Toast.makeText(MainActivity.this, "Ringtone already not being played", Toast.LENGTH_SHORT).show();
        }
    } else {
        Log.d("INFO:", "This Command does not exist");
    }
    vibrator.vibrate(500);
    myRingtone.play();
}

public void exit(){
    finish();
    System.exit(0);
}

public boolean isFlashAvailable(){  //  boolean function that returns true if flash is supported on this device

    return getApplicationContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
}

public void flashOnOff(){   //  self explanatory

    if (this.parameters.getFlashMode().equals(android.hardware.Camera.Parameters.FLASH_MODE_ON) || this.parameters.getFlashMode().equals(android.hardware.Camera.Parameters.FLASH_MODE_TORCH)){  //  if the flash is on torch mode
        Log.d("BHKE","408");
        this.flashlightButton.setImageResource(R.drawable.off);
        this.parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);  //  turn it off
    }else{
        Log.d("BHKE","412");
        this.flashlightButton.setImageResource(R.drawable.on);
        this.parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);    //  else turn it on
    }
    this.camera.setParameters(this.parameters);
    this.camera.startPreview();
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    String tempBrokerIp;
    String temptopic="";
    Integer tempqos;
    Boolean BrokerIpChanged = true;
    Boolean qosChanged = true;
    Boolean topicChanged = true;
    super.onActivityResult(requestCode, resultCode, data);
    switch(requestCode) {
        case (1) : {
            if (resultCode == Activity.RESULT_OK) {
                tempBrokerIp = data.getStringExtra("CURRENT_IP");
                tempqos = Integer.parseInt(data.getStringExtra("CURRENT_QOS"));
                temptopic = data.getStringExtra("CURRENT_TOPIC");

                Log.d("Info BROKER, TOPIC, QOS", ":"+ tempBrokerIp+ " " + temptopic+ " " + tempqos);
                if (tempBrokerIp.equals(BrokerIp)) {
                    BrokerIpChanged=false;
                    Log.i("BrokerIpChanged =", BrokerIpChanged.toString());
                }
                if (tempqos.equals(qos)) {
                    qosChanged=false;
                    Log.i("qosChanged =", qosChanged.toString());
                }else {
                    qos = tempqos;
                }
                if (temptopic.equals(topicStr)){
                    topicChanged=false;
                    Log.i("topicChanged =", topicChanged.toString());
                }else{
                    topicStr = temptopic;
                }
                if (!BrokerIpChanged && !qosChanged && !topicChanged) return;

                if (BrokerIpChanged){
                    try {
                        client.disconnect();

                        BrokerIp = tempBrokerIp;
                        topicStr = temptopic;
                        qos = tempqos;
//                            final String clientId = MqttClient.generateClientId();
                        client = new MqttAndroidClient(MainActivity.this, BrokerIp, clientId);


                        options = new MqttConnectOptions();
                        options.setUserName(Username);
                        options.setPassword(Password.toCharArray());
//                            options.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1);  //  to user the latest mqtt version

                        try {
                            IMqttToken token = client.connect(options);
                            token.setActionCallback(new IMqttActionListener() {
                                @Override
                                public void onSuccess(IMqttToken asyncActionToken) {
                                    // We are connected
                                    Toast.makeText(MainActivity.this, "connected", Toast.LENGTH_SHORT).show();
                                    Log.w("Mqtt","Connected to:"+ BrokerIp);

                                    try{
                                        Log.v("INFO 11111:", "about to subscribe with: "+ topicStr + qos);
                                        client.subscribe(topicStr,qos);
                                    }catch (MqttException e){
                                        e.printStackTrace();
                                    }
                                }
                                @Override
                                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                                    // Something went wrong e.g. connection timeout or firewall problems
                                    Log.w("Mqtt","Failed to connect to:"+ BrokerIp + exception.toString());
                                    Toast.makeText(MainActivity.this, "Failed to connect to:" +exception.toString(), Toast.LENGTH_SHORT).show();
                                }

                            });
                            System.out.println(client.isConnected());
//                                if (client.isConnected()){
//                                    Log.v("INFO 22222:", "about to subscribe with: "+ temptopic + tempqos);
//                                    client.subscribe(temptopic,tempqos);
//                                }

                        } catch (MqttException e) {
                            e.printStackTrace();
                        }

                        client.setCallback(new MqttCallback() {
                            @Override
                            public void connectionLost(Throwable throwable) {

                            }

                            @Override
                            public void messageArrived(String s, MqttMessage mqttMessage) throws Exception {
                                myMessageArrived(s,mqttMessage);
                            }

                            @Override
                            public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {

                            }
                        });

                    }catch (MqttException e){
                        e.printStackTrace();
                    }
                }else
                {
                    try {
                        client.unsubscribe(topicStr);
                        client.subscribe(temptopic,tempqos);

                        topicStr = temptopic;
                        qos = tempqos;

                    } catch (MqttException e) {
                        e.printStackTrace();
                    }
                }
            }
            break;
        }
    }
}

public boolean isFlashOn(){
    return (this.parameters.getFlashMode().equals(android.hardware.Camera.Parameters.FLASH_MODE_ON) || this.parameters.getFlashMode().equals(android.hardware.Camera.Parameters.FLASH_MODE_TORCH));
}

I can provide the settings activity code too is needed

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
George Sp
  • 553
  • 5
  • 20
  • Voting down without saying why doesn't make this post or me better... If you thing something is wrong you can tell me what and fix it – George Sp Dec 05 '17 at 16:17
  • 1
    You said the Nullpointer Exception occurs in the method "flashOnOff" so look there, maybe its because the variables "camera" and "parameters" are not initialized? Also more information and less code would be good i guess – Tyrmos Dec 05 '17 at 16:19
  • Possible duplicate of [What is a NullPointerException, and how do I fix it?](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – takendarkk Dec 05 '17 at 16:38
  • 1
    Post your full stacktrace/logcat output and tell us which line of code it is pointing to. – takendarkk Dec 05 '17 at 16:39

1 Answers1

0

It seems that the two variables needed for the flashOnOff where not initiallized after i returned from the settings activity.

Ι added :

     if (isFlashAvailable()){
        camera = Camera.open();
        parameters = camera.getParameters();
    }

at the onActivityResult start and it works like a charm.

George Sp
  • 553
  • 5
  • 20