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()}");
}
}
Related
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.
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;
}
}
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
I need to detect when wifi is turned on/off. For that purpose I'm using Connectivity by James Montemagno, but the problem is that I don't get an ConnectivityChanged event if the Phone have access to mobile network and I turn on/off the wifi.
Here is the mapping of the event:
CrossConnectivity.Current.ConnectivityChanged += (sender, args) =>
{
WiFiConnected = CrossConnectivity.Current.ConnectionTypes.Contains(ConnectionType.WiFi);
};
So can I detect Connectivity Changed on Wifi? I would like to do it in Xamarin Forms code so I won't have to implement a solution for each platform.
Here What Your Looking For
CrossConnectivity.Current.ConnectivityChanged += (sender, args) =>
{
if (args.IsConnected.ToString().Equals("False"))
{
if (CrossConnectivity.Current.ConnectionTypes.Contains(ConnectionType.WiFi))
{
// WE LOST AN CONNECTION BUT WIFI IS STILL ON
}
}
else
{
if (CrossConnectivity.Current.ConnectionTypes.Contains(ConnectionType.WiFi))
{
// WIFI WAS TURN ON AND WE HAVE A CONNECTION
}
else
{
// WE HAVE A CONNECTION BUT NOT WIFI
}
}
};
I dont know if there is a xamarin forms solution but you can do it plateform specific. In android with BroadcastReceiver.. for other plateforms i have no idea..
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???
}
}
}