Davide Paolillo
Davide Paolillo

Reputation: 43

Does Estimote UWB SDK for Android works with multiple Estimote UWB Beacons?

I'm currently working on an Android application that does indoor wayfinding.

I bought three Estimote UWB beacons and their Android UWB SDK that do not have any documentation whatsoever.

I settled up the main activity to check if the SDK is working correctly, here is the code:

class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
        FindYourWayTheme {
            Surface(
                modifier = Modifier.fillMaxSize(),
                color = MaterialTheme.colorScheme.background
            ) {

            }
        }
    }

    setContentView(R.layout.login)

    val usernameEditText = findViewById<EditText>(R.id.username)
    val passwordEditText = findViewById<EditText>(R.id.password)
    val loginButton = findViewById<Button>(R.id.loginbtn)

    loginButton.setOnClickListener {
        CoroutineScope(Dispatchers.Main).launch {
            val username = usernameEditText.text.toString()
            val password = passwordEditText.text.toString()

            val encryptedUsername = encryptWithPublicKey(username, publicKeyPEM)
            val encryptedPassword = encryptWithPublicKey(password, publicKeyPEM)

           sendSignInCredentialsToLambda(encryptedUsername, encryptedPassword, applicationContext)
        }
    }

    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ||
        ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED ||
        ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED ||
        ContextCompat.checkSelfPermission(this, Manifest.permission.UWB_RANGING) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.BLUETOOTH_CONNECT, Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.UWB_RANGING), 1)
    } else {
        startUWBScanning()
    }
}

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    if (requestCode == 1 && grantResults.all { it == PackageManager.PERMISSION_GRANTED }) {
    } else {
        Log.d("PERMISSIONS", "Some permissions are denied")
    }
}

private fun startUWBScanning() {
    val uwbManager = EstimoteUWBFactory.create()
    val bluetoothAdapter: BluetoothAdapter? = BluetoothAdapter.getDefaultAdapter()
    val deviceAddress = "D8:EB:87:DF:E7:BE"
    val deviceAddress1 = "EC:01:7C:7F:67:50"
    val device: BluetoothDevice? = bluetoothAdapter?.getRemoteDevice(deviceAddress)
    val device1: BluetoothDevice? = bluetoothAdapter?.getRemoteDevice(deviceAddress1)

    uwbManager.init(this, this) { deniedRequirements ->
        deniedRequirements.forEach {
            Log.d("UWBInit", "Requirement denied: $it")
        }
    }
    if (device != null && device1 != null) {
        launchUWBConnection(uwbManager, device)
        launchUWBConnection(uwbManager, device1)
    } else {
        Log.d("NotFoundBT", "DUCK OFF")
    }
    uwbManager.stopDeviceScanning()
}

fun launchUWBConnection(uwbManager: EstimoteUWBManager, device: BluetoothDevice) {
    CoroutineScope(Dispatchers.Main.immediate).launch {
        uwbManager.connect(device, applicationContext)
        uwbManager.startDeviceScanning(applicationContext)
        uwbManager.rangingResult.collect { result ->
            when (result) {
                is EstimoteUWBRangingResult.Position -> {
                    val position = result.position

                    // Extract position information
                    val positionInfo =
                        "Position of ${result.device.address} : Distance=${position.distance?.value}, Azimuth=${position.azimuth?.value}, Elevation=${position.elevation?.value}"

                    // Log or print the information
                    Log.d("UWBResult", positionInfo)
                }

                else -> {
                    // Handle other types of EstimoteUWBRangingResult
                }
            }
        }
    }
}

fun onRegisterClick(view: View) {
    val intent = Intent(this, SignUpActivity::class.java)
    startActivity(intent)
}
}

Now, the issue is that when I try to connect to one device the position (and all the data) looks fine, this is a sample log:

Position of 7B:ED : Distance=0.14999998, Azimuth=null, Elevation=null

Though, when I try to connect a second UWB beacon I receive this error message:

Creating Gms Client session scope

Error when removing Please check that the ranging is active and theranging profile supports multi-device ranging.

RangingResultPeerDisconnected address:20:00

I don't know if there's an issue with my code, or maybe with the SDK itself. Also I could not find any reference in the android uwb library documentation, that says if an android phone (in my case a Pixel 7 Pro) can connect to multiple devices via UWB.

Upvotes: 0

Views: 313

Answers (2)

estimote
estimote

Reputation: 21

Estimote Team here,

documentation for Estimote UWB Beacons and Android SDK is available on our GitHub here: https://github.com/Estimote/Android-Estimote-UWB-SDK

At the moment (April 2024) it is not possible to range with multiple UWB beacons at the same time on Android. We do support that on iOS.

However per our SDK documentation on GitHub there are uwbManager.connect() and uwbManager.disconnectDevice() methods available.

So in order to implement obtaining distance from multiple beacons one should:

  • connect to beacon A
  • obtain distance from beacon A
  • disconnect from beacon A
  • connect to beacon B
  • etc

The connect/disconnect time should not take more than seconds, so it should be possible to put together a simple indoor positioning using UWB beacons.

Upvotes: 0

Davide Paolillo
Davide Paolillo

Reputation: 43

Estimote does not provide any support more than a basic SDK, without any documentation.

After some months their support team answered that there was no official support for multiple beacons in Android, becoming a useless product both for iOS (which already has AirTag) and Android.

Upvotes: 0

Related Questions