I am working on an MQTTnet application for mobile/wearable devices. I've tested my code in both a standard C# Console application and .Net Core application, both work as expected. The issue I am having is when I port the code to Xamarin Forms, for running on a Galaxy Watch. The app will run for a few seconds, but then it will crash. I believe it could be from assigning the Label text too often?
I have an MQTT publisher device pumping out a simple position value at a 10ms interval. Where my other apps will just keep chugging along, the app in Xamarin will lock and then eventually crash. If it comment out the Label.Text assignment, the app keeps running without a crash.
Here is my Xamarin code, is there a better way to handle the assignment?
// Event Handler to the ApplicationMessageRecevied event
client.ApplicationMessageReceived += (s, e) =>
{
StatusLabel.Text = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
};
I found that using the following to assign the label works well. My publisher is sending messages at 2ms intervals, and the watch is stable!
Device.BeginInvokeOnMainThread(() => {
PositionData.Text = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
});
Related
I'm trying to send GPS-coordinates from an Android device to the Hololens by BLE-advertisments.
The problem as far as i see, the events from BluetoothLEAdvertisementWatcher do not trigger on the Hololens.
I have tried copy-paste both this implementation
and this on the receiver side, no received event.
This is the current implementation in Unity, i have implementated the same functions in a blank UWP-C# project and deployed directly on the Hololens with the same result.
private void StartWatcher()
{
void OnAdvertisementReceived(object sender, BluetoothLEAdvertisementReceivedEventArgs eventArgs)
{
Debug.Log("Event triggered"); // switched to Write-line on the C#->UWP implementation
}
void OnAdvertisementStop(object sender, BluetoothLEAdvertisementWatcherStoppedEventArgs eventArgs)
{
Debug.Log("Event triggered"); // switched to Write-line on the C#->UWP implementation
}
try {
BluetoothLEAdvertisementWatcher watcher = new BluetoothLEAdvertisementWatcher();
watcher.AdvertisementFilter.Advertisement.ManufacturerData.Add(GetManufacturerData());
watcher.Received += OnAdvertisementReceived;
watcher.Stopped += OnAdvertisementStop;
watcher.Start();
Debeug.Log("Started"); // switched to Write-line on the C#->UWP implementation
} catch (Exception e){
}
}
private BluetoothLEManufacturerData GetManufacturerData()
{
var manufacturerData = new BluetoothLEManufacturerData();
manufacturerData.CompanyId = 0X06EF;
return manufacturerData;
I know the advertisements are sent, becuase if i debug the native UWP-application directly in Visual Studio on the PC(even as ARM64), everything works. The events are triggered.
The watcher.Status reports "started" on the Hololens
Even if i disable the Bluetooth on the HoloLens while the application are running, the stop-event are not either triggered.
If i check watcher.Status after i disable the Bluetooth, the status reports aborted but the Stoped-event are not recieved.
The capability is activated following this article
Now to where it gets wierd.
During one of my first tries i had my application running on the Hololens as i've tried to remove the pairing between the Android device and HoloLens.
The android devices appears as two devices on the Hololens, device name as one and "LE"+MAC as the other.
Sometime during the time i was in the Bluetooth settings and removed the two adapters from the cellphone, the HoloLens recieved three separate advertisments. The data in the advertisments was also confirmed from my Android device becuase during my inital tries i parsed the data.
But thats it, i have tried to replicate this for 10 hours today, Pair and unpair the different adapters in different stages while listening for recieve events but without luck.
On my PC, it do not matter if the adapters are paired or not.
I have tried both .NET Standard 2.0 and .Net 4.x as API Compatibility Level.
I have set breakpoints in both the receive and Stoped event-handler as i was afraid that the calls from the Event-functions was the problem. As far as i see, we never reach the implemented events.
Any suggestion on what might be the next step to check is appreciated.
The Hololens Build is 19041.1144.
Ok, so i can now recevie advertisments on the HoloLens by running the example provedied by Microsoft.
I could not receive any events at all and no updates was available in the settings, so i've reinstalled all applications in the Microsoft Store and that seems to be the solution for me. After that and a restart of the HoloLens i was able to recieve advertisements from my PC.
Another tip for other tip for people trying to recieve advertisements on the HoloLens 2.
When i was able to receive advertismements from my pc i saw that the advertisments from my Android device was not recieved on the HoloLens, but recieved on the PC.
The advertisments on my PC was of type NonConnectableUndirected and from my Android device ScannableUndirected.
I needed to change to "AdvertisingSet" and in the AdvertisingSetParameters set both isConnectable and isScannable to false to be able to send NonConnectableUndirected.
Now the HoloLens recevies the advertisments from my Android device.
I am working on a windows iot core application running on a rasberry pi3
i tried to create/fetch the device key from the azure iot hub using the methods below
public MainPage()
{
systemName = "RaspIot";
this.InitializeComponent();
/* Register for the unloaded event so we can clean up upon exit */
Unloaded += MainPage_Unloaded;
registryManager = RegistryManager.CreateFromConnectionString(connectionString);
AddDeviceAsync().Wait();
}
private static async Task AddDeviceAsync()
{
Device device;
try
{
device = await registryManager.AddDeviceAsync(new Device(systemName));
}
catch (DeviceAlreadyExistsException)
{
device = await registryManager.GetDeviceAsync(systemName);
}
deviceKey = device.Authentication.SymmetricKey.PrimaryKey;
}
If the device with name "RaspIot" is already registered an exception is thrown.
This is working fine in a .net45 console application. but in the UWP application for the PI3 the exception is thrown (pops up in while debugging) but not captured by the catch). what should i do differently?
I can reproduce your issue. And when running the UWP app using your code, the UI hangs and is not responsive. So it is not a best practice in UWP app.
In the UWP app, you can directly use AddDeviceAsync() without Wait(). It will execute normal and can catch the exception.
But in the console app, the app will exit without getting the task completion if you remove Wait() operator. So they are different.
For calling asynchronous APIs in UWP you can reference this document.
Update:
And it is not recommended register a device in the MainPage function since it will always be executed every time the app is started.
The OnSuspending event is not triggered for my UWP app but this problem only occurs on Windows Phone running Windows 10. It works as expected when running it as a Windows Store app on my local machine or the simulator.
I'm using this event to save my app's settings when the app is closing, but this is obviously causing a major problem for windows phone since this event is not triggered.
As you can see, the OnSuspending event is initialized when the app starts
public App()
{
Microsoft.ApplicationInsights.WindowsAppInitializer.InitializeAsync(
Microsoft.ApplicationInsights.WindowsCollectors.Metadata |
Microsoft.ApplicationInsights.WindowsCollectors.Session);
this.InitializeComponent();
this.Suspending += OnSuspending;
}
Below is the OnSuspending code that should be called but isn't when running in Windows Phone 10.
private async void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
//TODO: Save application state and stop any background activity
await Locator.MainPageViewModel.SaveSettings();
deferral.Complete();
}
Any ideas on how I can resolve this or is there a potential work-around?
Thanks.
UPDATE-1:
When I terminate my app by holding the flag key and click on the cross to terminate it, is closes the app but it still doesn't trigger the OnSuspending event, but the .net IDE still runs. When I press F5 to run the app again, it then triggers the OnSuspending event. My app starts but the code stops running in the IDE.
From the official App lifecycle documentation:
A note about debugging using Visual Studio: Visual Studio prevents Windows from suspending an app that is attached to the debugger. This is to allow the user to view the Visual Studio debug UI while the app is running. When you're debugging an app, you can send it a suspend event using Visual Studio. Make sure the Debug Location toolbar is being shown, then click the Suspend icon.
That means that the OnSuspending event won't get fired while you are attached to the Visual Studio debugger. If you want to debug it, manually send the event by selecting the respective Lifecycle Event.
I need to push notifications to tens of thousands of iOS devices that my app installed. I'm trying to do it with PushSharp, but I'm missing some fundamental concepts here. At first I tried to actually run this in a Windows service, but couldn't get it work - getting null reference errors coming from _push.QueueNotification() call. Then I did exactly what the documented sample code did and it worked:
PushService _push = new PushService();
_push.Events.OnNotificationSendFailure += new ChannelEvents.NotificationSendFailureDelegate(Events_OnNotificationSendFailure);
_push.Events.OnNotificationSent += new ChannelEvents.NotificationSentDelegate(Events_OnNotificationSent);
var cert = File.ReadAllBytes(HttpContext.Current.Server.MapPath("..pathtokeyfile.p12"));
_push.StartApplePushService(new ApplePushChannelSettings(false, cert, "certpwd"));
AppleNotification notification = NotificationFactory.Apple()
.ForDeviceToken(deviceToken)
.WithAlert(message)
.WithSound("default")
.WithBadge(badge);
_push.QueueNotification(notification);
_push.StopAllServices(true);
Issue #1:
This works perfectly and I see the notification pop up on the iPhone. However, since it's called a Push Service, I assumed it would behave like a service - meaning, I instantiate it and call _push.StartApplePushService() within a Windows service perhaps. And I thought to actually queue up my notifications, I could do this on the front-end (admin app, let's say):
PushService push = new PushService();
AppleNotification notification = NotificationFactory.Apple()
.ForDeviceToken(deviceToken)
.WithAlert(message)
.WithSound("default")
.WithBadge(badge);
push.QueueNotification(notification);
Obviously (and like I already said), it didn't work - the last line kept throwing a null reference exception.
I'm having trouble finding any other kind of documentation that would show how to set this up in a service/client manner (and not just call everything at once). Is it possible or am I missing the point of how PushSharp should be utilized?
Issue #2:
Also, I can't seem to find a way to target many device tokens at once, without looping through them and queuing up notifications one at a time. Is that the only way or am I missing something here as well?
Thanks in advance.
#baramuse explained it all, if you wish to see a service "processor" you can browse through my solution on https://github.com/vmandic/DevUG-PushSharp where I've implemented the workflow you seek for, i.e. a win service, win processor or even a web api ad hoc processor using the same core processor.
From what I've read and how I'm using it, the 'Service' keyword may have mislead you...
It is a service in a way that you configure it once and start it.
From this point, it will wait for you to push new notifications inside its queue system and it will raise events as soon as something happens (delivery report, delivery error...). It is asynchronous and you can push (=queue) 10000 notifications and wait for the results to come back later using the event handlers.
But still it's a regular object instance you will have to create and access as a regular one. It doesn't expose any "outside listener" (http/tcp/ipc connection for example), you will have to build that.
In my project I created a small selfhosted webservice (relying on ServiceStack) that takes care about the configuration and instance lifetime while only exposing the SendNotification function.
And about the Issue #2, there indeed isn't any "batch queue" but as the queue function returns straight away (enqueue and push later) it's just a matter of a looping into your device tokens list...
public void QueueNotification(Notification notification)
{
if (this.cancelTokenSource.IsCancellationRequested)
{
Events.RaiseChannelException(new ObjectDisposedException("Service", "Service has already been signaled to stop"), this.Platform, notification);
return;
}
notification.EnqueuedTimestamp = DateTime.UtcNow;
queuedNotifications.Enqueue(notification);
}
I'm running into some strange stuff, hopefully someone can shed some light here...
I have my main app, app A, and I need to launch another app (app B) from App A. App A also needs to know when app B has exited. The code I've been using to do this looks like this:
_applicationProcess.StartInfo =
new ProcessStartInfo { FileName = _currentExecutablePath, WorkingDirectory = dir };
_applicationProcess.Start();
And I subscribe to the Exited event on the Process (_applicationProcess) to detect when it finishes.
Here's the kicker though. Both app A and app B share a library that sends a notification when a service is initialized (this is hooking up to the kinect service, as both apps are Kinect apps).
The bizarre thing is that when app B is launched using the code above, app A gets notified that the service is initialized. Yuck!
I don't want this. I want app B to be totally isolated from app A, yet I need to know when it has ended.
How can I do this?