I am developing an app that controls an Arduino robot. For that I need to communicate through Bluetooth. That means sending and receiving data. Why receiving? Because I also have sensors on the robot. I am already able to successfully connect with the Arduino Bluetooth bridge and send data, but I can't receive data from the Arduino. If someone can help me, I will appreciate it.
Here is the main Java code:
public class MainActivity extends AppCompatActivity {
Button forward_btn, forward_left_btn, forward_right_btn, reverse_btn, reverse_right_btn, reverse_left_btn, btnConexao, turbo;
public static final int SOLICITA_ATIVACAO = 1; // é o codigo numero 1, é diferenciado o codigo pq pode haver varias solicitações na msma tela
public static final int SOLICITA_CONEXAO = 2;
BluetoothAdapter meuBluetoothAdapter = null; //declarar o meu adptador bluetooth
BluetoothDevice meuDevice = null;
BluetoothSocket meuSocket = null; // faz transiçao dos dados
TextView myLabel;
Thread workerThread;
byte[] readBuffer;
int readBufferPosition;
volatile boolean stopWorker;
boolean conexao = false; //variavel para a conexao que indica se a conexao está em andamento ou nao
private OutputStream outputStream ;
private static String MAC = null;
private InputStream mmInputStream;
final int RECIEVE_MESSAGE = 1; // Status for Handler
Handler h;
private StringBuilder sb = new StringBuilder();
byte [] command = new byte[256]; //string variable that will store value to be transmitted to the bluetooth module
UUID MEU_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"); // canal de comunicaçao bluetooth, UUID- ID do canal
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
forward_btn = (Button) findViewById(R.id.forward_btn); //definir botoes e associar ao ficheiro xml
forward_left_btn = (Button) findViewById(R.id.forward_left_btn);
forward_right_btn = (Button) findViewById(R.id.forward_right_btn);
reverse_btn = (Button) findViewById(R.id.reverse_btn);
reverse_left_btn = (Button) findViewById(R.id.reverse_left_btn);
reverse_right_btn = (Button) findViewById(R.id.reverse_right_btn);
btnConexao = (Button) findViewById(R.id.btnConexao);
turbo = (Button) findViewById(R.id.turbo);
myLabel = (TextView) findViewById(R.id.label);
forward_btn.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) { // comandos bluetooth correspondentes do arduino
if (conexao) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
command = "1".getBytes();
try {
outputStream.write(command); //transmite o valor do comando para o modulo bluetooth
} catch (IOException e) {
e.printStackTrace();
}
} else if (event.getAction() == MotionEvent.ACTION_UP) {
command = "10".getBytes();
try {
outputStream.write(command);
} catch (IOException e) {
e.printStackTrace();
}
}
}
return false;
}
});
reverse_btn.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (conexao) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
command = "2".getBytes();
try {
outputStream.write(command);
} catch (IOException e) {
e.printStackTrace();
}
} else if (event.getAction() == MotionEvent.ACTION_UP) {
command = "10".getBytes();
try {
outputStream.write(command);
} catch (IOException e) {
}
}
}
return false;
}
});
forward_left_btn.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (conexao) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
command = "3".getBytes();
try {
outputStream.write(command);
} catch (IOException e) {
e.printStackTrace();
}
} else if (event.getAction() == MotionEvent.ACTION_UP) {
command = "10".getBytes();
try {
outputStream.write(command);
} catch (IOException e) {
}
}
}
return false;
}
});
forward_right_btn.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (conexao) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
command = "4".getBytes();
try {
outputStream.write(command);
} catch (IOException e) {
e.printStackTrace();
}
} else if (event.getAction() == MotionEvent.ACTION_UP) {
command = "10".getBytes();
try {
outputStream.write(command);
} catch (IOException e) {
e.printStackTrace();
}
}
}
return false;
}
});
reverse_left_btn.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (conexao) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
command = "5".getBytes();
try {
outputStream.write(command);
} catch (IOException e) {
e.printStackTrace();
}
} else if (event.getAction() == MotionEvent.ACTION_UP) {
command = "10".getBytes();
try {
outputStream.write(command);
} catch (IOException e) {
e.printStackTrace();
}
}
}
return false;
}
});
reverse_right_btn.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (conexao) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
command = "6".getBytes();
try {
outputStream.write(command);
} catch (IOException e) {
e.printStackTrace();
}
} else if (event.getAction() == MotionEvent.ACTION_UP) {
command = "10".getBytes();
try {
outputStream.write(command);
} catch (IOException e) {
e.printStackTrace();
}
}
}
return false;
}
});
turbo.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (conexao) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
command = "9".getBytes();
try {
outputStream.write(command);
} catch (IOException e) {
e.printStackTrace();
}
} else if (event.getAction() == MotionEvent.ACTION_UP) {
command = "10".getBytes();
try {
outputStream.write(command);
} catch (IOException e) {
e.printStackTrace();
}
}
}
return false;
}
});
meuBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); //obter o adaptador do dispositivo e definir como meubluetoothADpt
if (meuBluetoothAdapter == null) { //se o adptador for "null", ou seja nao tem adptador
Toast.makeText(getApplicationContext(), "O seu dispositivo nao possui bluetooth", Toast.LENGTH_LONG).show();
} else if (!meuBluetoothAdapter.isEnabled()) { // != não, so o bluetooth nao tiver ativao, pedir permissão
Intent ativaBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(ativaBluetooth, SOLICITA_ATIVACAO);
}
btnConexao.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (conexao) {
try {
meuSocket.close();
conexao = false;
btnConexao.setText("Conectar");
Toast.makeText(getApplicationContext(), "Bluetooth foi desconectado", Toast.LENGTH_SHORT).show();
} catch (IOException erro) {
Toast.makeText(getApplicationContext(), "Ocorreu um erro ao desconectar:", Toast.LENGTH_SHORT).show();
}
} else {
Intent abreLista = new Intent(MainActivity.this, ListaDispositivos.class);
startActivityForResult(abreLista, SOLICITA_CONEXAO);
}
}
});
}
void beginListenForData () {
final Handler handler = new Handler();
final byte delimiter = 10; //This is the ASCII code for a newline character
stopWorker = false;
readBufferPosition = 0;
readBuffer = new byte[1024];
workerThread = new Thread(new Runnable() {
public void run() {
while (!Thread.currentThread().isInterrupted() && !stopWorker) {
try {
int bytesAvailable = mmInputStream.available();
if (bytesAvailable > 0) {
byte[] packetBytes = new byte[bytesAvailable];
mmInputStream.read(packetBytes);
for (int i = 0; i < bytesAvailable; i++) {
byte b = packetBytes[i];
if (b == delimiter) {
byte[] encodedBytes = new byte[readBufferPosition];
System.arraycopy(readBuffer, 0, encodedBytes, 0, encodedBytes.length);
final String data = new String(encodedBytes, "US-ASCII");
readBufferPosition = 0;
handler.post(new Runnable() {
public void run() {
myLabel.setText(data);
}
});
} else {
readBuffer[readBufferPosition++] = b;
}
}
}
} catch (IOException ex) {
stopWorker = true;
}
}
}
});
workerThread.start();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case SOLICITA_ATIVACAO:
if (resultCode == Activity.RESULT_OK) {
Toast.makeText(getApplicationContext(), "O Bluetooth foi ativado", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), "O bluetooth nao foi ativado, App será encerrada", Toast.LENGTH_LONG).show();
finish();
}
break;
case SOLICITA_CONEXAO: // pede resultado da solicitaçao, se nao obter o resultado exibe toast
if (resultCode == Activity.RESULT_OK) {
MAC = data.getExtras().getString(ListaDispositivos.ENDERECO_MAC);//vai buscar info à lista, ao ENDERECO_MAC
meuDevice = meuBluetoothAdapter.getRemoteDevice(MAC); // obtem dispositivo remoto atraves do MAC
try { // tenta a conexao
meuSocket = meuDevice.createRfcommSocketToServiceRecord(MEU_UUID); // cria um canal de comunicaça0 Rfcomm
meuSocket.connect(); // tenta conexao exibre
try {
outputStream = meuSocket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
try {
mmInputStream = meuSocket.getInputStream();
} catch (IOException e) {
beginListenForData();
e.printStackTrace();
}
conexao = true; // apos conectado, passa a true
btnConexao.setText("Desconectar");
Toast.makeText(getApplicationContext(), "Você foi conectado com" + MAC, Toast.LENGTH_SHORT).show();
} catch (IOException erro) { // se falhar conexao exibe
conexao = false;
Toast.makeText(getApplicationContext(), "Ocorreu um erro:" + erro, Toast.LENGTH_SHORT).show();
//retirar o "+erro" se for publicada a app
}
} else {
Toast.makeText(getApplicationContext(), "Falha ao obter o mac", Toast.LENGTH_SHORT).show();
}
}
}
}
This is the code I added in order to receive data:
void beginListenForData () {
final Handler handler = new Handler();
final byte delimiter = 10; //This is the ASCII code for a newline character
stopWorker = false;
readBufferPosition = 0;
readBuffer = new byte[1024];
workerThread = new Thread(new Runnable() {
public void run() {
while (!Thread.currentThread().isInterrupted() && !stopWorker) {
try {
int bytesAvailable = mmInputStream.available();
if (bytesAvailable > 0) {
byte[] packetBytes = new byte[bytesAvailable];
mmInputStream.read(packetBytes);
for (int i = 0; i < bytesAvailable; i++) {
byte b = packetBytes[i];
if (b == delimiter) {
byte[] encodedBytes = new byte[readBufferPosition];
System.arraycopy(readBuffer, 0, encodedBytes, 0, encodedBytes.length);
final String data = new String(encodedBytes, "US-ASCII");
readBufferPosition = 0;
handler.post(new Runnable() {
public void run() {
myLabel.setText(data);
}
});
} else {
readBuffer[readBufferPosition++] = b;
}
}
}
} catch (IOException ex) {
stopWorker = true;
}
}
}
});
workerThread.start();
}