amay077 / Xamarin.Forms.GoogleMaps

Map library for Xamarin.Forms using Google maps API
https://www.nuget.org/packages/Xamarin.Forms.GoogleMaps/
MIT License
546 stars 346 forks source link

[Android] custom TileLayers not showing up without Google Maps API key #680

Open janusw opened 4 years ago

janusw commented 4 years ago

VERSIONS

PLATFORMS

ACTUAL BEHAVIOR

On Android I'm not able to use custom tiles (e.g. OSM) without a Google Maps API key. On iOS it works without a problem.

EXPECTED BEHAVIOR

OpenStreetMap tiles should not require an Google Maps API key in principle. I want to use custom tiles without being dependent on Google.

HOW TO REPRODUCE

  1. Open the XFGoogleMapSample solution.
  2. Do not enter a GOOGLE_MAPS_ANDROID_API_KEY in Variables.cs.
  3. Run the sample on an Android phone.
  4. Open the Tiles page.
  5. Click the OpenStreetMap or OpenRailWayMap button.
  6. Result: You see an empty map view (empty grey space with zoom controls).
janusw commented 4 years ago

The problem is not only that the API key is required, but also:

thespeech commented 4 years ago

Just popping in to highlight the same issue - I wish to utilize custom map tiles without a Google Maps API key.

ssombat commented 4 years ago

Doing the same thing. Using this package to display custom tiles. To get rid of duplicated city labels, I set the MapType to None.

janusw commented 4 years ago

To get rid of duplicated city labels, I set the MapType to None.

I already do that, but it doesn't seem to work (at least not on Android). Does this work on Android for you? If yes, how do you do it?

ssombat commented 4 years ago

It works for me. private void setCustomOnlineTiles() { TileLayer tileLayer; tileLayer = TileLayer.FromTileUri((int x, int y, int zoom) => new Uri(_tileServerUrl.Replace("{zoom}", zoom.ToString()).Replace("{x}", x.ToString()).Replace("{y}", y.ToString()))); map.TileLayers.Add(tileLayer); map.MapType = MapType.None; }

janusw commented 4 years ago

It works for me.

What platform are you targeting? Android? iOS? Other? If Android, which API level?

On iOS it works for me as well (apparently, because I can leave out the API key). @ssombat, are you specifying an API key in your application?

private void setCustomOnlineTiles() { TileLayer tileLayer; tileLayer = TileLayer.FromTileUri((int x, int y, int zoom) => new Uri(_tileServerUrl.Replace("{zoom}", zoom.ToString()).Replace("{x}", x.ToString()).Replace("{y}", y.ToString()))); map.TileLayers.Add(tileLayer); map.MapType = MapType.None; }

That's essentially what I do as well. I even have this in addition (before the call to TileLayers.Add):

tileLayer.Tag = "OSMTILE";
TileLayers.Clear(); 

... but that does not seem to help, either.

janusw commented 4 years ago

Note: If I completely remove the line ...

<meta-data android:name="com.google.android.geo.API_KEY" android:value="..." />

... from my AndroidManifest.xml, I get this:

[MonoDroid] UNHANDLED EXCEPTION:
[MonoDroid] Java.Lang.RuntimeException: API key not found.  Check that <meta-data android:name="com.google.android.geo.API_KEY" android:value="your API key"/> is in the <application> element of AndroidManifest.xml
[MonoDroid]   at Java.Interop.JniEnvironment+InstanceMethods.CallVoidMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x0006e] in <76fcbd94264c4e04b266cce1754a55fb>:0 
[MonoDroid]   at Xamarin.Forms.GoogleMaps.Android.MapRenderer.OnElementChanged (Xamarin.Forms.Platform.Andro04-09 12:59:06.614 I/MonoDroid(15284):   at Android.Runtime.JNIEnv.CallVoidMethod (System.IntPtr jobject, System.IntPtr jmethod, Android.Runtime.JValue* parms) [0x0000e] in <5043ed9b360b4966aca0d48faf6c40d5>:0 
[MonoDroid]   at Android.Gms.Maps.MapView.OnCreate (Android.OS.Bundle savedInstanceState) [0x00048] in <0ef98d0b7df944fb8f20d9e078937bf5>:0 
[MonoDroid]   at Android.App.SyncContext+<>c__DisplayClass2_0.<Post>b__0 () [0x00000] in <5043ed9b360b4966aca0d48faf6c40d5>:0 
[MonoDroid]   at Java.Lang.Thread+RunnableImplementor.Run () [0x00008] in <5043ed9b360b4966aca0d48faf6c40d5>:0 
[MonoDroid]   at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00009] in <5043ed9b360b4966aca0d48faf6c40d5>:0 
[MonoDroid]   at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.51(intptr,intptr)

If I leave the line in, but use an empty key value, like this ...

<meta-data android:name="com.google.android.geo.API_KEY" android:value="" />

... then it actually works now for me (in my own application).

I'm pretty sure that it did not work when I originally reported this issue in December, so maybe something has changed in the meantime. I still use the same version of Xamarin.Forms.GoogleMaps (3.3.0), but I now have a different version of Xamarin.Forms (4.5.0) and I'm targeting Android 10, instead of 9.

trevelyanuk commented 4 years ago

Note: If I completely remove the line ...

<meta-data android:name="com.google.android.geo.API_KEY" android:value="..." />

... from my AndroidManifest.xml, I get this:

[MonoDroid] UNHANDLED EXCEPTION:
[MonoDroid] Java.Lang.RuntimeException: API key not found.  Check that <meta-data android:name="com.google.android.geo.API_KEY" android:value="your API key"/> is in the <application> element of AndroidManifest.xml
[MonoDroid]   at Java.Interop.JniEnvironment+InstanceMethods.CallVoidMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x0006e] in <76fcbd94264c4e04b266cce1754a55fb>:0 
[MonoDroid]   at Xamarin.Forms.GoogleMaps.Android.MapRenderer.OnElementChanged (Xamarin.Forms.Platform.Andro04-09 12:59:06.614 I/MonoDroid(15284):   at Android.Runtime.JNIEnv.CallVoidMethod (System.IntPtr jobject, System.IntPtr jmethod, Android.Runtime.JValue* parms) [0x0000e] in <5043ed9b360b4966aca0d48faf6c40d5>:0 
[MonoDroid]   at Android.Gms.Maps.MapView.OnCreate (Android.OS.Bundle savedInstanceState) [0x00048] in <0ef98d0b7df944fb8f20d9e078937bf5>:0 
[MonoDroid]   at Android.App.SyncContext+<>c__DisplayClass2_0.<Post>b__0 () [0x00000] in <5043ed9b360b4966aca0d48faf6c40d5>:0 
[MonoDroid]   at Java.Lang.Thread+RunnableImplementor.Run () [0x00008] in <5043ed9b360b4966aca0d48faf6c40d5>:0 
[MonoDroid]   at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00009] in <5043ed9b360b4966aca0d48faf6c40d5>:0 
[MonoDroid]   at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.51(intptr,intptr)

If I leave the line in, but use an empty key value, like this ...

<meta-data android:name="com.google.android.geo.API_KEY" android:value="" />

... then it actually works now for me (in my own application).

I'm pretty sure that it did not work when I originally reported this issue in December, so maybe something has changed in the meantime. I still use the same version of Xamarin.Forms.GoogleMaps (3.3.0), but I now have a different version of Xamarin.Forms (4.5.0) and I'm targeting Android 10, instead of 9.

I'm having this issue even on the latest versions of XF, even in the sample project. Any other thoughts or pointers? I haven't been able to figure it out. It should not be this difficult..

Whilst I understand that the name of the project has "Google" in it, I am simply dumbstruck by the lack of solid support for a map rendering solution that does not rely on Google services; especially since Xamarin Forms is a Microsoft product!