SDK

Bluetooth Low-Energy Beacons

Bluetooth Low-Energy (BLE) Beacons complement GPS-based geofencing by allowing highly precise, proximity-based experiences — such as detecting when a user enters a store, approaches a product area, or interacts with a specific in-store device.

By enabling beacon detection, the Actito SDK can trigger campaigns, update user profiles, or log proximity events whenever the device detects a configured beacon region. Beacon-based triggers can operate both in the foreground and background, depending on device capabilities and permissions.

To use beacons, include the actito-geo-beacons dependency and request the required permissions as described below.

dependencies {
    def actito_version = 'REPLACE_WITH_LATEST_VERSION'

    implementation "com.actito:actito-geo:$actito_version"
    implementation "com.actito:actito-geo-beacons:$actito_version"
}

Requesting Permissions

Beacon scanning requires additional permissions, particularly on Android 12 (API level 31) and above. To supports beacon detection, request the Bluetooth Scan permission :

class MainActivity : AppCompatActivity() {
    private val bluetoothScanPermissionLauncher = registerForActivityResult(
        ActivityResultContracts.RequestPermission(),
    ) { granted ->
        if (granted) {
            // Permission granted — enable location updates
            enableLocationUpdates()
        } else {
            // Permission denied — handle accordingly
            // You may show a dialog explaining why location updates are useful
        }
    }

    private fun enableLocationUpdates() {
        if (!requestForegroundLocationPermission()) {
            // Permission denied or request performed
            return
        }

        if (!requestBackgroundLocationPermission()) {
            // Permission denied or request performed
            return
        }

        if (!requestBluetoothScanPermission()) {
            // Permission denied or request performed
            return
        }

        Actito.geo().enableLocationUpdates()
    }

    private fun requestBluetoothScanPermission(): Boolean {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return true

        val permission = Manifest.permission.BLUETOOTH_SCAN
        val granted = ContextCompat.checkSelfPermission(
            this,
            permission,
        ) == PackageManager.PERMISSION_GRANTED

        if (granted) return true

        if (shouldShowRequestPermissionRationale(permission)) {
            AlertDialog.Builder(this)
                .setTitle(R.string.app_name)
                .setMessage(R.string.permission_bluetooth_scan_rationale)
                .setCancelable(false)
                .setPositiveButton(R.string.dialog_ok_button) { _, _ ->
                    // Request the permission
                    bluetoothScanPermissionLauncher.launch(permission)
                }
                .setNegativeButton(R.string.dialog_cancel_button) { _, _ ->

                }
                .show()

            return false
        }

        // Request the permission
        bluetoothScanPermissionLauncher.launch(permission)

        return false
    }
}

Automatic Behaviour

Once permissions are granted and location updates are enabled, the Actito SDK automatically manages beacon scanning alongside standard geofencing.

When active, the SDK will:

  • Continuously scan for BLE beacons defined in your Actito dashboard.
  • Trigger campaigns or notifications when entering or exiting beacon regions.

This makes the Beacons module a fully managed extension of the Location Services module — no additional code is required beyond enabling location updates.

Beacon Scanning with a Foreground Service

On Android Oreo (API 26) and higher, background BLE scans are subject to strict system limits. While the first beacon detection occurs quickly, subsequent detections — such as leaving a beacon’s range — may take up to 15 minutes when the app is running in the background. This limitation is imposed by Android itself, and there is no way to bypass it while remaining in background mode.

To improve beacon detection responsiveness, you can opt into foreground scanning, which runs as a foreground service. Foreground services are always active and display a persistent notification to the user.

Enable this feature by adding the following metadata entry to your app’s AndroidManifest.xml:

<meta-data
    android:name="com.actito.geo.beacons.foreground_service_enabled"
    android:value="true" />