I'm new to kotlin/android programming. I am trying to fix program crashing when selecting a device connection type to bluetooth. This only happens in android 12 or newer.
This is a code fragment in kotlin related to bluetooth device connection:
private fun onItemSelected(view: View, printer: PosPrinter) {
var connectionType = printer.connectionType
when (view.id) {
R.id.connectionLayout -> {
val selectedConnection = connectionAdapter.selected?.first ?: ConnectionType.IP
if (selectedConnection != connectionType) {
connectionType = selectedConnection
if (model.triggerConnectivityChange(connectionType))
if (connectionType == ConnectionType.BT) showBtSelectDialog()
else if (connectionType == ConnectionType.USB) showUSBSelectDialog()
}
}
R.id.protocolLayout -> {
val protocol = protocolAdapter.selected?.first ?: PrintProtocol.ELZAB_STX
model.selectedProtocolChange(protocol)
}
}
handleVisibilityElements(connectionType)
}
private fun showBtSelectDialogInternal() {
ListSelectDialog.Builder<IODevice, LayoutSelectItemListBinding>(appActivity)
.apply {
title(R.string.select_bt_device)
applyItemLayout(R.layout.layout_select_item_list)
applyFunction { binding, dialog ->
IODeviceHolder(dialog, binding) {
model.selectedConnectionChange(ConnectionType.BT, it)
handleVisibilityElements(ConnectionType.BT)
}
}
applyList(appActivity.resolveBTDevices().map { IODevice.parse(it) })
headerIcon(R.drawable.ic_bluetooth)
titleColor(Helper.uiModeDialogColors(isDarkMode))
headerIconColor(Helper.uiModeDialogColors(isDarkMode))
dialogBackgroundColor(Helper.uiModeDialogColors(isDarkMode))
tintAll(R.color.iconBlue)
}.create().show(childFragmentManager, null)
}
private fun showBtSelectDialog() {
lifecycleScope.launch {
lifecycle.repeatOnLifecycle(Lifecycle.State.RESUMED){
showProgress()
bluetoothEnabler.launch(BluetoothUtils.turnBluetoothOn())
}
}
}
private val bluetoothEnabler: ActivityResultLauncher<Intent> = forResult {
hideProgress()
if (it.resultCode == Activity.RESULT_OK) showBtSelectDialogInternal()
}
And this is a permission related code in my android manifest file:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation"
android:minSdkVersion="31"
tools:targetApi="s" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"
android:minSdkVersion="31"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="32"
tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
I've tried some other solutions I found on the internet but they didn't worked or I didn't know how to adjust them into this code
It is not enough to declare Bluetooth permissions in the manifest file. Bluetooth permissions are runtime permissions and the application must obtain user consent to use the corresponding Bluetooth feature.
Here is a Stack Overflow answer on how to get these runtime permissions.
And here is the corresponding source code example from the link: