I use Xamarin geolocation in my project. When I test the application in the simulator
cannot throw 'plugin.geolocator.abstractions.Geolocationexception on thread 1 and does not return values.
var locator = CrossGeolocator.Current;
locator.DesiredAccuracy = 20;
var position = await locator.GetPositionAsync(timeout:
TimeSpan.FromSeconds(10000));
If you are using the iPhone Simulator, you need to simulate a location.
In the simulator menu select Debug > Location, and make sure you have a location set.
Here is the documentation
Related
I'm trying to get a string (UserID) using Preferences.Get (Xamarin.Essentials) on a PushNotification.Extension project, but as the Preferences.Set happens in the Xamarin iOS project, I'm always getting an empty string in the extensions project.
Is there a way to share this preference between the iOS project and the iOS.extension?
public string UserID
{
get
{
return Preferences.Get(nameof(UserID), UserIDDefault);
}
set
{
Preferences.Set(nameof(UserID), value);
}
}
According to Apple docs , please follow the steps to enable data-sharinig .
Enable App Groups Capabilities , refer to App Group Capabilities in Xamarin.iOS.
Add the app to the App Group .
Use NSUserDefaults and init it with the name of the extension bundle identifier.
//Save
var defaults = new NSUserDefaults(#"com.example.domain.MyShareExtension");
defaults.SetString("value","Mykey");
defaults.Synchronize();
//Get
var defaults = new NSUserDefaults(#"com.example.domain.MyShareExtension");
var value = defaults.ValueForKey("Mykey");
"NSUserDefaults(string)" does not work for me.
In the Xamarin iOS documentation this constructor is marked as deprecated! see https://learn.microsoft.com/en-us/dotnet/api/foundation.nsuserdefaults?view=xamarin-ios-sdk-12
But when I use "NSUserDefaults(String, NSUserDefaultsType)" it runs perfect.
I used the Xamarin version of SoupChef for Siri Intents. I was able to access the Container's Assets from the SoupChefIntentsUI.IntentViewController by requesting the bundle by identifier (using the BundleIdentifier of the main App) and then I just loaded the image by passing the bundle
CGSize DisplayOrderConfirmation(Order order, OrderSoupIntent intent, OrderSoupIntentResponse response){
/* unrelated code */
//this line work in the SoupChef example but
//On Xamarin.Forms this returns null
var containerBundle = NSBundle.FromIdentifier("com.something.SoupChef");
//always returns null because it seems it looks into the IntentsUI.Assets
var iconNull = UIImage.FromBundle("AppIcon");
//it returns the icon from the SoupChef.Assets
var iconNotNull = UIImage.FromBundle("AppIcon", containerBundle, configuration: null);
/* unrelated code */
}
I was also able to retrieve the AppIcon by creating the NSBundle doing something like this (in case you didn't want to assume that the bundle identifier names don't follow the Apple standard where the Container and the extensions have the same bundle identifier with the exception of the last segment)
CGSize DisplayOrderConfirmation(Order order, OrderSoupIntent intent, OrderSoupIntentResponse response){
/* unrelated code */
Class GetClassForType (Type type)
{
IntPtr myClassHandle = Class.GetHandle (typeToLookup);
if (myClassHandle != IntPtr.Zero)
return new Class (myClassHandle);
else
return null;
}
//this returns the bundle identifier of the SoupChef app
//(not the SoupChefIntentUI) on the SoupChef example
//on Xamarin.Forms (my project) it returns the IntentsUI identifier
var containerBundle = NSBundle.FromClass(GetClassForType(typeof(SoupChef.OrderIntent)));
//the icon is returned
var icon = UIImage.FromBundle("AppIcon", containerBundle, configuration: null);
/* unrelated code */
}
My problem is that I want to do the same thing on a different project that is using Xamarin.Forms, and the two previous ways that worked for me on the SoupChef project don't work here.
Is there a way to access the Assets set on the App.iOS.Assets or do I have to move them to the shared project where I have the models and other things that both the App.iOS and its Extensions are using?
I noticed that the Bindings (the project where the OrderIntent is) in the SoupChef example has the same namespace as the Container App ("SoupChef"), so I assigned the same namespace in my project with Xamarin.Forms and still nothing.
I have a xamarin forms app. When I compile and test on my Pixel3, everything seems to be working properly. When I load it up in my iOS device running iOS13.something, I get the following error when I try to make my second call to a web service in my app. The error is shown below.
Assertion at /Users/builder/jenkins/workspace/archive-mono/2019-08/ios/release/mono/mini/interp/interp.c:2160, condition `is_ok (error)' not met, function:do_jit_call, Attempting to JIT compile method '(wrapper other) void object:gsharedvt_out_sig (object&,single&,int&,intptr)' while running in aot-only mode. See https://learn.microsoft.com/xamarin/ios/internals/limitations for more information. assembly: type: member:(null)
The code is a bit of a mess, but has been working in the past.
var uri = String.Format("{0}//{1}/{2}?PlayerToken={3}", protocol, servername, tournamentsInClubUrl, userToken);
var httpC = new HttpClient();
HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, uri);
requestMessage.Headers.Add("AppKey", AppKey);
var body = await httpC.SendAsync(requestMessage); <-- Error happens here.
var str = await body.Content.ReadAsStringAsync();
var res = JsonConvert.DeserializeObject<List<PicVideoApp.Models.TournamentInfo>>(str);
httpC.Dispose();
httpC = null;
return res;
I assume that I am doing something wrong, but danged if I can see it. Any ideas are appreciated.
It runs properly in the iOS Simulator.
TIA.
From shared error info , you need to use C# delegate to call native functions .
To call a native function through a C# delegate, the delegate's declaration must be decorated with one of the following attributes:
UnmanagedFunctionPointerAttribute (preferred, since it is cross-platform and compatible with .NET Standard 1.1+)
MonoNativeFunctionWrapperAttribute
For example :
[MonoNativeFunctionWrapper]
delegate void SomeDelegate (int a, int b);
//
// the ptrToFunc points to an unmanaged C function with the signature (int a, int b)
void Callback (IntPtr ptrToFunc)
{
var del = (SomeDelegate) Marshal.GetDelegateForFunctionPointer (ptrToFunc, typeof (SomeDelegate));
// invoke it
del (1, 2);
A similar error was thrown at me in iOS when I used dynamic types in my code. I was able to solve it by enabling the 'Mono Interpreter' in iOS build settings. Hope that helps in your case.
I am getting some issues returning data from azure mobile backend api using android emulator. The mobile app is written with Xamarin and I am using MobileServiceClient and IMobileServiceSyncTable. The following is what I have coded:
var _mobileServiceClient = new MobileServiceClient(url);
var store = new MobileServiceSQLiteStore("notesdb.db");
store.DefineTable<Notes>();
_mobileServiceClient.SyncContext.InitializeAsync(store);
var _notesTable = _mobileServiceClient.GetSyncTable<Notes>();
var temp = await _notesTable.ReadAsync();
Backend code is as followed:
public IQueryable<Notes> GetAllNotes()
{
return Query();
}
Whenever I do that, the app will become unresponsive and never returned. Its like it is in deadlock mode.
Has anyone had this problem?
After looking at the MobileServiceClient usage: https://learn.microsoft.com/en-us/azure/app-service-mobile/app-service-mobile-dotnet-how-to-use-client-library
Your calls seem fine except one:
_mobileServiceClient.SyncContext.InitializeAsync(store);
Since you are not awaiting this method, the sync context will not be initialized for your next methods.
So just await the method and you should be fine:
await _mobileServiceClient.SyncContext.InitializeAsync(store);
One general rule your can apply almost everytime: always await the methods returning Task objects.
Also since you are in the service/repository layer, you should ConfigureAwait(false) your methods:
var _mobileServiceClient = new MobileServiceClient(url);
var store = new MobileServiceSQLiteStore("notesdb.db");
store.DefineTable<Notes>();
await _mobileServiceClient.SyncContext.InitializeAsync(store).ConfigureAwait(false);
var _notesTable = _mobileServiceClient.GetSyncTable<Notes>();
var temp = await _notesTable.ReadAsync().ConfigureAwait(false);
Doing that your code won't run in the UI thread (well it's not guaranteed but I don't want to confuse you :). Since you are not running the code on the same thread, it will also reduce possible deadlocks.
more on that: https://medium.com/bynder-tech/c-why-you-should-use-configureawait-false-in-your-library-code-d7837dce3d7f
I have I have been wasting at least a day trying to make this work. I am trying to play an mp3 file that i placed in Resources/raw once a notification is received. I do not know exactly how to get the Uri. My questions please are:
1.To play a custom file do you have to place it in Resources/raw or can it be also in Assets/Sounds under the Xamarin Android project.
2.How do i get the Uri correctly based on where the mp3 file resides.
This is my code:
private void createNotificationChannel()
{
var channelName = GetString(Resource.String.noti_chan_urgent);
var channelDescription = GetString(Resource.String.noti_chan_urgent_description);
// set the vibration patterm for the channel
long[] vibrationPattern = { 100, 200, 300, 400, 500, 400, 300, 200, 400 };
// Creating an Audio Attribute
var alarmAttributes = new AudioAttributes.Builder().SetUsage(AudioUsageKind.Alarm).Build();
// Create the uri for the alarm file
var alarmUri = Android.Net.Uri.Parse("MyApp.Android/Resources/raw/alarm.mp3"); // this must be wrong because its not working
// create chan1 which is the urgent notifications channel
var chan1 = new NotificationChannel(PRIMARY_CHANNEL_ID, channelName, NotificationImportance.High)
{
Description = channelDescription
};
// set the channel properties
chan1.EnableLights(true);
chan1.LightColor = Color.Red;
chan1.EnableVibration(true);
chan1.SetVibrationPattern(vibrationPattern);
chan1.SetSound(alarmUri, alarmAttributes);
chan1.SetBypassDnd(true);
chan1.LockscreenVisibility = NotificationVisibility.Public;
var manager = (NotificationManager)GetSystemService(NotificationService);
manager.CreateNotificationChannel(chan1);
}
}
I figured it out and I hope this will help someone better than getting a downvote for a question, this is how you do it:
(Note: Make sure you put your mp3 file in your Xamarin Android project under Resources/raw/soundFile.mp3 and build the file as Android Resource).
Then create the Uri like this:
Android.Net.Uri alarmUri = Android.Net.Uri.Parse(${ContentResolver.SchemeAndroidResource}://{Context.PackageName}/{Resource.Raw.soundFile}");
Create the Alarm Attributes like this:
var alarmAttributes = new AudioAttributes.Builder()
.SetContentType(AudioContentType.Sonification)
.SetUsage(AudioUsageKind.Notification).Build();
And finally setSound on the channel itself ONLY from Android Oreo onwards (not on the notification, create the channel at application launch):
chan1.SetSound (alarmUri, alarmAttributes);
uri = Android.Net.Uri.Parse(
"android.resource://" + Application.Context.PackageName + "/raw/sound2");
only change I had to make. to Fredsomofspeech answer.
android 9.
visualstudio 2019 xamarin.forms mobile ios android. sound2.mp3
was running a file android could not play, so make sure download a mp3 file for testing verified to work.