Bluetooth is one of the most essential features in Android applications, especially when developing apps that connect with IoT devices, external hardware, or wireless accessories. However, many developers face an issue where Kotlin Bluetooth not working on some devices even though the same code runs perfectly on other models. This article will guide you through the common causes, troubleshooting steps, and a full Kotlin code example to handle Bluetooth compatibility across different Android devices.
Why Bluetooth May Not Work on Some Devices
When building a Kotlin app with Bluetooth functionality, you may find that your app works smoothly on one smartphone brand but fails on another. The reasons behind this can include:
- Different Android Versions: Some devices may run Android 8 (Oreo), others Android 13 or higher. The Bluetooth API behavior has slightly changed over time.
- Manufacturer Customization: Brands like Samsung, Xiaomi, Oppo, and Vivo sometimes restrict background processes or require additional permissions.
- Permission Issues: From Android 12 onwards, you must request
BLUETOOTH_CONNECTandBLUETOOTH_SCANpermissions. - Hardware Incompatibility: Some devices simply don’t support certain Bluetooth profiles (e.g., BLE, A2DP).
- Battery Optimization: Aggressive power-saving settings can kill Bluetooth scanning in the background.
Step-by-Step Troubleshooting
Follow these steps to fix Bluetooth not working on some Android devices:
- Check Permissions: Always declare the correct permissions in
AndroidManifest.xmldepending on the Android version. - Request Runtime Permissions: For Android 12+, request Bluetooth permissions at runtime.
- Check if Bluetooth is Enabled: Use Kotlin code to verify if Bluetooth is turned on before scanning or connecting.
- Handle Manufacturer Restrictions: Ask users to disable battery optimization for your app if necessary.
- Use Compatible APIs: Ensure you use
BluetoothAdapterandBluetoothLeScannercorrectly.
Full Kotlin Code Example
Here’s a complete Kotlin example that handles Bluetooth initialization, permission requests, and device scanning. This code works for Android 12 and above while remaining backward-compatible.
import android.Manifest
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothManager
import android.bluetooth.le.ScanCallback
import android.bluetooth.le.ScanResult
import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import androidx.core.app.ActivityCompat
class MainActivity : AppCompatActivity() {
private lateinit var bluetoothAdapter: BluetoothAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
bluetoothAdapter = bluetoothManager.adapter
// Check Bluetooth availability
if (bluetoothAdapter == null) {
Log.e("Bluetooth", "Device does not support Bluetooth")
return
}
// Request permissions depending on Android version
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
ActivityCompat.requestPermissions(
this,
arrayOf(
Manifest.permission.BLUETOOTH_SCAN,
Manifest.permission.BLUETOOTH_CONNECT
),
1
)
} else {
ActivityCompat.requestPermissions(
this,
arrayOf(
Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN,
Manifest.permission.ACCESS_FINE_LOCATION
),
1
)
}
// Check if Bluetooth is enabled
if (!bluetoothAdapter.isEnabled) {
Log.e("Bluetooth", "Bluetooth is disabled")
} else {
startScanning()
}
}
private fun startScanning() {
val scanner = bluetoothAdapter.bluetoothLeScanner
scanner?.startScan(scanCallback)
}
private val scanCallback = object : ScanCallback() {
override fun onScanResult(callbackType: Int, result: ScanResult?) {
super.onScanResult(callbackType, result)
result?.device?.let {
Log.i("Bluetooth", "Device found: ${it.name} - ${it.address}")
}
}
override fun onScanFailed(errorCode: Int) {
super.onScanFailed(errorCode)
Log.e("Bluetooth", "Scan failed with error: $errorCode")
}
}
}
Common Fixes for Specific Brands
| Brand | Issue | Solution |
|---|---|---|
| Samsung | Bluetooth scan not running in background | Request user to disable battery optimization |
| Xiaomi / Redmi | Permissions ignored until manually granted | Guide user to Settings → Apps → Permissions |
| Oppo / Vivo | Bluetooth disconnects after screen lock | Enable “Allow background activity” |
| Huawei | Strict battery manager kills scan | Whitelist app in battery settings |
Best Practices
- Always check for runtime permissions.
- Inform users when Bluetooth is required.
- Handle exceptions for devices without BLE support.
- Test on multiple device brands before release.
Conclusion
When facing the issue of Kotlin Bluetooth not working on some devices, the root causes are often related to permissions, Android version differences, and manufacturer customizations. By following the steps above and using the provided Kotlin code example, you can make your Bluetooth implementation more reliable and compatible across different devices.
If you want to explore more about Android Bluetooth development, you can check the official documentation from Android Developers Bluetooth Guide.