Bluetooth no longer works on API 12,13 and probably 14. I'm having difficulties

runs in the procedure right after the first successful connection.

ChrisWard, I'm already using Anke's extension.

ABG, the the procedure procIsBlueToothEnabled is here.
image

image

Ewpatton, AddressesAndNames are used when clicking the scan button, to be able to locate the device's MAC.

image

I'm having misgivings about the use of a Spinner for the device list:
image

Typically, the first Element of a Spinner is just a heading for the other Elements.

These are the places where that Spinner is used:

Notably missing from that list is the event that catches a user act of selecting a particular Element (I inserted this one to show you what one looks like)

Instead, the Selection might be determined by a Clock Timer timing out:


but I see nothing to suggest that.

So I suspect your user might have missed his cue to select a device, and allowed the header of the spinner to be saved as the MAC address.

1 Like

Thank you for your effort in helping me, I have only received these reports from Android 12 and 13 users. Previous versions do not present this problem. If I had some money left over I would buy a new cell phone just to test it and try to resolve it, but at the moment it's not possible. Can I test this with an emulator?

Or suggest another approach for the bluetooth device list? I've used the list view in the past, but I didn't like it because I couldn't hide the other paired devices on the device. But I'm also unsure if the problem will persist.

You could add another list and ListView, with the user's Favorite devices, and offer ways to mark devices as Favorite or not.

1 Like

So I think this is the potential problem here, for a couple reasons.

First, it would be better to set the Elements property before calling the function to show the dropdown.

Second, you should check whether the AddressesAndNames property is an empty list. With Android 12 and later, this block will raise the PermissionDenied event on Screen1 if the right permissions aren't granted, which you can then use to prompt the user for permission. In a future update, this should happen automatically without the need to implement the PermissionDenied event logic.

Note that the if statement may be redundant since the setting of the elements will stop the execution if the permissions aren't granted.

2 Likes

.......For the apiLevel, instead of the procedure you are using.

1 Like

Why not use a ListPicker instead? That is just a button on the Screen, clicked it presents a list, you can set the text of the button to the the selected address - it is a good reliable solution.

1 Like

It would have to be an emulator on a device that has Bluetooth and the emulator supporting Bluetooth. I think ABG is right, using a spinner for the device list is going to cause a User error, even if it is not the error.

1 Like

Forcing the user to have completed a device Selection in the past is also a requirement

1 Like

Thanks you for the explanation.

The Addresses and Names value block 's existence hints at some background process that must have run to gather all those Addresses and Names prior to its evaluation.

Either that, or the value block must be stopping the app dead in its tracks for some unknown length of time while it searches the BlueTooth airwaves to gather MAC addresses and names.

I vaguely remember seeing a Clock Timer loop sample for the process of refreshing a ListView of Addresses and Names from the repeated evaluation of this value block, some time in the distant past.

1 Like

In classic Bluetooth, as far as Android was (is?) concerned, the pairing of devices happens via the settings app, so when the block queries the list it is known at runtime and the response was synchronous, which is why the block was designed the way it was and it's been that way since it came to us from Google. This is juxtaposed against BluetoothLE which has a formal scan process that apps must initiate, so that extension is designed with a method-event block pair.

I guess you could do this, but unless the person is moving through space or the devices are turning on and off around them the list of available devices will be relatively static. In the case where we also have to ask for permission, it might run the risk of asking multiple times if the clock timer is too short for the initial permission flow to complete.

2 Likes

Note that you may want to try compiling your app on ai2-test.appinventor.mit.edu, which contains the fix I mentioned earlier around the permission request behavior in BluetoothClient:

1 Like

Nice to know.

Now we have an extra question to ask any one complaining that their device list is empty:

"Did you pair any devices to your phone in the Settings app yet?"

1 Like

I have no idea what we're talking about here. What's the problem if I do it the way I've been suggesting for months? And at least according to my tests, this is independent of whether devices are paired or not.

1 Like

Yes, your method is the way to go

No, see rhe documentation Connectivity

AddressesAndNames
Returns the list of paired Bluetooth devices. Each element of the returned list is a String consisting of the device’s address, a space, and the device’s name. On Android 12 or later, if the permissions BLUETOOTH_CONNECT and BLUETOOTH_SCAN have not been granted to the app, the block will raise an error via the Screen’s PermissionDenied event.

Taifun

1 Like

Correct, I had unpaired a device and could still see it in the list after restarting the app. Apparently a problem/error during updating.

But I still don't understand what this is really about.

1 Like

In case anyone is interested in a deeper technical understanding, the AddressesAndNames block calls through to the BluetoothAdapter's getBondedDevices() method, the documentation for which states:

Return the set of BluetoothDevice objects that are bonded (paired) to the local adapter.

If the list contains unpaired devices, that sounds like a bug in the Bluetooth stack implementation by the device manufacturer.

There is the filter family of blocks that have been added somewhat recently that may be helpful here. You could filter the list returned by AddressesAndNames to only match whatever criteria you choose. For example, for micro:bit (using BluetoothLE), I've filtered just for devices with micro:bit in the name. If micro:bit worked over Classic Bluetooth, then the hypothetical blocks might look something like:

Of course, you could substitute in any component that renders a list of elements instead of the spinner.

2 Likes