Android connect to a paired bluetooth headset
Asked Answered
H

4

1

I want to simulate the action of going throgh Settings->Wireless->Bluetooth and connect a paired bluetooth headset programmatically. I've done some search in Stackoverflow and Google, both indicating that there is no solution available before API level 11. However, I'm interested in working it out by peeking in the source code of bluetooth implementation of Android. The problem is that I'm not aware of which specific source code I should review. Any suggestions? Many thanks.

Husein answered 28/5, 2011 at 13:16 Comment(0)
Q
2

OK, I got this updated to support Honeycomb and up. You need to add new functions to the interface. I did that here:

interface IBluetoothA2dp {
boolean connectSink(in BluetoothDevice device); // Pre API 11 only
boolean disconnectSink(in BluetoothDevice device); // Pre API 11 only
boolean connect(in BluetoothDevice device); // API 11 and up only
boolean disconnect(in BluetoothDevice device); // API 11 and up only
boolean suspendSink(in BluetoothDevice device); // all
boolean resumeSink(in BluetoothDevice device); // all
BluetoothDevice[] getConnectedSinks();  // change to Set<> once AIDL supports, pre API 11 only
BluetoothDevice[] getNonDisconnectedSinks();  // change to Set<> once AIDL supports, 
int getSinkState(in BluetoothDevice device);
boolean setSinkPriority(in BluetoothDevice device, int priority); // Pre API 11 only
boolean setPriority(in BluetoothDevice device, int priority); // API 11 and up only
int getPriority(in BluetoothDevice device); // API 11 and up only
int getSinkPriority(in BluetoothDevice device); // Pre API 11 only
boolean isA2dpPlaying(in BluetoothDevice device); // API 11 and up only

}

Then you need to check the API version before calling functions in this interface. Here is my example:

            if (android.os.Build.VERSION.SDK_INT < 11) {

            IBluetoothA2dp ibta = getIBluetoothA2dp();
            try {
                Log.d(LOG_TAG, "Here: " + ibta.getSinkPriority(device));
                if (ibta != null)
                    ibta.connectSink(device);
            } catch (Exception e) {
                Log.e(LOG_TAG, "Error " + e.getMessage());
            }
        } else {
            IBluetoothA2dp ibta = getIBluetoothA2dp();
            try {
                Log.d(LOG_TAG, "Here: " + ibta.getPriority(device));
                if (ibta != null)
                    ibta.connect(device);
            } catch (Exception e) {
                Log.e(LOG_TAG, "Error " + e.getMessage());
            }
        }

Hope this helps. I was able to get the same app to work with both interfaces.

Quadrilateral answered 11/1, 2012 at 4:9 Comment(0)
H
8

After days of struggling, I've now managed to do it, cheers :)

  1. Add android.bluetooth.IBluetoothA2dp.aidl in your /src dir of your app;
  2. Add this private method in your code:

    private IBluetoothA2dp getIBluetoothA2dp() {
    
    IBluetoothA2dp ibta = null;
    
    try {
    
        Class c2 = Class.forName("android.os.ServiceManager");
    
        Method m2 = c2.getDeclaredMethod("getService", String.class);
        IBinder b = (IBinder) m2.invoke(null, "bluetooth_a2dp");
    
        Log.d("Felix", "Test2: " + b.getInterfaceDescriptor());
    
        Class c3 = Class.forName("android.bluetooth.IBluetoothA2dp");
    
        Class[] s2 = c3.getDeclaredClasses();
    
        Class c = s2[0];
        // printMethods(c);
        Method m = c.getDeclaredMethod("asInterface", IBinder.class);
    
        m.setAccessible(true);
        ibta = (IBluetoothA2dp) m.invoke(null, b);
    
    } catch (Exception e) {
        Log.e("flowlab", "Erroraco!!! " + e.getMessage());
    }
    
  3. Test it with this:

    private void testBluetoothA2dp(BluetoothDevice device) {
    // TODO Auto-generated method stub
    // TODO Auto-generated method stub
    IBluetoothA2dp ibta = getIBluetoothA2dp();
    try {
        Log.d("Felix", "Here: " + ibta.getSinkPriority(device));
        ibta.connectSink(device);
    } catch (RemoteException e) {
        // * TODO Auto-generated catch block
        e.printStackTrace();
    }
    

    }

I'm not able to provide references of these code since I've spent lots of time googling, checking out stackoverflow, and reviewing Android source code, but failed to keep track of sources. Many thanks to you guys in Stackoverflow :)

Husein answered 29/5, 2011 at 16:16 Comment(1)
Hi there, I am also trying to connect a A2dp bluetooth headset to Android. I have already successfully paired with the bluetooth device without user interface as show in: #3463468 </br> But even using your code after pairing I still cannot connect to the headset (no error on Android 4.0.3 - Galaxy Note 1 ). Any idea ?Lemuel
Q
2

OK, I got this updated to support Honeycomb and up. You need to add new functions to the interface. I did that here:

interface IBluetoothA2dp {
boolean connectSink(in BluetoothDevice device); // Pre API 11 only
boolean disconnectSink(in BluetoothDevice device); // Pre API 11 only
boolean connect(in BluetoothDevice device); // API 11 and up only
boolean disconnect(in BluetoothDevice device); // API 11 and up only
boolean suspendSink(in BluetoothDevice device); // all
boolean resumeSink(in BluetoothDevice device); // all
BluetoothDevice[] getConnectedSinks();  // change to Set<> once AIDL supports, pre API 11 only
BluetoothDevice[] getNonDisconnectedSinks();  // change to Set<> once AIDL supports, 
int getSinkState(in BluetoothDevice device);
boolean setSinkPriority(in BluetoothDevice device, int priority); // Pre API 11 only
boolean setPriority(in BluetoothDevice device, int priority); // API 11 and up only
int getPriority(in BluetoothDevice device); // API 11 and up only
int getSinkPriority(in BluetoothDevice device); // Pre API 11 only
boolean isA2dpPlaying(in BluetoothDevice device); // API 11 and up only

}

Then you need to check the API version before calling functions in this interface. Here is my example:

            if (android.os.Build.VERSION.SDK_INT < 11) {

            IBluetoothA2dp ibta = getIBluetoothA2dp();
            try {
                Log.d(LOG_TAG, "Here: " + ibta.getSinkPriority(device));
                if (ibta != null)
                    ibta.connectSink(device);
            } catch (Exception e) {
                Log.e(LOG_TAG, "Error " + e.getMessage());
            }
        } else {
            IBluetoothA2dp ibta = getIBluetoothA2dp();
            try {
                Log.d(LOG_TAG, "Here: " + ibta.getPriority(device));
                if (ibta != null)
                    ibta.connect(device);
            } catch (Exception e) {
                Log.e(LOG_TAG, "Error " + e.getMessage());
            }
        }

Hope this helps. I was able to get the same app to work with both interfaces.

Quadrilateral answered 11/1, 2012 at 4:9 Comment(0)
E
2

I tried this on Android 4.2 and following line returns null. It was working on 4.1, any ideas ?

IBinder b = (IBinder) m2.invoke(null, "bluetooth_a2dp");
Enid answered 20/11, 2012 at 2:15 Comment(2)
Did you add: android.bluetooth.IBluetoothA2dp.aidl in your /src dir of your app; in your /src directory?Husein
yes i did. This works fine till android 4.1. For 4.2 it gives errorsEnid
T
-2

this is KIND of related to the connect/reconnect issue (the ANSWER being an apple script) ..

i just bought an android htc one V and am using it as a hotspot via the app PdaNet (installed both on my phone and my mac os 10.5.8 ppc laptop).

I can't seem to get the hotspot tethering working via wifi or usb but it DOES work well with BLUETOOTH! only problem is the connection only lasts up to 2 minutes to 40 minutes (looking at it now ha, a record) and i have to reconnect manually, which only takes 2 seconds but it'd be nice if the Network aspect of my mac could AUTO reconnect.

my cell is not the problem as it's sending out a constant signal (although i could be losing signal temporarily from my cell, which is normal connection stuff) .. the problem is having my laptop auto RE-connect. my laptop and htc one v DO remain paired, there's just no AUTO-RECONNECT on the laptop end.

i wish i knew apple scripts bcs then i could maybe write an apple script that AUTO-RECONNECTS a lost bluetooth connection .. or maybe a widget could do this? if so i'd have it made in the shade as bluetooth tethering is working NICELY.

i was hoping this would help both myself and others searching for the same answers .. if you keep this thread open i could return later with some possible apple script solutions (which i will have to quickly learn) .. thanks -marcus

Thou answered 24/6, 2013 at 10:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.