Xamarin.Forms.GoogleMaps icon indicating copy to clipboard operation
Xamarin.Forms.GoogleMaps copied to clipboard

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

Open janusw opened this issue 5 years ago • 8 comments

VERSIONS

  • Xamarin.Forms.GoogleMaps - 3.3.0-1-g3f3c482
  • Xamarin.Forms - 3.0.0.482510
  • Android 9

PLATFORMS

  • [x] Android
  • [ ] iOS
  • [ ] UWP

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 avatar Dec 09 '19 08:12 janusw

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

  • When the tiles are rebuilt after zooming or moving, one always seen the Google tiles appearing shortly, before the OSM tiles appear. So it seems that both tiles are loaded, generating unnecessary network traffic etc.
  • Most city labels are duplicated. The OSM tiles apparently include text for city names, but then there is additional text rendered on top of it (from Google Maps?).

janusw avatar Dec 09 '19 08:12 janusw

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

thespeech avatar Feb 17 '20 06:02 thespeech

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

ssombat avatar Apr 07 '20 18:04 ssombat

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?

janusw avatar Apr 07 '20 20:04 janusw

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; }

ssombat avatar Apr 08 '20 17:04 ssombat

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 avatar Apr 09 '20 10:04 janusw

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.

janusw avatar Apr 09 '20 11:04 janusw

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!

trevelyanuk avatar Jun 17 '20 10:06 trevelyanuk