How to check Bluetooth tethering status programmat

2019-01-12 04:36发布

问题:

Is there any way to find out bluetooth tethering is enabled or disabled programmatically in Android 2.3+(any version after 2.3+)?

I am not asking to enable/disable it, but only to know if it is enabled currently or not.

回答1:

It turns out that BluetoothPan (Personal Area Networking) is the keyword for tethering. I pored over the API documentation and Android source code, but the brief examples in the comments were misleading. This poster provided an example but I had trouble with it initially:
Android BluetoothPAN to create TCP/IP network between Android device and Windows7 PC

I tried various other methods including checking the IP address of the BT device. However no Bluetooth network device exists, so there's no IP to check.
Detect USB tethering on android

Back to the BluetoothPan code... The example in the first thread was incomplete (no ServiceListener implementation). I tried a standard one but the isTetheringOn proxy call failed. The crucial piece is that the onServiceConnected() callback needs at least one line of code or the compiler optimizes it away. It also shouldn't disconnect the proxy like most other examples have. Here's the working code:

BluetoothAdapter mBluetoothAdapter = null;
Class<?> classBluetoothPan = null;
Constructor<?> BTPanCtor = null;
Object BTSrvInstance = null;
Class<?> noparams[] = {};
Method mIsBTTetheringOn;

@Override
public void onCreate() {
    Context MyContext = getApplicationContext();
    mBluetoothAdapter = getBTAdapter();
    try {
        classBluetoothPan = Class.forName("android.bluetooth.BluetoothPan");
        mIsBTTetheringOn = classBluetoothPan.getDeclaredMethod("isTetheringOn", noparams);
        BTPanCtor = classBluetoothPan.getDeclaredConstructor(Context.class, BluetoothProfile.ServiceListener.class);
        BTPanCtor.setAccessible(true);
        BTSrvInstance = BTPanCtor.newInstance(MyContext, new BTPanServiceListener(MyContext));
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private BluetoothAdapter getBTAdapter() {
    if (android.os.Build.VERSION.SDK_INT <= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1)
        return BluetoothAdapter.getDefaultAdapter();
    else {
        BluetoothManager bm = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
        return bm.getAdapter();
    }
}

// Check whether Bluetooth tethering is enabled.
private boolean IsBluetoothTetherEnabled() {
    try {
        if(mBluetoothAdapter != null) {
            return (Boolean) mIsBTTetheringOn.invoke(BTSrvInstance, (Object []) noparams);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return false;
}

public 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) {
        //Some code must be here or the compiler will optimize away this callback.
        Log.i("MyApp", "BTPan proxy connected");
    }

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