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