Xamarin Forms Bluetooth LE not showing nearby discoverable devices - c#

I am making an app that utilizes bluetooth function such as scanning devices etc. I checked the scan flag and returns true but not showing the discoverable device that I am testing.
I am using Samsung J7 Pro as my app test device and Samsung J7 as the device I want to see in the list of discovered devices.
J7 already set as discoverable and with bluetooth ON.
I based my codes in Monkey.BluetoothLE
Here is what I have:
Declarations
ObservableCollection<BluetoothViewModel> vm = new ObservableCollection<BluetoothViewModel>();
Android.Bluetooth.BluetoothManager _blManager;
Android.Bluetooth.BluetoothManager _blManager;
Robotics.Mobile.Core.Bluetooth.LE.Adapter _bleAdapter;
Functions
public BluetoothPage()
{
InitializeComponent();
lvInfo.ItemsSource = vm;
var appContext = Android.App.Application.Context;
_blManager = (Android.Bluetooth.BluetoothManager)appContext.GetSystemService("bluetooth");
_blAdapter = _blManager.Adapter;
_bleAdapter = new Robotics.Mobile.Core.Bluetooth.LE.Adapter();
_bleAdapter.DeviceDiscovered += _bleAdapter_DeviceDiscovered;
_bleAdapter.ScanTimeoutElapsed += _bleAdapter_ScanTimeoutElapsed;
}
private void btnScanStopBluetooth_Click(object sender, EventArgs e)
{
if (!_bleAdapter.IsScanning)
{
if (!_blAdapter.IsEnabled)
{
_blAdapter.Enable();
DisplayInformation("Turning on bluetooth...");
while (!_blAdapter.IsEnabled)
{
//do nothing until enabled
}
}
vm.Clear();
btnScan.Text = "Stop Scan";
_bleAdapter.StartScanningForDevices();
}
else
{
btnScan.Text = "Start Scan";
_bleAdapter.StopScanningForDevices();
}
}
private void _bleAdapter_DeviceDiscovered(object sender, Robotics.Mobile.Core.Bluetooth.LE.DeviceDiscoveredEventArgs e)
{
count++;
vm.Add(new BluetoothViewModel
{
Name = e.Device.Name,
ID = e.Device.ID.ToString(),
RSSI = e.Device.Rssi.ToString()
});
}
private void _bleAdapter_ScanTimeoutElapsed(object sender, EventArgs e)
{
DisplayInformation("Scan Timeout");
_bleAdapter.StopScanningForDevices();
btnScan.Text = "Start Scan";
}
private void DisplayInformation(string line)
{
lblStatus.Text = line;
}
A listview is bound to "vm" that will display the discovered device.
It does not show anything, and count is always zero but I checked the scan flag using _bleAdapter.IsScanning, it returns true.
EDIT:
I tried other open-source sample programs for Bluetooth such as
xamarin-bluetooth-le (BLE Explorer)
Bluetooth-Xamarin.Forms (DemoBluetooth)
None of them seem to list the device. When I use my built-in bluetooth app under settings, it lists the device. What am I missing here?

Have you granted permission for bluetooth and location?
You have to grant permission in the Manifest/or Settings and depending on the sdk (23+) also asking the user for extra permission.
https://learn.microsoft.com/en-us/xamarin/android/app-fundamentals/permissions?tabs=windows

Related

EventHandler to get HDMI connectivity in windows application

I am looking for event handler to get the information when HDMI is connected or disconnected using c#/WPF like how myNetworkAvailabilityChangeHandler is used to detect when internet gots disconnected or connected.
There is no direct answer to this but you can use the SystemEvents to achieve this.
Code in C# :
main()
{
SystemEvents.DisplaySettingsChanged += new
EventHandler(SystemEvents_DisplaySettingsChanged);
}
private void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e)
{
int HDMI_Monitors = 0;
ManagementClass mClass = new ManagementClass(#"\\localhost\ROOT\WMI:WmiMonitorConnectionParams");
foreach (ManagementObject mObject in mClass.GetInstances())
{
var ss = mObject["VideoOutputTechnology"];
if(ss.ToString().StartsWith("5"))
{
int HDMIport = Convert.ToInt32(ss);
if (HDMIport == 5)
{
HDMI_Monitors += 1;
}
}
}
}
You can use the model class to keep on updating the HDMI status.
So every time your HDMI will connect or disconnect SystemEvents_DisplaySettingsChanged will trigger and then it will check the HDMI connection.

how to make sure that function only fires once (RawInputEventArg)

I'm currently working on a method that gives the user the possibility to add a handscanner to a dicitionary in order to scan some barcodes with it. (before i started the scanners were hardcoded in the dictionary). my colleague from which i got this project, implemented the rawinput_dll in order to get all of the necessary data from the barcode scanner. The method to get the data is shown below:
private void OnKeyPressed(object sender, RawInputEventArg e)
{
if (!Scanners.ContainsKey(e.KeyPressEvent.DeviceName))
{
return;
}
else if (Scanners.ContainsKey(e.KeyPressEvent.DeviceName))
{
if (e.KeyPressEvent.KeyPressState == "MAKE")
{
return;
}
if (e.KeyPressEvent.VKeyName != "\n")
{
scanNumber += e.KeyPressEvent.VKeyName;
return;
}
devID = e.KeyPressEvent.DeviceName;
Debug.Print(devID);
Aufrufen(scanNumber);
scanNumber = "";
}
}
Basically there are three classes in this program (FrmMenu, FrmSettings and a Class for the Scanner itself). If you want to add settings for the program you click on a button that opens up a new instance of FrmSettings
private void BtnSettings_Click(object sender, EventArgs e)
{
FrmSettings settings = new FrmSettings();
settings.ShowDialog();
settings.BtnSave_Click(sender, e);
settings.Dispose();
}
In this form there 2 buttons where you can choose if you want to add a scanner that scans even numbers or one that scans odd ones. If you press one of the buttons you need to scan a barcode in order to get the information (VID of Scanner) which is used as key to add the new scanner to the dictionary.
private void OnKeyPressed(object sender, RawInputEventArg e)
{
if (newScanner == true)
{
devIDnew = e.KeyPressEvent.DeviceName;
scannerAnlegen(devIDnew);
}
}
scannerAnlegen is the methode that adds the scanner to the dict.
public void scannerAnlegen(string devIDnew)
{
if(EvenOrOdd == true)
{
Scanner ger = new Scanner("dev3", "even");
FrmMenu.Scanners.Add(devIDnew, ger);
newScanner = false;
}
else
{
Scanner ug = new Scanner("dev4", "odd");
FrmMenu.Scanners.Add(devIDnew, ug);
newScanner = false;
}
}
my problem rn is, that it seems like i cant get out of this OneKeyPressed method of the Settings class. the logic of the OneKeyPressed method of the FrmMenu Class is that it can only proceed if the scanner is in the dictionary. Adding the scanner seems to work because when i debug and try to add one scanner the second time it throws and exception and says something like "element with this key already added". But why does this code doesn't continue then?

Bluetooth Radio.StateChanged Event fires twice

I want to listen when bluetooth radio turn on or turn off.
For this i simply got the default radio and subscribed to StateChanged.
var bluetoothAdapter = await BluetoothAdapter.GetDefaultAsync();
var radio = await bluetoothAdapter.GetRadioAsync();
radio.StateChanged += Radio_StateChanged;
private void Radio_StateChanged(Windows.Devices.Radios.Radio sender, object args)
{
Console.WriteLine(String.Format("Radio state changed {0} {1}", sender.Kind, sender.Name));
}
When i change bluetooth state via Windows Bluetooth settings i got StateChanged event fires twice.
Output:
Radio state changed Bluetooth Bluetooth
Radio state changed Bluetooth Bluetooth
I have the module with Bluetooth and Wifi together. I thought maybe it is cause. Then i get all radios Radio.GetRadiosAsync
radios = await Radio.GetRadiosAsync();
foreach (var r in radios)
{
r.StateChanged += Radio_StateChanged;
}
Output:
Radio state changed Bluetooth Bluetooth
Radio state changed Bluetooth Bluetooth
Radio state changed WiFi Wi-Fi
Radio state changed WiFi Wi-Fi
is this the expected behavior?
Update. I added state value to output
Output:
Radio state changed Bluetooth Bluetooth Off
Radio state changed Bluetooth Bluetooth Off
This is probably a bug of Radio.StateChanged API. I have also faced the same problem. You can minimize the problem by checking the Radio State like bellow :
public Radio BluetoothAdapter { get; set; }
public RadioState OldBluetoothState;
public RadioState NewBluetoothState;
IReadOnlyList<Radio> radios = await Radio.GetRadiosAsync();
BluetoothAdapter = radios.FirstOrDefault(radio => radio.Kind == RadioKind.Bluetooth);
if (BluetoothAdapter != null)
{
OldBluetoothState = BluetoothAdapter.State;
BluetoothAdapter.StateChanged += RadioBluetoothAdapter_StateChanged;
}
private void RadioBluetoothAdapter_StateChanged(Radio sender, object args)
{
try
{
NewBluetoothState = sender.State;
if (NewBluetoothState != OldBluetoothState)
{
OldBluetoothState = NewBluetoothState;
if (sender.State == RadioState.Off)
{
//Application logic will goes here.
Debug.WriteLine("Bluetooth has been turned off.");
}
else
{
//Application logic will goes here.
Debug.WriteLine("Bluetooth has been turned on.");
}
}
}
catch (Exception ex)
{
Debug.WriteLine($"Exception has been occured: {ex.Message.ToString()}");
}
}

C# - Force windows around 20s delay to realize bluetooth not connected

I'm currently using the 32feet library for bluetooth in my application. I'm trying to check whether the device is still alive before it takes windows the 20s to change the status from "Connected" --> "Paired".
"True" --> "False"
I'm forcing a device refresh with:
holders.storedDevice.Refresh();
but it seems that the refresh isn't actually forcing windows to do anything. For reference storedDevice is of type
BluetoothDeviceInfo name {get; set;}
Timer code:
private void refreshDevice(object Sender, EventArgs e)
{
holders.StoredDevice.Refresh();
if(!holders.StoredDevice.Connected)
{
deviceRefreshTimer.Enabled = false;
updateTextBox( connectButton ,"Disconnecting...");
ExecuteSecure(() => connectButton.Enabled = false);
updateTextBox(statusTextBox, "Lost connection");
readBackgroundWorker.CancelAsync();
holders.localClient.Close();
storedStream = null;
}
}

C# Detect button press on bluetooth device in Windows Phone Project

I have a Bluetooth stylus device. It has three buttons on it: power/call, volume up, volume down. In a C# project running on my windows phone paired with the stylus, how can I detect when one of those buttons is pressed?
Note: I already can see the device in code:
BluetoothDevice currentDevice { get; set; }
string deviceName = "P1";
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
foreach (DeviceInformation di in await DeviceInformation.FindAllAsync(BluetoothDevice.GetDeviceSelector()))
{
BluetoothDevice bdDevice = await BluetoothDevice.FromIdAsync(di.Id);
if (bdDevice.Name == deviceName)
{
currentDevice = bdDevice;
//OK, so now what do I do to listen for the button clicks???
}
}
}

Categories

Resources