cancel
Showing results for 
Search instead for 
Did you mean: 

Bluetooth scan and permissions. BLE and the CompanionDeviceManager

platinio
Honored Guest

Hi,

I am working on a project that connects  BLE Gatt devices ( heart rate, FTMS, Power, speed, cadence profiles... ) to Oculus Quest headsets .

I've been using the alpha and release channels to regularly upload and distribute the app with a test user group.

I got this error message the last time that I uploaded  a build : " DO not use location permissions to scan for nearby Bluetooth devices. Update your app to use the COmpanionDeviceManager API to make and manage connections...." 

I need help using the CompanionDeviceManager API on Oculus Quest. I've been trying A LOT of things and permissions, but I can't make it work on Quest. The device scan seems to silently fail.

I made it work seamlessly on my Android phone ( the COmpanionDeviceManager API  BLE device scan & bonding ), but it doesn't work on Oculus Quest.

 

Also :  there are these 2 valid permissions in the Quest VRC checks,  BLUETOTH_SCAN and BLUETOOTH_CONNECT . The problem is that they don't seem to be accepted by the Oculus Quest headset.

They are permissions introduced with Android S.

https://developer.oculus.com/distribute/vrc-quest-security-2/

 

Please help,

I would really need to talk with someone from Oculus about the BLE support.

 

 

 

 

 

22 REPLIES 22

dprh
Explorer

Companion API finally available since v37!

Valepapi
Explorer

I am trying to find a tutorial to follow in order to use the companion api and ble, but I am quite puzzled. Do you have any example on how to use that?

 

Thanks

Do you have any success with companion API?

Valepapi
Explorer

babichev i couldnt find any example so i tried to write to the Oculus dev and they didnt have any example too.. so i gave up on bt and completed the same thing via wifi

You can find example in Android documentation here: https://developer.android.com/guide/topics/connectivity/companion-device-pairing#java  I just wanted to see if this really works on Quest before deep diving into JNI. But no one seems to have tried it.

I can confirm it works now. Here is example code.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == SELECT_DEVICE_REQUEST_CODE) {
        if (resultCode == Activity.RESULT_OK && data != null) {
            ScanResult result = data.getParcelableExtra(CompanionDeviceManager.EXTRA_DEVICE);
            if (result != null) {
                stopListening();
                BluetoothDevice device = result.getDevice();
                if (device.getType() != BluetoothDevice.DEVICE_TYPE_LE) {
                    Log.e("Unexpected device type: " + device.getType() + ", address: " + device.getAddress());
                    return;
                }
                SparseArray<byte[]> manufacturerData = result.getScanRecord().getManufacturerSpecificData();
                constructObject(device, manufacturerData);
            }
        }
    }
}

@TargetApi(26)
private class BTScanner {
    private CompanionDeviceManager deviceManager = null;
    private final AssociationRequest pairingRequest = new AssociationRequest.Builder()
            .addDeviceFilter(new BluetoothLeDeviceFilter.Builder()
            .setNamePattern(Pattern.compile(".+")).build()).build(); // change as required

    public void startScanning() {
        if (deviceManager == null) {
            deviceManager = (CompanionDeviceManager) context.getSystemService(Context.COMPANION_DEVICE_SERVICE);
        }
        deviceManager.associate(pairingRequest, new CompanionDeviceManager.Callback() {
            @Override
            public void onDeviceFound(IntentSender chooserLauncher) {
                Log.i("Device(s) found, opening selection dialog");
                try {
                    ((Activity) context).startIntentSenderForResult(chooserLauncher, SELECT_DEVICE_REQUEST_CODE, null, 0, 0, 0);
                } catch (IntentSender.SendIntentException e) {
                    Log.e("BTScanner: " + e.getMessage());
                }
            }

            @Override
            public void onFailure(CharSequence error) {
                Log.e("BTScanner.onFailure() " + error.toString());
            }
        }, null);
    }

    public void stopScanning() {
        if (adapter != null) {
            adapter.cancelDiscovery();
        }
    }
}

Many thanks!  Nice to see it works now.

I can start pairing from Java side but can't see pairing dialog.  No errors reported.  Are some special permissions needed or I need to do something to allow overlay layer with pairing dialog in my app?

GerfesoOVR
Explorer

Question, can we release to the Oculus/Meta store if we just let the user connect to the BLE device via the native BLE Menu in OS and then have our App check to see if any of the connected device match one we are looking for? 

In that way all we need is the Bluetooth_Connect permission and then we don't need Location Services or Scan permission or even to do a scan in App. We wouldn't even need to use the Companion Device manager. 

If got that functioning, would TRULY appreciate if can post the complete Unity scripts (hopefully with an example .ino file for a common BLE MCU, such as ESP32). I tried A LOT of different ways to get BLE communication functioning on Quest with an ESP32. Tried multiple popular bluetooth things on the Unity store also. 

Currently have it functioning on an Android phone. And on the Quest it connects to the ESP32 in the app, but it says it can't find the BLE service. 

And yes, if post a full solution on the Unity store for $10 and it definitely functions, I would be willing to buy that. (I'm not Apple and I've been making this prototype solo)

Thanks in advance!