ObtainMessage does not call Handler

0

I'm doing a communication between arduino and android, the android already manages to send command to the arduino quietly, however now I want to read commands received from arduino. I managed to make it work however with a class that extends thread and this class inside class main ... I separated the files and now it does not work because it does not call the handler. I will comment with several "#" the main parts.

    public class MainActivity extends AppCompatActivity {

        private RelativeLayout layoutCoord;

        /* TTS */
        Speech speech;
        private TextToSpeech myTTS;


        /* DATABASE */
        private SQLiteDatabase conn;
        private DataOpenHelper dataOH;

        /* Bluetooth */
        Bluetooth bluetooth;
        UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");

        /* Controle */
        ImageButton btnControl;

        /* Temperature */
        ImageButton btnTemperature;

        /**
         * When it's being created
         * @param savedInstanceState
         */
        @Override
        protected void onCreate(Bundle savedInstanceState) {

            super.onCreate(savedInstanceState);
            /* BLUETOOTH ###############*/
//Instancia da classe bluetooth que criei passando o cotext, uuid e a //activity
            bluetooth = new Bluetooth(getApplicationContext(),uuid,this);
//########## Requisicao para iniciar o bluetooth
            bluetooth.create();
            speech =  new Speech(this, getApplicationContext(),bluetooth);

            setContentView(R.layout.controle);

            btnControl  = (ImageButton) findViewById(R.id.btnControl);
            btnTemperature = (ImageButton) findViewById(R.id.btnTemperature);

            FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);

            /* Mic button Event */
            fab.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
                    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
                    intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS,1);
                    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE,new Locale("pt","BR"));

                    speech.mySR.startListening(intent);
                }
            });

            /* TTS FUNCTIONS*/
            speech.initializeTextToSpeech();
            speech.initializeSpeechRecognizer();




            /* CREATE CONNECTION DATABASE */
            createConnection();


            btnControl.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent it = new Intent(MainActivity.this, Control.class);
                    startActivity(it);
                }
            });

            btnTemperature.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent it = new Intent(MainActivity.this, Temperature.class);
                    startActivity(it);
                }
            });



        }

        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            bluetooth.result(requestCode,resultCode,data);
        }

        private void createConnection(){
            try{
                dataOH = new DataOpenHelper(this);

                conn = dataOH.getWritableDatabase();
                Snackbar.make(findViewById(android.R.id.content), "Conexão criada com sucesso!",Snackbar.LENGTH_SHORT).setAction("OK",null).show();
            }
            catch (SQLException e){
                AlertDialog.Builder dlg = new AlertDialog.Builder(getApplicationContext());
                dlg.setTitle("Erro");
                dlg.setMessage(e.getMessage());
                dlg.setNeutralButton("OK", null);
                dlg.show();
            }
        }


        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.menu_main, menu);
            return true;
        }

        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            // Handle action bar item clicks here. The action bar will
            // automatically handle clicks on the Home/Up button, so long
            // as you specify a parent activity in AndroidManifest.xml.
            int id = item.getItemId();

            //noinspection SimplifiableIfStatement
            if (id == R.id.action_settings) {
                return true;
            }

            return super.onOptionsItemSelected(item);
        }

        protected void onPause(){
            super.onPause();
            speech.myTTS.shutdown();
        }
    }

Bluetooth Class

 public class Bluetooth extends Activity  {

        private BluetoothAdapter bluetoothAdapter = null;
        private Context context;
        private Activity activity;
        BluetoothDevice device = null;
        BluetoothSocket btSocket = null;
        private static final int BLUETOOTH_ACTIVE = 1;
        private static final int CONNECTION_PERMISSION = 2;
        private boolean isConection = false;
        private boolean hasBlueetooth = false;
        ConnectionThread connectedThread;
        UUID uuid = null;
        private static String MAC = null;

        public Bluetooth(Context context, UUID uuid, Activity activity)
        {
            this.context = context;
            this.uuid = uuid;
            this.activity = activity;
        }

        public void create(){
            bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

            if(bluetoothAdapter == null){
                Toast.makeText(context, "Seu dispositivo não possui bluetooth", Toast.LENGTH_LONG).show();
            }else if(!bluetoothAdapter.isEnabled()){
                Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                activity.startActivityForResult(enableBtIntent, BLUETOOTH_ACTIVE);
                hasBlueetooth = true;
            }
        }


        public void result(int requestCode, int resultCode, Intent data){

            switch(requestCode){

                case BLUETOOTH_ACTIVE:
                    if(resultCode == Activity.RESULT_OK){
                        Toast.makeText(context,"O bluetooth foi ativado", Toast.LENGTH_LONG).show();
                        connect();
                    }
                    else {
                        Toast.makeText(context, "O bluetooth não foi ativado, o app será encerrado", Toast.LENGTH_LONG).show();
                        activity.finish();
                    }
                    break;
                case CONNECTION_PERMISSION:
                    if(resultCode == activity.RESULT_OK){
                        MAC = data.getExtras().getString(ShowDevices.MAC_ADDRESS);

                        device = bluetoothAdapter.getRemoteDevice(MAC);

                        try{
                            //Create a communication socket (channel)
                            btSocket = device.createRfcommSocketToServiceRecord(uuid);
                            btSocket.connect();

                            isConection = true;

                            connectedThread = new ConnectionThread(btSocket);
//####################################################
//Aqui eu inicio a thread
//####################################################
                            connectedThread.start();

                            Toast.makeText(context,"Conectado com: " + MAC, Toast.LENGTH_LONG).show();
                        }catch(IOException error){
                            isConection = false;
                            Toast.makeText(context,"Falha ao conectar com: " + MAC, Toast.LENGTH_LONG).show();
                        }
                    }else{
                        Toast.makeText(context,"Falha ao obter o endereço MAC", Toast.LENGTH_LONG).show();
                    }

            }
        }


        public void connect(){
            if(hasBlueetooth){

                if(isConection){
                    //Disconnect
                    try{
                        btSocket.close();
                        isConection = false;

                        //btnConection.setText("Conectar");

                        Toast.makeText(context,"Conexão encerrada", Toast.LENGTH_LONG).show();
                    }
                    catch(IOException error){
                        Toast.makeText(context,"Erro" + error, Toast.LENGTH_LONG).show();
                    }
                }
                else{
                    //Connect
                    Intent openList = new Intent(activity, ShowDevices.class);

                    activity.startActivityForResult(openList,CONNECTION_PERMISSION);
                }

            }

        }

        public boolean isConnected(){
            return isConection;
        }

        public String getMac(){
            return MAC;
        }

        public ConnectionThread getConnectedThread() {
            return connectedThread;
        }
    }

Thread Class

   public class ConnectionThread extends Thread{

            private final InputStream mmInStream;
            private final OutputStream mmOutStream;
            private final int MESSAGE_READ = 3;
            public static Context context;
            Handler mHandler;
            StringBuilder bluetoothData = new StringBuilder();

            public ConnectionThread(BluetoothSocket socket, Context context) {

                InputStream tmpIn = null;
                OutputStream tmpOut = null;

                // Get the input and output streams, using temp objects because
                // member streams are final
                try {
                    tmpIn = socket.getInputStream();
                    tmpOut = socket.getOutputStream();
                } catch (IOException e) {
                }

                mmInStream = tmpIn;
                mmOutStream = tmpOut;
                this.context = context;
                this.mHandler = mHandler;

    //######################## Criacao do handler
                mHandler = new Handler(){
                    @Override
                    public void handleMessage(Message msg) {
                        Toast.makeText(ConnectionThread.context, "Teste", Toast.LENGTH_LONG).show();
                        if(msg.what == MESSAGE_READ){
                            String received = (String)msg.obj;

                            bluetoothData.append(received);

                            int endInformation = bluetoothData.indexOf("}");

                            if(endInformation > 0){
                                //it can be coming in the final, but it's not necessarity came with the start
                                String completeData = bluetoothData.substring(0, endInformation);
                                int informationSize = completeData.length();

                                if(bluetoothData.charAt(0) == '{'){
                                    String finalData = bluetoothData.substring(1, informationSize);
                                    Log.d("Recebidos",finalData);
                                }
                            }
                        }
                    }
                };
            }

            public void run() {
                byte[] buffer = new byte[1024];  // buffer store for the stream
                int bytes; // bytes returned from read()
                //Log.d("Teste", "VERRRR");
                // Keep listening to the InputStream until an exception occurs
                while (true) {
                    try {
                        //  Read from the InputStream
                        bytes = mmInStream.read(buffer);

                        String btData = new String(buffer,0,bytes);
    //########################################
// Aqui é para chamar o mHandler que foi criado lá em cima passando 
// as strings capturadas do arduino
                        // Send the obtained bytes to the UI activity
                        mHandler.obtainMessage(MESSAGE_READ, bytes, -1, btData)
                                  .sendToTarget();
                    } catch (IOException e) {
                        break;
                    }
                }
            }

            /* Call this from the main activity to send data to the remote device */
            public void write(String input) {
                byte[] buffer = input.getBytes();

                try {
                    mmOutStream.write(buffer);
                } catch (IOException e) { }
            }

            public void read(Context context){
                try {
                    Toast.makeText(context,mmInStream.read(), Toast.LENGTH_LONG).show() ;
                }catch(IOException e){}
            }


    }

Basically what's causing the problem is that the thread class's run () method does not call my mHandle, but if I take that entire class from the thread and let it join the MainActivity class it works.

I also encounter the following message

"This Handler class should be static or leaks might occur (anonymous android.os.Handler) Since this Handler is declared as an inner class, it may prevent the outer class from being garbage collected. If the Handler is using a Looper or MessageQueue for a thread other than the main thread, then there is no issue. If the Handler is using the Looper or MessageQueue of the main thread, you need to fix your Handler declaration, as follows: Declare the Handler as a static class; In the outer class, we instantiate the WeakReference to the outer class and pass this object to your Handler when you instantiate the Handler; Make all references to members of the outer class using the WeakReference object. "

    
asked by anonymous 28.09.2018 / 23:36

0 answers