I am using Geoposition and a Postition changed event to grab Coordinates of the device location.
private async void StartGpsMonitoring()
{
if (locator == null)
{
locator = new Geolocator();
}
if (locator.LocationStatus == PositionStatus.Disabled)
{
//throw new Exception();
MessageDialog noGpsDialog = new MessageDialog("Location services are disabled, please enable location services");
noGpsDialog.Commands.Add(new UICommand("Location Settings", new UICommandInvokedHandler(this.CommandInvokedHandler), 0));
noGpsDialog.Commands.Add(new UICommand("Cancel", new UICommandInvokedHandler(this.CommandInvokedHandler), 1));
await noGpsDialog.ShowAsync();
}
if (locator != null)
{
//locator.MovementThreshold = 3;
locator.ReportInterval = 1;
locator.DesiredAccuracy = PositionAccuracy.High;
locator.PositionChanged +=
new TypedEventHandler<Geolocator,
PositionChangedEventArgs>(locator_PositionChanged);
}
}
private async void locator_PositionChanged(Geolocator sender, PositionChangedEventArgs e)
{
string speed = string.Empty;
await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
Geoposition geoPosition = e.Position;
if (e.Position.Coordinate.Speed != null)
{
speed = e.Position.Coordinate.Speed.Value.ToString(); // always 5.8
}
geolocation = geoPosition.Coordinate.Point.Position.Latitude.ToString() + " " +
geoPosition.Coordinate.Point.Position.Longitude.ToString() + "Speed = " +
speed;
var textBlockStatus =
ControlHelper.FindChildControl<TextBlock>(JourneyTrackerSection, "TextBlockStatus") as TextBlock;
textBlockStatus.Text = geolocation;
});
}
I am also trying to get the speed value. But when using the emulator I am always getting 5.8 regardless of if I have speed limit/walking/biking set on the emulator, and still get 5.8 from a static position.
Can anybody shed some light as to why? Is it just the emulator? Would I get an accurate result if I used a real device?
Its hard to develop a location speed application where I have to run out side every time I want to debug/run it.
Any help much appreciated.
Thought I would post some details as to what I have managed to find out in case anyone comes across this in the future. Looks like this is because it is running on the emulator. Managed to come across some limited details about using the geopositioning code and some details about it being hardware specific. After I have managed to get hold of a windows phone for testing the emulator cannot do the speed. Works perfect on an actual device.
This is extremely annoying by Microsoft. means that every time I need to test my app I have to go out driving. Rendering the GPS emulator completely useless!
Related
I'm developing a c# desktop api with forms where I want to receive ACC data from a BLE server und display them in a chart.
So I'm running in a connection problem and I can't find any solution.
I can find my LE server Device with the watcher.
DevicePairingResult dpr = await device.DeviceInformation.Pairing.PairAsync(DevicePairingProtectionLevel.Encryption);
returns me "AlreadyPaired"
But when I do
device = await BluetoothLEDevice.FromBluetoothAddressAsync(bluetoothAddress: eventArgs.BluetoothAddress);
mGattService = device.GetGattService(MotionService_GUID);
mCharacteristic = mGattService.GetCharacteristics(ACC_Characteristic_GUID)[0];
and then
var con = device.ConnectionStatus;
I receive "Disconnected" in con.
I am bound with de device on windows( I searched for it in Windows and entered the Code) but I am not connected(based on the Status in the windows info center).
I've read in another Thread in the windows c# developer page that it should not be necessary anymore to pair the device manually.
I'm pretty shure that the rest of my code works because sometimes I can get a connection( pretty confusing for me) and see the right Data in my chart.
Right now I just want to reach a stable connection before changing other part of my code.
Anyone any idea how to solve this?
Thx medTech
Edit:
Here is part of the Code:
Scanning for BLE
private void button1_Click(object sender, EventArgs e)
{
// Create Bluetooth Listener
var watcher = new BluetoothLEAdvertisementWatcher();
watcher.ScanningMode = BluetoothLEScanningMode.Active;
// Register callback for when we see an advertisements
watcher.Received += OnAdvertisementReceivedAsync;
// Wait 5 seconds to make sure the device is really out of range
watcher.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMilliseconds(5000);
watcher.SignalStrengthFilter.SamplingInterval = TimeSpan.FromMilliseconds(2000);
// Starting watching for advertisements
watcher.Start();
}
Connect to Server:
private async void OnAdvertisementReceivedAsync(BluetoothLEAdvertisementWatcher watcher, BluetoothLEAdvertisementReceivedEventArgs eventArgs)
{
// Filter for specific Device
if (eventArgs.Advertisement.LocalName == "MYDEVICE")
{
watcher.Stop();
var MotionService_GUID = new Guid("00002000-0000-1000-8000-00805F9B34FB");
var ACC_Characteristic_GUID = new Guid("00002001-0000-1000-8000-00805F9B34FB");
device = await BluetoothLEDevice.FromBluetoothAddressAsync(bluetoothAddress: eventArgs.BluetoothAddress);
DevicePairingResult dpr = await device.DeviceInformation.Pairing.PairAsync(DevicePairingProtectionLevel.Encryption);
mGattService = device.GetGattService(MotionService_GUID);
mCharacteristic = mGattService.GetCharacteristics(ACC_Characteristic_GUID)[0];
GattDeviceServicesResult result = await device.GetGattServicesAsync();
GattCommunicationStatus status1 = await ReadFromCharacteristicAsync(mCharacteristic);
var con = device.ConnectionStatus;
while (status1 == GattCommunicationStatus.Success)
{
try
{
status1 = await ReadFromCharacteristicAsync(mCharacteristic);
}
catch
{
Console.WriteLine("ERROR");
status1 = GattCommunicationStatus.Unreachable;
}
}
}
}
Read from Characteristic:
async Task ReadFromCharacteristicAsync(GattCharacteristic mCharacteristic)
{
GattReadResult readResult = await mCharacteristic.ReadValueAsync(BluetoothCacheMode.Uncached);
if (readResult.Status == GattCommunicationStatus.Success)
{
byte[] data = new byte[readResult.Value.Length];
DataReader.FromBuffer(readResult.Value).ReadBytes(data);
if (chart1.IsHandleCreated)
{
this.Invoke((MethodInvoker)delegate { updateChart(data); });
}
return readResult.Status;
}
return readResult.Status;
}
Terminate Connection
private async Task<bool> ClearBluetoothLEDeviceAsync()
{
mCharacteristic.Service.Dispose();
mGattService.Dispose();
await device.DeviceInformation.Pairing.UnpairAsync();
device?.Dispose();
device = null;
GC.Collect();
return true;
}
SO now when I connect the first time to the Server, I only receive zeros which shows me that the there might be a authentication Error.
After that I always receive this Error:
"System.ArgumentException" in mscorlib.dll with a notification that there is noch executable Code left because all Threads are doing some asynchronous stuff.
This Error gets thrown when I try to read from the Characteristic.
I never coded in c# before so I am not shure if there is an error in my asynchronous part oder the communication part.
Thanks you
Pairing is not the same as connecting!
I really advise using the BLE-advertisementWatcher to select and connect to your device.
The reason is that many BLE-devices don't save their pairing status.
In windows device-watcher once paired, the device stays paired even if it is switched off or out of reach.
Also many times the connection status is kept, unless the device is unpaired and disposed in code or removed in windows settings.
All BLE-devices that I know of start advertising as soon as there is no connection for some time.
This time depends on the device, but most of the time within seconds.
So don't pair but just connect if the device is advertising.
In the way of learning BLE programming using C#, I'm trying to write a winform application that should detec BLE devices and use them as proximity sensors. For this purpose I've applied the BluetoothAdvertisementWatcher class, filtering the advertisements with a provided signal strength. The problem is the detection seems to be quite crappy... Even with the device at no distance from my PC, the listener often returns a RSSI value of -127, wich stands for "no detection" as I've understood. I've tried setting the OutOfRangeTimeout to 10 seconds and, even if things get better, problems are still heavy. The major issue is the detection can flows without interruption just for about a bunch of seconds, then the debugger signals me a thread exiting with code 0, and the listener can't receive new advertisements (with the device ever aside the pc) for even 30-40 seconds, then it restarts and so it loops.
Do you know if is this how it is intended to work or if am I missing something? Is there a way, eventually, to intercept this interruption and immediately restart the listener?
This is how I initialize the watcher:
public BLEScanner(short maxDBRange, TimeSpan outOfRangeTimeout) {
this.InRange = maxDBRange;
this.OutOfRange = (short)(this.InRange + BLEScanner.BUFFER_RANGE);
this.OutOfRangeTimeout = outOfRangeTimeout;
this.watcher = new BluetoothLEAdvertisementWatcher();
this.watcher.SignalStrengthFilter.InRangeThresholdInDBm = this.InRange;
this.watcher.SignalStrengthFilter.OutOfRangeThresholdInDBm = this.OutOfRange;
this.watcher.SignalStrengthFilter.OutOfRangeTimeout = this.OutOfRangeTimeout;
this.watcher.SignalStrengthFilter.SamplingInterval = TimeSpan.FromSeconds(1);
this.watcher.ScanningMode = BluetoothLEScanningMode.Active;
}
While this is the event handler:
private async void OnAdvertisementReceived(BluetoothLEAdvertisementWatcher watcher, BluetoothLEAdvertisementReceivedEventArgs eventArgs) {
var deviceAddress = eventArgs.BluetoothAddress;
BluetoothLEDevice device = await BluetoothLEDevice.FromBluetoothAddressAsync(deviceAddress);
UpdateUiDelegate update = new UpdateUiDelegate(
(dev, args) => {
if (eventArgs.RawSignalStrengthInDBm == -127) {
this.form.spyLabel.BackColor = System.Drawing.Color.Red;
this.form.nameLabel.Text = "(none)";
this.form.addressLabel.Text = "(none)";
this.form.rssiLabel.Text = "(none)";
this.form.connectedLabel.Text = device.ConnectionStatus.ToString();
} else {
this.form.spyLabel.BackColor = System.Drawing.Color.Green;
this.form.nameLabel.Text = device.Name;
this.form.addressLabel.Text = device.BluetoothAddress.ToString();
this.form.rssiLabel.Text = eventArgs.RawSignalStrengthInDBm.ToString();
this.form.connectedLabel.Text = device.ConnectionStatus.ToString();
}
});
this.form.Invoke(update, device, eventArgs);
Console.Write(eventArgs.RawSignalStrengthInDBm + " ");
}
Any help is appreciated!
I am trying to showToast when the phone leaves or enter the geofenced location (which is set elsewhere and passed in). The issue is that when the app is in the background the trigger does not occur and I don't see the showToast message. I am changing the location manually using an emulator on my PC.
Background Tasks> Location is set under the app manifest.
This is the code I am using to build the Geofence and backgroundtask
//Creates Geofence and names it "PetsnikkerVacationFence"
public static async Task SetupGeofence(double lat, double lon)
{
await RegisterBackgroundTasks();
if (IsTaskRegistered())
{
BasicGeoposition position = new BasicGeoposition();
position.Latitude = lat;
position.Longitude = lon;
double radius = 8046.72; //5 miles in meters
Geocircle geocircle = new Geocircle(position, radius);
MonitoredGeofenceStates monitoredStates = MonitoredGeofenceStates.Entered | MonitoredGeofenceStates.Exited;
Geofence geofence = new Geofence("PetsnikkerVacationFence", geocircle, monitoredStates, false);
GeofenceMonitor monitor = GeofenceMonitor.Current;
var existingFence = monitor.Geofences.SingleOrDefault(f => f.Id == "PetsnikkerVacationFence");
if (existingFence != null)
monitor.Geofences.Remove(existingFence);
monitor.Geofences.Add(geofence);
}
}
//Registers the background task with a LocationTrigger
static async Task RegisterBackgroundTasks()
{
var access = await BackgroundExecutionManager.RequestAccessAsync();
if (access == BackgroundAccessStatus.Denied)
{
}
else
{
var taskBuilder = new BackgroundTaskBuilder();
taskBuilder.Name = "PetsnikkerVacationFence";
taskBuilder.AddCondition(new SystemCondition(SystemConditionType.InternetAvailable));
taskBuilder.SetTrigger(new LocationTrigger(LocationTriggerType.Geofence));
taskBuilder.TaskEntryPoint = typeof(Petsnikker.Windows.Background.GeofenceTask).FullName;
var registration = taskBuilder.Register();
registration.Completed += (sender, e) =>
{
try
{
e.CheckResult();
}
catch (Exception error)
{
Debug.WriteLine(error);
}
};
}
}
static bool IsTaskRegistered()
{
var Registered = false;
var entry = BackgroundTaskRegistration.AllTasks.FirstOrDefault(keyval => keyval.Value.Name == "PetsnikkerVacationFence");
if (entry.Value != null)
Registered = true;
return Registered;
}
}
}
This code is where I monitor the state of the geofence.
This is where the Entry point in the appxmanifest is pointing
public sealed class GeofenceTask : IBackgroundTask
{
public void Run(IBackgroundTaskInstance taskInstance)
{
var monitor = GeofenceMonitor.Current;
if (monitor.Geofences.Any())
{
var reports = monitor.ReadReports();
foreach (var report in reports)
{
switch (report.NewState)
{
case GeofenceState.Entered:
{
ShowToast("Approaching Home",":-)");
break;
}
case GeofenceState.Exited:
{
ShowToast("Leaving Home", ":-)");
break;
}
}
}
}
//deferral.Complete();
}
private static void ShowToast(string firstLine, string secondLine)
{
var toastXmlContent =
ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText02);
var txtNodes = toastXmlContent.GetElementsByTagName("text");
txtNodes[0].AppendChild(toastXmlContent.CreateTextNode(firstLine));
txtNodes[1].AppendChild(toastXmlContent.CreateTextNode(secondLine));
var toast = new ToastNotification(toastXmlContent);
var toastNotifier = ToastNotificationManager.CreateToastNotifier();
toastNotifier.Show(toast);
Debug.WriteLine("Toast: {0} {1}", firstLine, secondLine);
}
}
After looking at your code, it seems that your code is correct.
In order to fire the Geofence Backgroundtask to show the toast information, please make sure the following things:
1) Please make sure that you have done all the necessary configuration in the Package.appxmanifest for registering the BackgroundTask, for example you have set the correct EntryPoint and added the “Location” capabilities.
For the detailed information, you can try to compare your Package.appxmanifest with the official sample Geolocation’s Package.appxmanifest.
Please also check: Create and register a background task and Declare background tasks in the application manifest.
2) Please make sure that you know how to set the location in the Emulator manually for simulating the phone leave or enter the geofenced location. For more information about how to set location in the emulator, please check the following article:
https://msdn.microsoft.com/library/windows/apps/dn629629.aspx#location_and_driving .
3) Please make sure that your second position in your emulator is not really far away from the geofences that you have defined in the first time, because the emulator behaves like a real device, and the device doesn’t expect to suddenly move from New York to Seattle. Or the BackgroundTask will not be fire immediately.
4) Background tasks for geofencing cannot launch more frequently than every 2 minutes. If you test geofences in the background, the emulator is capable of automatically starting background tasks. But for the next subsequent background tasks, you need to wait for more than 2 minutes.
Besides, I will recommend you refer to the following article about how to use the Windows Phone Emulator for testing apps with geofencing:
https://blogs.windows.com/buildingapps/2014/05/28/using-the-windows-phone-emulator-for-testing-apps-with-geofencing/ .
Thanks.
Geolocator seems to simply not work on WP8 when it should. (But for some strange reason works perfectly fine on 8.1)... I'm in optimal conditions - LTE, FiOS Wifi... No obstructions. No reason why it shouldn't work. However, it seems to just hang and never return the current location or even an exeption.
I have tried to disable the reverse geocode and it does not work. I've narrowed it down to being the actual service that gets the location (Geolocator or GeoPosition)
ID_CAP_LOCATION is enabled. Phone location services are enabled. I'm targeting WP8.
Code:
private async void getlocation()
{
try
{
Geolocator gl = new Geolocator(); gl.DesiredAccuracyInMeters = 50;
Geoposition geoposition = await gl.GetGeopositionAsync(maximumAge: TimeSpan.FromMinutes(5), timeout: TimeSpan.FromSeconds(60));
latitude = geoposition.Coordinate.Latitude.ToString(); longitude = geoposition.Coordinate.Longitude.ToString();
//Location to physical address
List<MapLocation> locations;
ReverseGeocodeQuery query = new ReverseGeocodeQuery();
query.GeoCoordinate = new GeoCoordinate(geoposition.Coordinate.Latitude, geoposition.Coordinate.Longitude);
//Set address to tecxtblock
query.QueryCompleted += (s, e) =>
{
locations = e.Result as List<MapLocation>;
address = locations[0].Information.Address.City.ToString();
ts.Center = new GeoCoordinate(geoposition.Coordinate.Latitude, geoposition.Coordinate.Longitude);
ts.ZoomLevel = 7;
location.Text = address.ToUpper(); //Location
//Successful, now get weather for current location
getforecast();
};
query.QueryAsync();
}
catch
{
MessageBox.Show("Location services appear to be turned off. To use Atmosphere, turn location services on.");
}
}
I've encountered issues on WP8 with background tracking where it would only update the the position when the app was bought to the foreground. Very confusing as I knew it was working on other devices without issue.
In the end I simply un-installed the app completely and re-installed, this solved the issue. Just in case you haven't tried it - just completely remove the app and re-install / re-deploy using Visual Studio. Issue might resolve itself.
I had the same problem. The same code works in 8.1 but does not in 8.0
I was able to make it work when i called the function from a button click instead of the constructor of the Page or in Page_loaded event.
I have an problem with muting the mic on an windows 7 machine. But all the code i have found dosen't run ore it's not doing anything the runned. Have is it done for an Windows 7 machine using C# code. I just need an on/off solution.
The DDL file works also with Win x64bit. But i thing that i creates an error another place.
mixers.Recording.Lines.GetMixerFirstLineByComponentType(
MIXERLINE_COMPONENTTYPE.SRC_MICROPHONE).Volume = 0;
if (!mediaElement1.CheckAccess()) mediaElement1.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, (Action)delegate { mediaElement1.Play(); });
if (MessageBox.Show("Incoming Call from: " + string.Format(e.RemoteParticipant), "Video Chat Call", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
mixers.Recording.Lines.GetMixerFirstLineByComponentType(
MIXERLINE_COMPONENTTYPE.SRC_MICROPHONE).Volume = 1;
if (!mediaElement1.CheckAccess()) mediaElement1.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, (Action)delegate { mediaElement1.Stop(); });
_currentConversation.StartVideo();
}'
If error occurs at if (MessageBox.Show("Incoming Call from: " + string.Format(e.RemoteParticipant), "Video Chat Call", MessageBoxButton.YesNo) == MessageBoxResult.Yes) and says {"Arithmetic operation resulted in an overflow."}
http://www.computercabal.com/2010/11/mute-microphone-from-c-on-windows.html -- this gentleman appears to have had a similar problem, and he's provided the source code for a solution.
You can use Audio Switcher Api
https://www.nuget.org/packages/AudioSwitcher.AudioApi.CoreAudio/4.0.0-alpha5
Code is quite simple:
private async void btnMute_ButtonClick(object sender, EventArgs e)
{
var audioController = new CoreAudioController();
var devices = await audioController.GetDevicesAsync(DeviceType.Capture, DeviceState.Active);
var device = devices.FirstOrDefault(x => x.IsDefaultDevice);
if(device != null) {
await device.SetMuteAsync(!device.IsMuted);
}
}
this might help: Windows Mixer Control in C#
Good luck :).
EDIT: It can also mute certain devices if I'm right.