Moony_cat
Moony_cat

Reputation: 57

Connecting to a bluetooth device programmatically

I am writing a program for a new vehicle security app. the app allows the user to control lock/unlock operations via his phone app. Lets say the user's phone Bluetooth is switched off at first. If that's the case, when he opens the app, the phone bluetooth adapter should be automatically switched on and should connect with the bluetooth module fixed in to the vehicle. according to the code I have done, the programatic enabling of the BT adapter of phone works fine. But the connection to the vehicle BT module does NOT happen.

But if the user opens the app while the phone BT adapter is already switched on, then the connection establishing between the vehicle and phone happens automatically.

I need to know why the connection does NOT happen when the BT adapter is turned on programmatically.

Note - the phone and the vehicle BT module is paired. The bluetooth modules mac address is hard coded in the coding. The coding is as follows. I only pasted the necessary parts. I hope every needed to understand and solve my problem is here. The way I posted the code is pretty messed up. Sorry about that. Hope it's clear. I'm new to this.

    private static final UUID MY_UUID =
      UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

  // Insert bluetooth devices MAC address
  private static String address = "00:19:5D:EF:03:79";


  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

  setContentView(R.layout.main); 
  btAdapter = BluetoothAdapter.getDefaultAdapter();
    btAdapter.enable();


  @Override
  public void onResume() {
    super.onResume();

    btAdapter.enable();

     // Set up a pointer to the remote node using it's address.
    BluetoothDevice device = btAdapter.getRemoteDevice(address);

    // Two things are needed to make a connection:
    //   A MAC address, which we got above.
    //   A Service ID or UUID.  In this case we are using the
    //     UUID for SPP.


    try {
      btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
    } catch (IOException e) {
      errorExit("Fatal Error", "In onResume() and socket create failed: " + e.getMessage() + ".");
    }

    // Make sure Discovery isn't going on when you attempt to connect and pass your message.

    btAdapter.cancelDiscovery();

    // Establish the connection.  This will block until it connects.

    try {
      btSocket.connect();

    } catch (IOException e) {
      try {
        btSocket.close();
      } catch (IOException e2) {
        errorExit("Fatal Error", "In onResume() and unable to close socket during connection failure" + e2.getMessage() + ".");
      }
    }

    // Create a data stream so we can talk to server.

    try {
      outStream = btSocket.getOutputStream();
    } catch (IOException e) {
      errorExit("Fatal Error", "In onResume() and output stream creation failed:" + e.getMessage() + ".");
    }
  }

Upvotes: 1

Views: 3586

Answers (1)

mach
mach

Reputation: 8395

There might be a timing problem, onCreate and onResume are called in very short order. In the case that the BT is not enabled the code in onResume might be called before the BT service is online.

My advice: Try to delay the initiation a few seconds by putting the code in a Runnable.

private Handler mHandler = new Handler();

public void onCreate() {

     [...]

     mHandler.postDelayed(new Runnable() {
         @Override
         public void run() {
             btAdapter.enable();
              // Set up a pointer to the remote node using it's address.
             BluetoothDevice device = btAdapter.getRemoteDevice(address);
             // Two things are needed to make a connection:
             //   A MAC address, which we got above.
             //   A Service ID or UUID.  In this case we are using the
             //     UUID for SPP.
             try {
                 btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
             } catch (IOException e) {
                 errorExit("Fatal Error", "In onResume() and socket create failed: " +                  e.getMessage() + ".");                
             }

             // Make sure Discovery isn't going on when you attempt to connect and pass your message.

             btAdapter.cancelDiscovery();

             // Establish the connection.  This will block until it connects.

             try {
               btSocket.connect();

             } catch (IOException e) {
               try {
                 btSocket.close();
               } catch (IOException e2) {
                 errorExit("Fatal Error", "In onResume() and unable to close socket during connection failure" + e2.getMessage() + ".");
               }
             }

             // Create a data stream so we can talk to server.

             try {
               outStream = btSocket.getOutputStream();
             } catch (IOException e) {
               errorExit("Fatal Error", "In onResume() and output stream creation failed:" + e.getMessage() + ".");
             }
     }, 5000); // 5 second delay

     [...]

Caveats: This works really bad if you exit the app promptly after startup. Put the runnable in a member variable and call mHandler.removeCallback(Runnable) in onDestroy().

Upvotes: 1

Related Questions