issues with the Geolocator xamarin plugin by James Montemagno - xamarin

Hello I am working on a app in xamarin forms that needs to take the gps location and combine the latitude and longitude into a url for forcast.io i'm using the Geolocator plugin by James Montemagno and followed the readme but i'm still getting these errors:
Severity Code Description Project File Line Suppression State
Error CS0165 Use of unassigned local variable 'msi'
Severity Code Description Project File Line Suppression State
Error CS0266 Cannot implicitly convert type
'Plugin.Geolocator.Abstractions.IGeolocator' to
'Plugin.Geolocator.CrossGeolocator'. An explicit conversion exists
(are you missing a cast?)
Severity Code Description Project File Line Suppression State
Error CS1061 'CrossGeolocator' does not contain a definition for
'IsGeolocationEnabled' and no extension method 'IsGeolocationEnabled'
accepting a first argument of type 'CrossGeolocator' could be found
(are you missing a using directive or an assembly reference?)
Severity Code Description Project File Line Suppression State
Error CS1061 'CrossGeolocator' does not contain a definition for
'GetPositionAsync' and no extension method 'GetPositionAsync'
accepting a first argument of type 'CrossGeolocator' could be found
(are you missing a using directive or an assembly reference?)
Severity Code Description Project File Line Suppression State
Error CS1061 'CrossGeolocator' does not contain a definition for
'DesiredAccuracy' and no extension method 'DesiredAccuracy' accepting
a first argument of type 'CrossGeolocator' could be found (are you
missing a using directive or an assembly reference?)
and then here's the radar code:
using Xamarin.Forms;
using System;
using System.Diagnostics;
using Plugin.Geolocator;
namespace AppName.Radar
{
public interface MyLocationTracker
{
void ObtainMyLocation();
event EventHandler<MyLocationEventArgs> locationObtained;
}
public interface MyLocationEventArgs
{
double lat { get; set; }
double lng { get; set; }
}
public partial class RadarHome : ContentPage
{
private readonly CrossGeolocator _locator;
private double BetaLat;
private double BetaLog;
public RadarHome()
{
MyLocationTracker msi;
_locator = CrossGeolocator.Current;
if (_locator.IsGeolocationEnabled == false)
{
if (Device.OS == TargetPlatform.Android)
{
msi.locationObtained += (object Esender, MyLocationEventArgs ew) =>
{
Debug.WriteLine(ew.lat);
};
msi.ObtainMyLocation();
}
else if (Device.OS == TargetPlatform.iOS)
{
msi = DependencyService.Get<MyLocationTracker>();
msi.locationObtained += (object Jsender, MyLocationEventArgs je) =>
{
Debug.WriteLine(je.lat);
};
msi.ObtainMyLocation();
}
}
_locator.DesiredAccuracy = 50;
GetPositionAsynchronously();
string str = string.Format(
"https://forecast.io/?mobile=1#/f/Lat:{0} , Long: {1}", BetaLat, BetaLog);
var client = new System.Net.Http.HttpClient();
client.BaseAddress = new Uri(str);
}
private async void GetPositionAsynchronously()
{
//will run asynchronously in a diff thread
var position = await _locator.GetPositionAsync(timeoutMilliseconds: 100000);
BetaLat = position.Latitude; //will work
BetaLog = position.Longitude; // will work
}
}
}
I have the latest Geolocator nuget package installed on all 3 platforms (Froms, iOS, Android) I am using VS2015 update 3 and am still learning xamrarin forms so I'm sorry for asking such a noob question.
Thanks in advance!

Your _locator definition should look like this
private readonly IGeolocator _locator;

if (Device.OS == TargetPlatform.Android)
{
//You missed to resolve plugin there
msi = DependencyService.Get<MyLocationTracker>();
msi.locationObtained += (object Esender, MyLocationEventArgs ew) =>
{
Debug.WriteLine(ew.lat);
};
msi.ObtainMyLocation();
}

So both #William Corncob Decker, and #Greensy answers were correct
_locator definition needs to be: private readonly IGeolocator _locator;
and I did miss to resolve the msi plugin heres that code:
if (Device.OS == TargetPlatform.Android)
{
//You missed to resolve plugin there
msi = DependencyService.Get<MyLocationTracker>();
msi.locationObtained += (object Esender, MyLocationEventArgs ew) =>
{
Debug.WriteLine(ew.lat);
};
msi.ObtainMyLocation();
}
The only reason I'm doing this is because I can't mark both William Corncob Decker, and Greensy answers as correct so full credit goes to both of them!
Thank you guys again!

Related

Error on all Program.cs files on eShopOnContainers, microsoft microsevice based implmentation

Severity Code Description Project File Line Suppression State Error CS0260 Missing partial modifier on declaration of type 'Program'; another partial declaration of this type exists WebStatus D:\GitHub\eShopOnContainers\src\Web\WebStatus\Program.cs 123 Active
...
(int httpPort, int grpcPort) GetDefinedPorts(IConfiguration config)
{
var grpcPort = config.GetValue("GRPC_PORT", 5001);
var port = config.GetValue("PORT", 80);
return (port, grpcPort);
}
public class Program
{
public static string Namespace = typeof(Startup).Namespace;
public static string AppName
=Namespace.Substring(Namespace.LastIndexOf('.',Namespace.LastIndexOf('.') - 1) + 1);
}
this is the program found in Program.cs, look that it doesn't have a defined namespace, there are a bunch of functions defined as 'GetDefinedPorts'. I am following the Microsoft microservice implementation example https://github.com/dotnet-architecture/eShopOnContainers
This looks like a bug in Visual Studio 2022. It doesn't happen in 2019. They are also in the middle of converting the solution to dot net 6 so things may get a little more stable after that work is complete.

How to Reference .Net Core Library in a .Net Core Console Application

I am following this code example
I am on Visual Studio Community 2019 for Mac. I created a .Net Core - Class Library project and compiled to create the assembly file P1-ProgramStructure.dll.
I created another solution with program2.cs code. Please see the code below.
I renamed the .dll to acme.dll and copied the file into its directory.
Class library - .Net Core Project
Program1.cs
using System;
namespace Acme.Collections
{
public class Stack
{
Entry top;
public void Push(object data)
{
top = new Entry(top, data);
}
public object Pop()
{
if (top == null)
{
throw new InvalidOperationException();
}
object result = top.data;
top = top.next;
return result;
}
class Entry
{
public Entry next;
public object data;
public Entry(Entry next, object data)
{
this.next = next;
this.data = data;
}
}
}
}
.Net Core Console App
Program2.cs
using System;
using Acme.Collections;
class Example
{
static void Main()
{
Stack s = new Stack();
s.Push(1);
s.Push(10);
s.Push(100);
Console.WriteLine(s.Pop());
Console.WriteLine(s.Pop());
Console.WriteLine(s.Pop());
}
}
When I run the project, I get the error:
$ dotnet run
Program.cs(15,7): error CS0246: The type or namespace name 'Acme' could not be found (are you missing a using directive or an assembly reference?) [/Users/csarami/VisStudioProjects/cSharp Projects/Project2-ProjectStructure/Project2-ProjectStructure/Project2-ProjectStructure.csproj]
The build failed. Please fix the build errors and run again.
Make sure both projects have the same target framework

LINQ Extensions not available inside CSharpCodeProvider

I have a .NET application that can take a script written in C# and executes it internally. The scripts are parsed by the class listed below and then compiled. I find that whenever I try and use System.Xml.Linq in the C# script that is compiled I get a compile error and I am not sure why.
public static void CreateFunction(string scriptCode, BO.ObjectBO obj)
{
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters options = new CompilerParameters();
options.ReferencedAssemblies.Add("System.Data.dll");
options.ReferencedAssemblies.Add("System.dll");
options.ReferencedAssemblies.Add("System.Xml.dll");
options.ReferencedAssemblies.Add("System.Linq.dll");
options.ReferencedAssemblies.Add("System.Xml.Linq.dll");
options.GenerateExecutable = false;
options.GenerateInMemory = true;
CompilerResults results = provider.CompileAssemblyFromSource(options, scriptCode);
_errors = results.Errors;
if (results.Errors.HasErrors)
{
DataTable errorTable = BO.DataTableBO.ErrorTable();
foreach(CompilerError err in results.Errors)
{
DataRow dr = errorTable.NewRow();
dr["ErrorMessage"] = "Line "+ err.ErrorNumber.ToString() + " " + err.ErrorText;
errorTable.Rows.Add(dr);
}
return;
}
Type binaryFunction = results.CompiledAssembly.GetType("UserFunctions.BinaryFunction");
_methodInfo = binaryFunction.GetMethod("Function");
}
Here is the error message I get when I try and run a script that makes use of LINQ extensions inside the compiler.
'System.Collections.Generic.IEnumerable<System.Xml.Linq.XElement>' does not contain a definition for 'Select' and no extension method 'Select' accepting a first argument of type 'System.Collections.Generic.IEnumerable<System.Xml.Linq.XElement>' could be found (are you missing a using directive or an assembly reference?)
Does anyone see what I may be doing wrong? I am attempting to include System.Linq and System.Xml.Linq yet the compiler does not seem to be able to locate them.
Here is an example C# script I am trying to compile that makes use of LINQ extensions.
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Xml.Linq;
namespace CompilerTest
{
public class BinaryFunction
{
public static void Function()
{
string xmlData = #"<data>
<clients>
<client>
<clientId>1</clientId>
<clientName>Dell</clientName>
</client>
<client>
<clientId>2</clientId>
<clientName>Apple</clientName>
</client>
</clients>
</data>";
XDocument xDoc = XDocument.Parse(xmlData);
List<string> results = xDoc.Descendants("data")
.Descendants("client")
.Select(x => x.Element("clientName").Value)
.ToList<string>();
}
}
}
UPDATE: I confirmed that the following assemblies were in the GAC. System.Xml and System.Xml.Linq. I also added the compiler version to the constructor and I still get the same error.
CSharpCodeProvider(new Dictionary<String, String> { { "CompilerVersion", "v4.6.1" } })
After searching for related errors I found the solution. I needed to add System.Core as a referenced assembly.
options.ReferencedAssemblies.Add("System.Core.dll");
Once I did this then the LINQ assemblies were used and I was able to use LINQ extensions. So to be clear my new code is
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters options = new CompilerParameters();
options.ReferencedAssemblies.Add("System.Data.dll");
options.ReferencedAssemblies.Add("System.dll");
options.ReferencedAssemblies.Add("System.Xml.dll");
options.ReferencedAssemblies.Add("System.Linq.dll");
options.ReferencedAssemblies.Add("System.Xml.Linq.dll");
options.ReferencedAssemblies.Add("System.Core.dll");
I am not sure why the reference to System.Core.dll is needed to be added as I would assume that it was referenced by default when creating a compiler instance but I guess not.

TypeLoadException: Could not load type from assembly in Xamarin

I have Xamarin Forms PCL application and I am trying to inherit from HttpContent in attempt to follow this reference. I would like to implement progress bar for image upload. Here is my implementation which contains minimum code to implement HttpContent:
public class ProgressableStreamContent : HttpContent
{
public ProgressableStreamContent()
{ }
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
{
return Task.Run(async () =>
{
});
}
protected override bool TryComputeLength(out long length)
{
length = 0;
return true;
}
}
and I have procedure that is using this ProgressableStreamContent:
public async void UseProgressableStreamContent()
{
var progressableContent = new ProgressableStreamContent();
}
Problem is that this code produces exception:
UNHANDLED EXCEPTION: System.TypeLoadException: Could not load type 'MyApp.Classes.ProgressableStreamContent' from assembly 'MyApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
When I comment out line "var progressableContent = new ProgressableStreamContent();" - everything works good.
When I comment out inheritance ": HttpContent" (and override keywords) - everything works good.
Should I install some package? What else could be a problem?
I resolved issue by changing profile from 259 to 7. Changing profile includes deleting all NuGet packages and installing them again after profile change.

cross-AppDomain event issues

I use the following helper class with POS for .Net to get a reference to the hardware in a separate AppDomain (getting around some limitations of requiring <NetFx40_LegacySecurityPolicy enabled="true"/>
public static class PosHelper
{
private static AppDomain _posAppDomain { get; set; }
private static AppDomain PosAppDomain
{
get
{
if (_posAppDomain == null)
{
AppDomainSetup currentAppDomainSetup = AppDomain.CurrentDomain.SetupInformation;
AppDomainSetup newAppDomainSetup = new AppDomainSetup()
{
ApplicationBase = currentAppDomainSetup.ApplicationBase,
LoaderOptimization = currentAppDomainSetup.LoaderOptimization,
ConfigurationFile = currentAppDomainSetup.ConfigurationFile
};
newAppDomainSetup.SetCompatibilitySwitches(new[] { "NetFx40_LegacySecurityPolicy" });
_posAppDomain = AppDomain.CreateDomain("POS Hardware AppDomain", null, newAppDomainSetup);
}
return _posAppDomain;
}
}
public static T GetHardware<T>() where T : PosHardware, new()
{
T hardware = (T)PosAppDomain.CreateInstanceFromAndUnwrap(Assembly.GetAssembly(typeof(T)).Location, typeof(T).FullName);
hardware.FindAndOpenDevice();
return hardware;
}
}
I have a basic class to handle when a POS scanner scans data. In that class I have an event that I want to fire when data is scanned. Here's a snippet:
public class ScannerDevice : PosHardware
{
public event Action<string> DataScanned;
...
_scanner.DataEvent += new DataEventHandler(Scanner_DataEvent);
...
private void Scanner_DataEvent(object sender, DataEventArgs e)
{
ASCIIEncoding encoder = new ASCIIEncoding();
if (DataScanned != null)
DataScanned(encoder.GetString(_scanner.ScanDataLabel));
_scanner.DataEventEnabled = true; // enable for subsequent scans
}
Note that the PosHardware abstract class inherits MarshalByRefObject and is marked [Serializable]
In my main AppDomain I try to use the event like so:
Scanner = PosHelper.GetHardware<ScannerDevice>();
Scanner.DataScanned += m =>
{
Debug.WriteLine(m);
};
When it hits the line trying to add the lambda to the DataScanned event I get this error:
Could not load file or assembly 'MyAssemlyName, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null' or one of its dependencies. The
system cannot find the file specified.
This has to be related to trying to communicate between AppDomains. Not really sure what to do. Do I need to register "MyAssemblyName" in the separate AppDomain used for Pos for .Net?
I use prism, so some modules are loaded at runtime (in a subfolder in my output directory)... including the one in which I use the last code snippet above (Scanner = PosHelper.GetHardware....)
I believe I solved my problem. Since my prism modules are loaded at runtime within a subdirectory I needed to add this to the AppDomain so that the AppDomain could find the assemblies in the subdirectories folder.:
PrivateBinPath = #"Modules"
http://msdn.microsoft.com/en-us/library/system.appdomainsetup.privatebinpath.aspx
Edit
This only partially solved my problem. I also had to override InitializeLifetimeService() and return null so that my MarshalByRefObject's would not be disposed while the program is running (I believe the default timeout is 5 minutes).
Also , this now works:
Scanner.DataScanned += m =>
{
Debug.WriteLine(m);
}
but when I try something like this
Scanner.DataScanned += m =>
{
DoSomething(m);
}
Where DoSomething is not in a Serializable and MarshalByRefObject class, it craps out since all classes that are used in the communication between AppDomain's need to have those. So where I'm at now is looking at using WCF named pipes to pass data around... and other similar solutions.

Resources