I am using (Always Allow) location permission in my iOS Xamarin Forms application. The problem I face today is that I'm unable to fully leverage ALWAYS permission in order to bring back my app (which was already killed) in the background whenever a location event occurs. Any Solution for that ?
My Code :
lm = new CLLocationManager
{
PausesLocationUpdatesAutomatically = false,
DesiredAccuracy=CLLocation.AccuracyBest,
DistanceFilter=0,
AllowsBackgroundLocationUpdates = true
};
lm.LocationsUpdated +=
(object sender, CLLocationsUpdatedEventArgs e) => {
var locations = e.Locations;
LocationEventArgs args = new LocationEventArgs();
args.lat = locations[locations.Length - 1].Coordinate.Latitude;
args.lng = locations[locations.Length - 1].Coordinate.Longitude;
locationObtained(this, args); //Log
};
lm.AuthorizationChanged += (object sender,
CLAuthorizationChangedEventArgs e) => {
if (e.Status == CLAuthorizationStatus.Authorized)
{
//lm.StartMonitoringSignificantLocationChanges();
lm.StartUpdatingLocation();
}
};
lm.RequestAlwaysAuthorization();
Thank you
The problem I face today is that I'm unable to fully leverage ALWAYS permission in order to bring back my app (which was already killed) in the background whenever a location event occurs.
If APP terminated , AllowsBackgroundLocationUpdates will not work. You should ensure app is not killed first.
allowsBackgroundLocationUpdates : A Boolean value indicating whether the app should receive location updates when suspended.(Not killed status).
Related
I am using Plugin.LocalNotification to create notification after file is downloaded. But my issue is I am not able to open that file by tapping notification. Instead it navigates to MainPage(Login Page in my case)
public App()
{
InitializeComponent();
NotificationCenter.Current.NotificationTapped += Current_NotificationTapped;
}
private void Current_NotificationTapped(NotificationTappedEventArgs e)
{
// This event doesn't get fire.
}
I show Notification using following code after creating pdf file.
var notification = new NotificationRequest
{
Title = "Invoice",
Description = message,
ReturningData = filepath, // Returning data when tapped on notification.
// NotifyTime = DateTime.Now.AddSeconds(2) // Used for Scheduling local notification, if not specified notification will show immediately.111
};
NotificationCenter.Current.Show(notification);
NotificationCenter.Current.NotificationTapped += Current_NotificationTapped; // tried calling tapped event here as well. but no success.
private void Current_NotificationTapped(NotificationTappedEventArgs e)
{
}
Someone has also reported bug regarding this issue on github.
Thanks
I am trying to launch my UWP app from another UWP app. This feature is working fine for android and ios.
I am using this blog for the UWP section.
UWP Render Code
public class OpenAppImplementation : IAppHandler
{
public async Task<bool> LaunchApp(string stringUri)
{
Uri uri = new Uri(stringUri);
return await Windows.System.Launcher.LaunchUriAsync(uri);
}
}
In the Main project
var appname = "UWP package name://";
var result = await DependencyService.Get<IAppHandler>().LaunchApp(appname);
if (!result)
{
Device.OpenUri(new Uri(windows store link));
}
I am passing the package name of the second app as appname here. If the app is installed in the device, I need to open that; else open the windows store app page for downloading the app.
When I execute this I am getting a screen like below:
Update
I have added the protocol declaration on the second app as below:
Then on the first app call like below:
var appname = "alsdk:";
var result = await DependencyService.Get<IAppHandler>().LaunchApp(appname);
if (!result)
{
Device.OpenUri(new Uri("windows store link"));
}
The second app is opening and the splash screen is showing after the above changes. But not going to the home page, the app is staying in the splash screen. Also, I need to show the windows store app page if the app is not installed on the device. What I am missing here?
The problem is you have pass the wrong uri scheme or you have not registered protocol for the launched app. For more please refer this document.
Steps:
Specify the extension point in the package manifest like the following.
<Applications>
<Application Id= ... >
<Extensions>
<uap:Extension Category="windows.protocol">
<uap:Protocol Name="alsdk">
<uap:Logo>images\icon.png</uap:Logo>
<uap:DisplayName>SDK Sample URI Scheme</uap:DisplayName>
</uap:Protocol>
</uap:Extension>
</Extensions>
...
</Application>
And you could also use visual studio manifest GUI to add the protocol.
If you have not specific the parameter you could remove // , just keep uri scheme like alsdk:.
Update
The second app is opening and the splash screen is showing after the above changes. But not going to the home page, the app is staying in the splash screen. Also, I need to show the windows store app page if the app is not installed on the device. What I am missing here?
In target app we need process OnActivated method and invoke Window.Current.Activate() finally.
protected override void OnActivated(IActivatedEventArgs args)
{
if (args.Kind == ActivationKind.Protocol)
{
ProtocolActivatedEventArgs eventArgs = args as ProtocolActivatedEventArgs;
// Navigate to a view
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame == null)
{
rootFrame = new Frame();
Window.Current.Content = rootFrame;
}
// assuming you wanna go to MainPage when activated via protocol
rootFrame.Navigate(typeof(MainPage), eventArgs);
}
Window.Current.Activate();
}
Update
if you launch xamarin uwp app, you need initialize Xamarin Form component in the OnActivated method.
protected override void OnActivated(IActivatedEventArgs args)
{
if (args.Kind == ActivationKind.Protocol)
{
ProtocolActivatedEventArgs eventArgs = args as ProtocolActivatedEventArgs;
// Navigate to a view
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame == null)
{
rootFrame = new Frame();
Xamarin.Forms.Forms.Init(args);
Window.Current.Content = rootFrame;
}
// assuming you wanna go to MainPage when activated via protocol
rootFrame.Navigate(typeof(MainPage), eventArgs);
}
Window.Current.Activate();
}
I'm using Visual Studio for Mac.
When I build and run my app on the iPhone simulator, it only runs on the iPhone XS Max simulator.
Every other simulated device (from XS Max all the way down to iPhone 6) will display the splash screen but then thorw a
Foundation.MonoTouchexception...NSInternalInconsistencyException Reason: Application windows are expected to have a root view controller at the end of the application launch
The only physical device I have to test with is an iPhone 6S Plus, but it throws the same exception as well.
I have tried cleaning and rebuilding, deleting bin and obj folders.
I checked the device log, but I haven't found anything yet to lead me to a solution (if you need the logs I can certainly provide).
Any ideas on what could cause this peculiar issue or what to keep an eye out for in the device logs that could help lead to a resolutoin?
This issue was being caused by my tokenExpiration on my App.xaml page.
At some point when I tested my app on iPhone XS Max 12.1 the string was stored somewhere else so that when the app initializes this string isn't empty so var tokenDate = Convert.ToDateTime(tokenExpiration); will not throw an error.
Then my if statement can be run successfully, and my application will have a base root view.
However, for a new simulator that I haven't used before and haven't set the tokenExpiration string before when you want to retrieve this tokenExpiration it will return an empty string as the default setting.
Then var tokenDate = Convert.ToDateTime(tokenExpiration); will throw an error as it can't convert the empty string.
At last, my code will then run to my catch statement which means my application loses a base root view, and that is what causes my issue.
Previous Code:
try
{
TaskScheduler.UnobservedTaskException += (sender, e) => {
Console.WriteLine(e.Exception.ToString(), Category.Exception, Priority.High);
};
await NavigationService.NavigateAsync("/LoginPage");
}
catch (Exception e)
{
Console.WriteLine(e.ToString(), Category.Exception, Priority.High);
}
Updated Code:
var tokenExpiration = Preferences.Get("facebookTokenExpiration", string.Empty);
if (tokenExpiration != null && tokenExpiration.Length > 0)
{
var tokenDate = Convert.ToDateTime(tokenExpiration);
var tokenStatus = DateTime.Now.CompareTo(tokenDate);
//Token is still active
if (tokenExpiration != string.Empty & tokenStatus < 0)
{
await NavigationService.NavigateAsync("/MainTabbedPage?selectedTab=PuppyDetailsPage");
}
else
{
await NavigationService.NavigateAsync("/Login");
}
}
else
{
await NavigationService.NavigateAsync("/MainTabbedPage?selectedTab=PuppyDetailsPage");
}
Edit: Thank you #LandLu a forums.xamarin.com for helping me to resolve this.
I am sending app usage analytics events to Fabric and Firebase. Together with the event, I am also sending another value (an example event type is font_selection and the value I pass is which font the user selects - this is a number that tells me which font was used). I was using Fabric events and I could see which fonts were being used more or less when I selected the font_selection event (I could see numbers for each different font).
Since the Fabric functionality is being moved to Firebase, I started checking the Analytics section in Firebase. Unfortunately I cannot find the above information in Firebase > Analytics > Events. I can see the event, font_selection but when I click on it I do not get the additional information I used to get in Fabric. Is there something I am missing or has this additional information been removed from Firebase?
This is still an issue for me. Here is how I'm sending the event into Firebase:
protected void Report(string id, Severity severity, string message = null, Exception exception = null)
{
try
{
var processedId = id ?? severity.ToString().ToLowerInvariant();
var values = new Dictionary<string, string>();
values.Add("severity", severity.ToString().ToLowerInvariant());
if (!string.IsNullOrWhiteSpace(message))
{
values.Add("message", message);
}
if (exception != null)
{
values.Add("exception", exception.Message);
values.Add("trace", exception.StackTrace);
}
SendEvent(values, processedId);
}
catch
{
// do nothing.
}
}
protected override void SendEvent(Dictionary<string, string> eventData, string id)
{
var firebaseAnalytics = FirebaseAnalytics.GetInstance(Android.App.Application.Context);
var bundle = new Android.OS.Bundle();
foreach(var pair in eventData)
{
bundle.PutString(pair.Key, pair.Value);
}
firebaseAnalytics.LogEvent(id, bundle);
}
During runtime, I call this successfully and I can see these event popping up in Firebase console:
But how do I display the rest of the properties that I have bundled with it? Here is what the console shows me in events:
I feel like I must be using it wrong or something. There is no UI to shows me a simple chronologically sorted table with events as they came in with properties they came with. I frankly don't understand what good is this tool to me.
Theory: Use Cortana on the band to launch your application on the phone, and that application will communicate with the band, allowing your band custom tile/buttons to work.
I have it working when you use Cortana on the phone, BUT when using Cortana on the band it does try to launch the app, but it hangs on Starting (app name) with your app icon (basically Cortana trying to start the app). I don't even think it makes it to the app.xaml..
This is where I need help...
Use this page to get Cortana to launch your simple application...
https://msdn.microsoft.com/en-us/library/windows/apps/mt185609.aspx?f=255&MSPPError=-2147217396
You have to put code in your app.xaml.cs as well to navigate to the main page when coming in via voice commands.
protected override void OnActivated(IActivatedEventArgs args)
{
if (args.Kind == ActivationKind.VoiceCommand)
{
Frame rootFrame = Window.Current.Content as Frame;
// if (rootFrame == null)
//{
// Repeat the same basic initialization as OnLaunched() above, taking into account whether
// or not the app is already active.
rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();
rootFrame.NavigationFailed += OnNavigationFailed;
if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: Load state from previously suspended application
}
// Place the frame in the current Window
Window.Current.Content = rootFrame;
}
if (rootFrame.Content == null)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
rootFrame.Navigate(typeof(MainPage));
}
Window.Current.Activate();
}
// }
}