【发布时间】:2018-01-05 08:00:48
【问题描述】:
我有问题。我正在尝试在 Xamarin 跨平台应用程序上显示 Google 地图。
对于 Android,我的 API 密钥正确生成了以下代码:
MainActivity.cs:
using System;
using Android.App;
using Android.Content.PM;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
namespace PruebaMapas.Droid
{
[Activity(Label = "PruebaMapas", Icon = "@drawable/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(bundle);
Xamarin.FormsMaps.Init(this, bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new App());
}
}
}
然后,我的 AndroidManifest.xml 中有这些:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.PruebaMapas" android:installLocation="auto">
<uses-sdk android:minSdkVersion="13" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application android:label="PruebaMapas.Android">
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="AIzaSyD2bMPYdPUw_0Fd8-GkHle0_CiImTgtqX0" />
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
</application>
</manifest>
我已启用此权限:
然后,我创建一个名为“MapPage.xaml”的页面,代码如下:
MapPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="PruebaMapas.MapPage">
<ContentPage.Content>
<StackLayout>
<Label Text="Welcome to Xamarin.Forms!"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
MapPage.xaml.cs:
using System;
using Xamarin.Forms;
using Xamarin.Forms.Maps;
using System.Diagnostics;
namespace PruebaMapas
{
public partial class MapPage : ContentPage
{
Map map;
public MapPage()
{
map = new Map
{
IsShowingUser = true,
HeightRequest = 100,
WidthRequest = 960,
VerticalOptions = LayoutOptions.FillAndExpand
};
// You can use MapSpan.FromCenterAndRadius
map.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(37, -122), Distance.FromMiles(0.3)));
// or create a new MapSpan object directly
//map.MoveToRegion(new MapSpan(new Position(0, 0), 360, 360));
// add the slider
var slider = new Slider(1, 18, 1);
slider.ValueChanged += (sender, e) => {
var zoomLevel = e.NewValue; // between 1 and 18
var latlongdegrees = 360 / (Math.Pow(2, zoomLevel));
Debug.WriteLine(zoomLevel + " -> " + latlongdegrees);
if (map.VisibleRegion != null) map.MoveToRegion(new MapSpan(map.VisibleRegion.Center, latlongdegrees, latlongdegrees));
};
// create map style buttons
var street = new Button
{
Text = "Street"
};
var hybrid = new Button
{
Text = "Hybrid"
};
var satellite = new Button
{
Text = "Satellite"
};
street.Clicked += HandleClicked;
hybrid.Clicked += HandleClicked;
satellite.Clicked += HandleClicked;
var segments = new StackLayout
{
Spacing = 30,
HorizontalOptions = LayoutOptions.CenterAndExpand,
Orientation = StackOrientation.Horizontal,
Children = {
street,
hybrid,
satellite
}
};
// put the page together
var stack = new StackLayout
{
Spacing = 0
};
stack.Children.Add(map);
stack.Children.Add(slider);
stack.Children.Add(segments);
Content = stack;
// for debugging output only
map.PropertyChanged += (sender, e) => {
Debug.WriteLine(e.PropertyName + " just changed!");
if (e.PropertyName == "VisibleRegion" && map.VisibleRegion != null) CalculateBoundingCoordinates(map.VisibleRegion);
};
}
void HandleClicked(object sender, EventArgs e)
{
var b = sender as Button;
switch (b.Text)
{
case "Street":
map.MapType = MapType.Street;
break;
case "Hybrid":
map.MapType = MapType.Hybrid;
break;
case "Satellite":
map.MapType = MapType.Satellite;
break;
}
}
/// <summary>
/// In response to this forum question http://forums.xamarin.com/discussion/22493/maps-visibleregion-bounds
/// Useful if you need to send the bounds to a web service or otherwise calculate what
/// pins might need to be drawn inside the currently visible viewport.
/// </summary>
static void CalculateBoundingCoordinates(MapSpan region)
{
// WARNING: I haven't tested the correctness of this exhaustively!
var center = region.Center;
var halfheightDegrees = region.LatitudeDegrees / 2;
var halfwidthDegrees = region.LongitudeDegrees / 2;
var left = center.Longitude - halfwidthDegrees;
var right = center.Longitude + halfwidthDegrees;
var top = center.Latitude + halfheightDegrees;
var bottom = center.Latitude - halfheightDegrees;
// Adjust for Internation Date Line (+/- 180 degrees longitude)
if (left < -180) left = 180 + (180 + left);
if (right > 180) right = (right - 180) - 180;
// I don't wrap around north or south; I don't think the map control allows this anyway
Debug.WriteLine("Bounding box:");
Debug.WriteLine(" " + top);
Debug.WriteLine(" " + left + " " + right);
Debug.WriteLine(" " + bottom);
}
}
}
最后,我运行应用程序时的屏幕截图:
输出窗口显示下一个:
[0:] Width just changed!
[0:] Height just changed!
01-05 08:50:33.704 D/Mono ( 8860): Assembly Ref addref Xamarin.GooglePlayServices.Maps[0x9ebcb740] -> Xamarin.GooglePlayServices.Basement[0x9ebcb500]: 3
01-05 08:50:33.722 D/Mono ( 8860): Assembly Ref addref Xamarin.Forms.Maps.Android[0x9ebcb140] -> System.Core[0x9ebcc160]: 7
01-05 08:50:33.730 D/Mono ( 8860): DllImport searching in: '__Internal' ('(null)').
01-05 08:50:33.730 D/Mono ( 8860): Searching for 'java_interop_jnienv_call_nonvirtual_float_method_a'.
01-05 08:50:33.730 D/Mono ( 8860): Probing 'java_interop_jnienv_call_nonvirtual_float_method_a'.
01-05 08:50:33.730 D/Mono ( 8860): Found as 'java_interop_jnienv_call_nonvirtual_float_method_a'.
01-05 08:50:33.736 D/Mono ( 8860): Assembly Ref addref Mono.Android[0x9ebcb800] -> System.Xml[0x8af1bfc0]: 3
01-05 08:50:33.741 E/Google Maps Android API( 8860): Authorization failure. Please see https://developers.google.com/maps/documentation/android-api/start for how to correctly set up the map.
01-05 08:50:33.741 E/Google Maps Android API( 8860): In the Google Developer Console (https://console.developers.google.com)
01-05 08:50:33.741 E/Google Maps Android API( 8860): Ensure that the "Google Maps Android API v2" is enabled.
01-05 08:50:33.741 E/Google Maps Android API( 8860): Ensure that the following Android Key exists:
01-05 08:50:33.741 E/Google Maps Android API( 8860): API Key: AIzaSyD2bMPYdPUw_0Fd8-GkHle0_CiImTgtqX0
01-05 08:50:33.741 E/Google Maps Android API( 8860): Android Application (<cert_fingerprint>;<package_name>): BF:45:E2:59:BF:E1:B0:77:66:E0:DC:13:9A:1F:E3:45:8D:F8:E1:41;com.companyname.PruebaMapas
01-05 08:50:33.756 D/ ( 8860): HostConnection::get() New Host Connection established 0xa5508b40, tid 8919
01-05 08:50:33.758 W/ ( 8860): Unrecognized GLES max version string in extensions: ANDROID_EMU_CHECKSUM_HELPER_v1
01-05 08:50:33.758 W/ ( 8860): Process pipe failed
01-05 08:50:33.763 D/EGL_emulation( 8860): eglCreateContext: 0xa5506140: maj 1 min 0 rcv 1
01-05 08:50:33.767 D/ ( 8860): HostConnection::get() New Host Connection established 0x7ec86800, tid 8860
01-05 08:50:33.767 W/ ( 8860): Unrecognized GLES max version string in extensions: ANDROID_EMU_CHECKSUM_HELPER_v1
01-05 08:50:33.816 D/EGL_emulation( 8860): eglMakeCurrent: 0xa5506140: ver 1 0 (tinfo 0x8acec820)
01-05 08:50:35.243 W/DynamiteModule( 8860): Local module descriptor class for com.google.android.gms.googlecertificates not found.
01-05 08:50:35.247 I/DynamiteModule( 8860): Considering local module com.google.android.gms.googlecertificates:0 and remote module com.google.android.gms.googlecertificates:0
01-05 08:50:35.247 E/GoogleCertificates( 8860): Failed to load com.google.android.gms.googlecertificates
01-05 08:50:35.247 E/GoogleCertificates( 8860): qq: No acceptable module found. Local version is 0 and remote version is 0.
01-05 08:50:35.247 E/GoogleCertificates( 8860): at com.google.android.gms.dynamite.DynamiteModule.a(:com.google.android.gms.DynamiteModulesB@11509470:11)
01-05 08:50:35.247 E/GoogleCertificates( 8860): at in.a(:com.google.android.gms.DynamiteModulesB@11509470:12)
01-05 08:50:35.247 E/GoogleCertificates( 8860): at in.a(:com.google.android.gms.DynamiteModulesB@11509470:31)
01-05 08:50:35.247 E/GoogleCertificates( 8860): at in.b(:com.google.android.gms.DynamiteModulesB@11509470:30)
01-05 08:50:35.247 E/GoogleCertificates( 8860): at iy.a(:com.google.android.gms.DynamiteModulesB@11509470:35)
01-05 08:50:35.247 E/GoogleCertificates( 8860): at iy.a(:com.google.android.gms.DynamiteModulesB@11509470:20)
01-05 08:50:35.247 E/GoogleCertificates( 8860): at com.google.maps.api.android.lib6.impl.ev.a(:com.google.android.gms.DynamiteModulesB@11509470:143)
01-05 08:50:35.247 E/GoogleCertificates( 8860): at com.google.maps.api.android.lib6.impl.fb.run(:com.google.android.gms.DynamiteModulesB@11509470:28)
01-05 08:50:35.247 E/GoogleCertificates( 8860): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
01-05 08:50:35.247 E/GoogleCertificates( 8860): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
01-05 08:50:35.247 E/GoogleCertificates( 8860): at java.lang.Thread.run(Thread.java:761)
Thread finished: <Thread Pool> #4
Thread started: <Thread Pool> #8
El subproceso 0x4 terminó con código 0 (0x0).
Thread finished: <Thread Pool> #8
Thread started: <Thread Pool> #9
El subproceso 0x8 terminó con código 0 (0x0).
我在尝试查看 UWP 解决方案的结果时也遇到了问题,我有一个例外。我使用的代码在 MainPage.xaml.cs 中:
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
namespace PruebaMapas.UWP
{
public sealed partial class MainPage
{
public MainPage()
{
this.InitializeComponent();
Xamarin.FormsMaps.Init();
LoadApplication(new PruebaMapas.App());
}
}
}
我的错误就在这里:
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), e.Arguments);
}
// Ensure the current window is active
Window.Current.Activate();
#if DEBUG && !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
UnhandledException += (sender, e) =>
{
if (global::System.Diagnostics.Debugger.IsAttached) global::System.Diagnostics.Debugger.Break();
};
#endif
为什么我看不到谷歌地图信息?任何人都可以帮助我吗?谢谢!
【问题讨论】:
-
有什么异常?您是否尝试调试异常?
-
我在 Android 应用上没有异常,它会加载谷歌地图但什么也没显示。
-
引用上面的“我有一个例外”。现在你说,我没有例外....是哪一个?
-
当我写“我有一个异常”时,我写在“关于 UWP 解决方案”之前,而不是在 Android 解决方案之前。所以,在 Android 应用程序上我没有例外。在 UWP 解决方案上,它在以下位置中断: if (rootFrame.Content == null) { // 当导航堆栈未恢复时,导航到第一页, // 通过将所需信息作为导航参数传递来配置新页面 // 参数rootFrame.Navigate(typeof(MainPage), e.Arguments); } Window.Current.Activate();
-
我将错误行贴在问题上,以便看得更清楚
标签: c# android google-maps xaml xamarin