Paul
Paul

Reputation: 536

Initiate a bluetooth tether programmatically

The Android bluetooth class is fairly easy to use with regards to enabling, discovering, listing paired devices, and connecting to bluetooth devices.

My plan was to initiate a connection to another bluetooth device that provides tethering via bluetooth.

After a bit of investigation, this doesn't look feasible - it looks like I'd have to implement the profile myself, and have root access to do the networking, and do everything in an app.

There also doesn't seem to be an intent I can trigger via Settings to initiate a bluetooth connection, the best I can do is turn it on.

Am I missing something - if the system doesn't expose a method for initiating a system level bluetooth connection, am I out of luck?

Upvotes: 2

Views: 2778

Answers (1)

andredami
andredami

Reputation: 71

A private profile is already present in the API: BluetoothPan

Bluetooth PAN (Personal Area Network) is the correct name to identify tethering over Bluetooth.

This private class allows you to connect to and disconnect from a device exposing the PAN Bluetooth Profile, via the public boolean connect(BluetoothDevice device) and public boolean disconnect(BluetoothDevice device) methods.

Here is a sample snippet connecting to a specific device:

String sClassName = "android.bluetooth.BluetoothPan";

class BTPanServiceListener implements BluetoothProfile.ServiceListener {

    private final Context context;

    public BTPanServiceListener(final Context context) {
        this.context = context;
    }

    @Override
    public void onServiceConnected(final int profile,
                                   final BluetoothProfile proxy) {
        Log.e("MyApp", "BTPan proxy connected");
        BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice("AA:BB:CC:DD:EE:FF"); //e.g. this line gets the hardware address for the bluetooth device with MAC AA:BB:CC:DD:EE:FF. You can use any BluetoothDevice
        try {
            Method connectMethod = proxy.getClass().getDeclaredMethod("connect", BluetoothDevice.class);
            if(!((Boolean) connectMethod.invoke(proxy, device))){
                Log.e("MyApp", "Unable to start connection");
            }
        } catch (Exception e) {
            Log.e("MyApp", "Unable to reflect android.bluetooth.BluetoothPan", e);
        }
    }

    @Override
    public void onServiceDisconnected(final int profile) {
    }
}

try {

     Class<?> classBluetoothPan = Class.forName(sClassName);

     Constructor<?> ctor = classBluetoothPan.getDeclaredConstructor(Context.class, BluetoothProfile.ServiceListener.class);
     ctor.setAccessible(true);
     Object instance = ctor.newInstance(getApplicationContext(), new BTPanServiceListener(getApplicationContext()));
} catch (Exception e) {
     Log.e("MyApp", "Unable to reflect android.bluetooth.BluetoothPan", e);
}

Upvotes: 4

Related Questions