2

In my app I established a communication with car via OBD port and Bluetooth. I have a SharedPreferences that contains the preferences of commands to shown set by a Preference Activity.

I would to use a Shared Array of commands that can change their content dynamically and send the new ArrayList to the Thread that manage communication.

There is some way to do that or simply use SharedPreferences and when change the content of the Array i restart the Thread that manage comunications with the devices.

I need something that can be changed (add or remove commands from ArrayList) and in the same time notify to the Thread that send commands that the ArrayList has changed the items.

Method that manage connections

   private synchronized void manage() {
        Log.d(TAG, "connected, Socket Type:");

        // Cancel the thread that completed the connection
        if (mConnectThread != null) {
            mConnectThread.cancel();
            mConnectThread = null;
        }

        // Cancel any thread currently running a connection
        if (mConnectedThread != null) {
            mConnectedThread.cancel();
            mConnectedThread = null;
        }
        // Cancel any thread currently managing connections
        if (mManageThread != null) {
            mManageThread.cancel();
            mManageThread = null;
        }

        if (mmSocket != null && mmDevice != null) {
            // Start the thread to manage the connection and perform transmissions
            mManageThread = new ManageDataThread(mmSocket);
            mManageThread.start();

            // Send the name of the connected device back to the UI Activity
            Message msg = mHandler.obtainMessage(Constants.MESSAGE_DEVICE_NAME);
            Bundle bundle = new Bundle();
            bundle.putString(Constants.DEVICE_NAME, mmDevice.getName());
            msg.setData(bundle);
            mHandler.sendMessage(msg);
            // Update UI title
            updateUserInterfaceTitle();
        }
    }

And the Thread mManageThread that manage connetions and message exchange

   public class ManageDataThread extends Thread {

        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;
        private boolean wait_response = false;
        private String typeCommand;

        public ManageDataThread(BluetoothSocket socket) {
            Log.d(TAG, "create ManageDataThread: ");

            mmSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            // Get the BluetoothSocket input and output streams
            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) {
                Log.e(TAG, "temp sockets not created", e);
            }

            mmInStream = tmpIn;
            mmOutStream = tmpOut;
            mState = STATE_CONNECTED;

        }

        public void run() {

            ObdCommand obc = new ObdCommand();

            while(canGo) {
                for (final String command : commandArray) {

                    byte[] send = command.getBytes();
                    write(send); //Setta la wait_response come true
                    //mState = STATE_WAIT_RESPONSE;

                    byte[] buffer = new byte[1024];
                    int bytes;

                    // Keep listening to the InputStream while connected
                    while (wait_response) {
                        try {
                            // Read from the InputStream
                            bytes = mmInStream.read(buffer);

                            obc.readResult(mmInStream);

                            //formattedMessage = obc.getResult();
                            formattedMessage = obc.getCalculatedResult();
                            //Ritorno la ripologia di comando
                            typeCommand = obc.getCommandType();
                            //buffer = (byte) obc.getBuffer();

                            // Send the obtained bytes to the UI Activity
                            /*mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, formattedMessage)
                                    .sendToTarget();*/

                            mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, typeCommand
                                    + ""
                                    + formattedMessage)
                                    .sendToTarget();

                            wait_response = false;

                        } catch (IOException e) {
                            Log.e(TAG, "disconnected", e);
                            connectionLost();
                            break;
                        }
                    }


                }

                try {
                    ManageDataThread.sleep(400);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }



        }

        /**
         * Write to the connected OutStream.
         *
         * @param buffer The bytes to write
         */
        public void write(byte[] buffer) {
            try {
                mmOutStream.write(buffer);

                // Share the sent message back to the UI Activity
                mHandler.obtainMessage(Constants.MESSAGE_WRITE, -1, -1, buffer)
                        .sendToTarget();
                wait_response = true;
            } catch (IOException e) {
                Log.e(TAG, "Exception during write", e);
                canGo = false;
            }
        }

        public void cancel() {
            try {
                canGo = false;
                mmSocket.close();
            } catch (IOException e) {
                Log.e(TAG, "close() of connect socket failed", e);
            }
        }
    }

Here i can't use some method that check is Array is changed and change the command list in the Thread? The only way is stop and restart method?

And here the call in MainActivity

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

        Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar);
        setSupportActionBar(myToolbar);

        rpmTxt = (TextView) findViewById(R.id.rpmText);
        speedTxt = (TextView) findViewById(R.id.speedText);
        coolantTxt = (TextView) findViewById(R.id.colantTempText);
        carbTxt = (TextView) findViewById(R.id.carbTypeText);
        nodata = (TextView) findViewById(R.id.nodataTxt);
        canerror = (TextView) findViewById(R.id.canErrorTxt);

        /**
         * SharedPreferences per gestire quali cose mostrare nell'activity
         */
        showUserSettings();

        /*Check bluetooth sensor*/
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (mBluetoothAdapter == null) {
            // Device does not support Bluetooth
            Toast.makeText(getApplicationContext(), "Il telefono NON supporta il bluetooth",
                    Toast.LENGTH_LONG).show();

        }

        // If BT is not on, request that it be enabled.
        // setupChat() will then be called during onActivityResult
        if (!mBluetoothAdapter.isEnabled()) {
            Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
            // Otherwise, setup the chat session
        } else if (mBluetoothService == null) {
            setupChat();
        }

    }

And setupchat() method that call Threads in the MyBluetoothService.java

 /**
     * Set up the UI and background operations for chat.
     */
    private void setupChat() {
        Log.d(TAG, "setupChat()");

        // Initialize the BluetoothChatService to perform bluetooth connections
        mBluetoothService = new MyBluetoothService(MainActivity.this, mHandler, commandArray);

        // Initialize the buffer for outgoing messages
        //mOutStringBuffer = new StringBuffer("");
    }

that send the commandArray read from sharedPreferences to the class that start Threads

Dario
  • 732
  • 7
  • 30
  • I think you could do this with [`OnSharedPreferenceChangeListener`](https://developer.android.com/reference/android/content/SharedPreferences.OnSharedPreferenceChangeListener.html) but it wouldn't facilitate communication between two threads because the `onSharedPreferenceChanged` is called on the main thread so you'll still need to implement that. – Jon Aug 18 '17 at 21:00
  • @Jonathan727 But how can i check this to the Thread that Manage comunication? As you say i check the change to the MainActivity and if the OnSharedPreferenceChangeListener is focused i stop the Thread and start another one with the new Array? I will post some code so my question is more clear – Dario Aug 19 '17 at 10:27

0 Answers0