Question

Ive written code that connects and sends data from an Android device to another via Bluetooth.

It all works when run from that class. When I create an instance of the class the data gets sent to the output stream before the connection creation has finished.

How do I check that the connection is up before sending data?

package com.flightscope.app.metawatch;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import com.flightscope.app.metawatch.Crc;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.util.Log;

public class MetawatchConnected {

//  public static final String TAG = "MetawatchConnected";

    private BluetoothSocket mSocket;
    private BluetoothDevice mMetawatchDevice;
    private final BluetoothAdapter mAdapter;
//  private final InputStream mInput;
//  private final OutputStream mOutput;

    ConnectThread mConnectThread = null;
    ConnectedThread mConnectedThread = null;

    final private String TAG = "MetaWatch Connection Thread";


    public MetawatchConnected(String address)
    {
        Log.d(TAG, "Start");
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        mMetawatchDevice = mAdapter.getRemoteDevice(address);

        if(mConnectThread == null)
        {
            mConnectThread = new ConnectThread(mMetawatchDevice);
            mConnectThread.start();
        }

    }

    public void getBmp()
    {
        Bitmap bmp = Bitmap.createBitmap(96, 96, Bitmap.Config.RGB_565);
        Canvas canvas = new Canvas(bmp);
        Paint paint = new Paint();

        paint.setColor(Color.BLACK);
        paint.setTextSize(14);
        Typeface tp = Typeface.DEFAULT;
        paint.setTypeface(tp);
        canvas.drawColor(Color.WHITE);
        canvas.drawText("Carry Distance", 0, 14, 0, 50, paint);

        int[] pixelArray = new int[96 * 96];
        bmp.getPixels(pixelArray, 0, 96, 0, 0, 96, 96);

        int[] buffer = new int[1152];

        for(int i = 0; i < buffer.length; i++)
        {
            int[] bytes = new int[8];

            for(int j = 0; j < bytes.length; j++)
            {
                if(pixelArray[(i * 8) + j ] != Color.BLACK)
                {
                    bytes[j] = 0;
                }
                else
                {
                    bytes[j] = 1;
                }

                buffer[i] = (128 * bytes[7]) + (64 * bytes[6]) + (32* bytes[5]) + (16 * bytes[4]) + 
                            (8 * bytes[3]) + (4 * bytes[2]) + (2 * bytes[1]) + (1 * bytes[0]);

            }

        }

        //fillScreen();

        for(int z = 30; z < 96; z +=2 )
        {
    //      int[] buffer = {0x01, 0x20, 0x40, 0x00, (i), 0xd8, 0xb6, 0x6d, 0xdb, 0xb6, 0x6d, 
    //                      0xdb, 0xb6, 0x6d, 0xdb, 0xb6, 0x0d, (i + 1), 0x00, 0x00, 0x00, 0x00, 
    //                      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

            int[] send = new int[30];
            Log.d(TAG, ""+z);
            send[0] = 0x01;
            send[1] = 0x20;
            send[2] = 0x40;
            send[3] = 0x00;
            send[4] = z;
            for(int j = 0; j < 12; j++)
            {
                send[5+j] = buffer[((z * 12) + j)];
            }

            send[17] = (z + 1);
            for(int j = 0; j < 12; j++)
            {
                send[18+j] = buffer[(12 * z) + 12 + j];
            }

            try
            {
                final Crc sendMsg = new Crc(send);
                mConnectedThread.write(sendMsg.message);
            }
            catch(Exception e) { Log.d(TAG, "Write Exception"); }
        }






    }

    public void fillScreen()
    {
        int[] bytes = new int[5];

        bytes[0] = 0x01;
        bytes[1] = (byte) (bytes.length+2); // packet length
        bytes[2] = 0x44; 
        bytes[3] = (byte) 0x02; 
        bytes[4] = (byte) 0x00;
    }



class ConnectThread extends Thread {


    public ConnectThread(BluetoothDevice device)
        {
            BluetoothSocket temp = null;
            mMetawatchDevice = device;
            try
            {
                //temp = btDevice.createRfcommSocketToServiceRecord(myUUID);

                Method m = mMetawatchDevice.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
                 temp = (BluetoothSocket) m.invoke(mMetawatchDevice, 1);

            } //catch(IOException e) {  }
             catch (SecurityException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            mSocket = temp;
        }

        public void run()
        {
            mAdapter.cancelDiscovery();

            try 
            {
                if(mSocket!=null){
                    Log.d(TAG, "Attempting to Connect via Bluetooth");
                mSocket.connect();
                Log.d(TAG,"\nConnected via Bluetooth");

                mConnectedThread = new ConnectedThread(mSocket);
                mConnectedThread.start();
                Log.d(TAG, "Connected Thread Started");
                }
            }
            catch (IOException connectException)
            {
                try
                {
                    Log.d(TAG, "Attempt Close");
                    mSocket.close();
                    Log.d(TAG, "Socket Closed");
                    Log.d(TAG, "Exception : "+connectException.getMessage());
                }
                catch(IOException closeException) { Log.d(TAG, "Open and Close Failed"); }              
            }
        }

        public void cancel()
        {
            try
            {
                Log.d(TAG, "Attempting To Close ConnectingThread Socket");
                mSocket.close();
                Log.d(TAG, "ConnectingThread Socket Closed");
            }
            catch(IOException e) { Log.d(TAG, "Failed To Close ConnectThread Socket"); }
        }
    }

class ConnectedThread extends Thread {

    private final BluetoothSocket mmSocket;
    private final InputStream mmInput;
    private final OutputStream mmOutput;

    public ConnectedThread(BluetoothSocket socket)
    {
        mmSocket = socket;
        InputStream tmpIn = null;
        OutputStream tmpOut = null;

        try
        {
            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();
        }
        catch(IOException e) { }

        mmInput = tmpIn;
        mmOutput = tmpOut;
    }

    public void run()
    {
        byte[] buffer = new byte[1024];
        int bytes;

        while(true)
        {
            try
            {
                bytes = mmInput.read(buffer);
                Log.d(TAG, "Received : "+bytes);
            }
            catch(IOException e) { break; }
        }
    }

    public void write(byte[] bytes)
    {  
        try
        {
            mmOutput.write(bytes);
            Log.d(TAG, "Bytes Sent");
        }
        catch (IOException e) { Log.d(TAG, "Bytes Not Sent"); }
    }

    public void cancel()
    {
        try
        {
            Log.d(TAG, "Attempting to Close ConnectedThread Socket");
            mmSocket.close();
            Log.d(TAG, "ConnectedThread Socket Closed");
        }
        catch(IOException e) { Log.d(TAG, "ConnectedThread Failed To Close"); }
    }

}




}

MetawatchConnected gets called from a different class, then right after that I send data using getBmp() from the calling class

Calling code

String address = mActiveProfile.metawatchAddressBluetooth;

      if(address != null)
      {  
          if(mMetawatchConnected == null)
          {
              mMetawatchConnected = new MetawatchConnected(address);
          }

      }

              mMetawatchConnected.getBmp();
Was it helpful?

Solution

It seems that you have a synchronization issue. What I had to do in my class was implement a timer. The timer basically controls everything, it checks if BT is connected, if the network is connected, etc... But my activity required long running BT / network connections, I don't think yours does.

Why don't you add an isConnected() method to your MetawatchConnected class? After connection is complete, set it to true. Then you can:

if (mMetawatchConnected.isConnected())
{

    mMetawatchConnected.getBmp();
}

You will still have to deal with synchronization issues such as waiting for the initial connection, but I think you get the point.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top