I am writing an android app that can interact with arduino. My app have 2 buttons 1. Connect 2. Dis-Connect, to start and stop bluetooth service. I have a test sketch on arduino which when receives "1" will send "404"(just to test!) back to my phone.
Here's my Bluetooth service class
public class BluetoothService extends Service {
private BluetoothManager bluetoothManager;
private ServiceHandler mSHandler;
public BluetoothService(){}
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
}
}
@Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("ServiceStartArguments", android.os.Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
Looper mSLoop = thread.getLooper();
mSHandler = new ServiceHandler(mSLoop);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Message msg = mSHandler.obtainMessage();
msg.arg1 = startId;
mSHandler.sendMessage(msg);
bluetoothManager=new BluetoothManager();
bluetoothManager.writeData("1", getApplicationContext()); //sending "1" to arduino
String str= bluetoothManager.readData(getApplicationContext()); //reading "404" from arduino
Toast.makeText(getApplicationContext(), str, Toast.LENGTH_LONG).show();
return START_STICKY;
}
@Override
public void onDestroy(){
bluetoothManager.turnBluetoothOff();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
Now here's my BluetoothManager class:
public class BluetoothManager {
private BluetoothAdapter bluetoothAdapter;
private BluetoothDevice bluetoothDevice;
private BluetoothSocket bluetoothSocket;
private ConnectedThread connectedThread;
private byte[] buffer;
public BluetoothManager(){
buffer=new byte[256];
bluetoothSocket=null;
bluetoothAdapter=null;
bluetoothDevice=null;
connectedThread=null;
getBluetoothAdapter();
if(!isBluetoothAvailable()){
turnBluetoothOn();
}
scanToConnect();
}
public void turnBluetoothOff(){
try {
bluetoothSocket.close();
bluetoothSocket=null;
bluetoothAdapter.cancelDiscovery();
bluetoothAdapter.disable();
bluetoothAdapter=null;
bluetoothDevice=null;
}catch(Exception e){
e.printStackTrace();
}
}
private boolean isBluetoothAvailable(){
return bluetoothAdapter.isEnabled();
}
private void turnBluetoothOn(){
bluetoothAdapter.enable();
}
public String readData(Context context){
String outputString=null;
if(isBluetoothAvailable()) {
outputString = connectedThread.read(buffer);
}else{
Toast.makeText(context, "Error: Not Connected", Toast.LENGTH_LONG).show();
}
return outputString;
}
public void writeData(String string, Context context){
if(isBluetoothAvailable()) {
connectedThread.write(string.getBytes());
}else{
Toast.makeText(context, "Error: Not Connected", Toast.LENGTH_LONG).show();
}
}
private void getBluetoothAdapter(){
try{
bluetoothAdapter=BluetoothAdapter.getDefaultAdapter();
}catch (Exception e){
e.printStackTrace();
}
}
private void scanToConnect(){
Set<BluetoothDevice> pairedDevices=bluetoothAdapter.getBondedDevices();
if(pairedDevices.size()>0){
try {
for (BluetoothDevice device : pairedDevices) {
if (device.getName().equals("HC-05")) {
bluetoothDevice = device;
new connectBt(bluetoothDevice);
break;
}
}
}catch(Exception e){
e.printStackTrace();
}
}
}
private class connectBt extends Thread {
public connectBt(BluetoothDevice device) {
BluetoothSocket tmp = null;
bluetoothDevice = device;
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
try {
tmp = device.createRfcommSocketToServiceRecord(uuid);
} catch (IOException e) {
e.printStackTrace();
}
bluetoothSocket = tmp;
run();
}
public void run() {
bluetoothAdapter.cancelDiscovery();
try {
bluetoothSocket.connect();
connectedThread = new ConnectedThread(bluetoothSocket);
} catch (IOException connectException) {
closeSocket();
}
}
private void closeSocket() {
try {
bluetoothSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private class ConnectedThread extends Thread{
private InputStream mInput=null;
private OutputStream mOutput=null;
private String strInput;
public ConnectedThread(BluetoothSocket socket){
bluetoothSocket=socket;
InputStream tmpIn=null;
OutputStream tmpOut=null;
try{
tmpIn=socket.getInputStream();
tmpOut=socket.getOutputStream();
}catch(IOException e){
e.printStackTrace();
closeSocket();
}
mInput=tmpIn;
mOutput=tmpOut;
}
public void write(byte[] bytes){
try{
mOutput.write(bytes);
}catch(IOException e){
e.printStackTrace();
}
}
public String read(byte[] bytes){
try {
mInput.read(bytes);
strInput = new String(bytes);
}catch(Exception e){
e.printStackTrace();
}
return strInput;
}
public void closeSocket(){
try{
bluetoothSocket.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
}
My problem is that I am have to press connect button twice to connect to arduino, first press will enable bluetooth and second press will connect to arduino, then send and receive data. But this is not as I intended, enabling bluetooth and connecting should have taken place with a single press. So why is this behaving like this?
N.B: I am newbie to java and android.
After enabling Bluetooth it will take sometime to get the paired device list. But in this case you are reading the paired devices immediately after turning on the Bluetooth. May be you delay the connection part.
Use handler methods to delay the execution.