1

我有一个非常奇怪的问题与Xamarin.Forms.Maps。 我试图用一张地图实现一个页面,该页面获取当前位置,并在页面启动时移至区域。谷歌地图Geocoder和MoveToRegion不工作

所有在IOS中工作正常,但在Android中,地理编码器& MoveToRegion根本不起作用。只显示地图。

我在仿真器&设备中正确检索位置(Long & Lat)。 MoveToRegion什么都不做& GetAddressesForPositionAsync什么都没收。

在这里,在我的清单中的信息:

<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="mykey" /> 
     <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" /> 

<uses-permission android:name="android.permission.INTERNET" /> 
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" /> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 
<uses-permission android:name="android.permission.ACCESS_COARSE_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" /> 

下面的代码:

map.MoveToRegion(MapSpan.FromCenterAndRadius(
       new Xamarin.Forms.Maps.Position(coordinates.Lat.Value, coordinates.Lng.Value), Distance.FromMiles(1)) 
      ); 

     var possibleAddresses = await locator.GetAddressesForPositionAsync(position); 

我试着在Genymotion,模拟器从AVD。 我不能在真实设备来测试(部署在我的平板电脑失败)

编辑:

global::Xamarin.Forms.Forms.Init(this, bundle); 

设置正确,但仍然没有工作。

我强迫地理编码器使用,它抛出这个错误:

[MonoDroid] UNHANDLED EXCEPTION: 
[MonoDroid] Java.IO.IOException: grpc failed 
[MonoDroid] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() [0x0000c] in <896ad1d315ca4ba7b117efb8dacaedcf>:0 
[MonoDroid] at Java.Interop.JniEnvironment+InstanceMethods.CallObjectMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x00069] in <6cd960837cc24c26bab2a0a29b597627>:0 
[MonoDroid] at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeAbstractObjectMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x00014] in <6cd960837cc24c26bab2a0a29b597627>:0 
[MonoDroid] at Android.Locations.Geocoder.GetFromLocationName (System.String locationName, System.Int32 maxResults) [0x0003c] in <d278c06ad5684d6882c743a94a93ebc2>:0 
[MonoDroid] at Android.Locations.Geocoder+<>c__DisplayClass17_0.<GetFromLocationNameAsync>b__0() [0x00000] in <d278c06ad5684d6882c743a94a93ebc2>:0 
[MonoDroid] at System.Threading.Tasks.Task`1[TResult].InnerInvoke() [0x0000f] in <896ad1d315ca4ba7b117efb8dacaedcf>:0 
[MonoDroid] at System.Threading.Tasks.Task.Execute() [0x00010] in <896ad1d315ca4ba7b117efb8dacaedcf>:0 
[MonoDroid] --- End of stack trace from previous location where exception was thrown --- 
[MonoDroid] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() [0x0000c] in <896ad1d315ca4ba7b117efb8dacaedcf>:0 
[MonoDroid] at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in <896ad1d315ca4ba7b117efb8dacaedcf>:0 
[MonoDroid] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <896ad1d315ca4ba7b117efb8dacaedcf>:0 
[MonoDroid] at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <896ad1d315ca4ba7b117efb8dacaedcf>:0 
[MonoDroid] at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult() [0x00000] in <896ad1d315ca4ba7b117efb8dacaedcf>:0 
[MonoDroid] at Xamarin.Forms.Maps.Android.GeocoderBackend+<GetPositionsForAddressAsync>d__1.MoveNext() [0x0006b] in <39c694c022be4f7b8a39897d372b2d00>:0 
[MonoDroid] --- End of stack trace from previous location where exception was thrown --- 
[MonoDroid] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() [0x0000c] in <896ad1d315ca4ba7b117efb8dacaedcf>:0 
[MonoDroid] at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in <896ad1d315ca4ba7b117efb8dacaedcf>:0 
[MonoDroid] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <896ad1d315ca4ba7b117efb8dacaedcf>:0 
[MonoDroid] at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <896ad1d315ca4ba7b117efb8dacaedcf>:0 
[MonoDroid] at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult() [0x00000] in <896ad1d315ca4ba7b117efb8dacaedcf>:0 
[MonoDroid] at Picaplant.Views.GeolocationPage+<HandleAdressCompleted>d__8.MoveNext() [0x00047] in /Users/OrcusZ/Documents/AutoEntrepreneur/Picaplant/Source/Picaplant/Views/GeolocationPage.xaml.cs:158 
[MonoDroid] --- End of stack trace from previous location where exception was thrown --- 
[MonoDroid] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() [0x0000c] in <896ad1d315ca4ba7b117efb8dacaedcf>:0 
[MonoDroid] at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_0 (System.Object state) [0x00000] in <896ad1d315ca4ba7b117efb8dacaedcf>:0 
[MonoDroid] at Android.App.SyncContext+<>c__DisplayClass2_0.<Post>b__0() [0x00000] in <d278c06ad5684d6882c743a94a93ebc2>:0 
[MonoDroid] at Java.Lang.Thread+RunnableImplementor.Run() [0x00008] in <d278c06ad5684d6882c743a94a93ebc2>:0 
[MonoDroid] at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in <d278c06ad5684d6882c743a94a93ebc2>:0 
[MonoDroid] at (wrapper dynamic-method) System.Object:6621ff63-14b8-4291-a222-45bff630bddc (intptr,intptr) 
[MonoDroid] --- End of managed Java.IO.IOException stack trace --- 
[MonoDroid] java.io.IOException: grpc failed 
[MonoDroid]  at android.location.Geocoder.getFromLocationName(Geocoder.java:178) 
[MonoDroid] 

编辑2:

同样的错误与Xamarin形式的地图样本

任何想法工作?

+0

'mykey'意味着你必须添加键值?我想我们可能需要看一些代码来帮助您找出问题所在。 –

+0

是的,我隐藏了mykey的真正关键,不显示它。地图显示正确,我可以与它进行交互。 – OrcusZ

+0

尝试部署在真正的杀手上,如果有任何问题,请随时询问。 –

回答

2

这是一个可用的跨平台示例应用程序。它运行在一个KitKat 4.4 API级别19模拟器,也在一个三星Android设备。 我们还提供了一个使用HTTP请求的自定义Geocoder实现,因为标准实体可以在实际Android设备上正常工作,但会为模拟器返回空响应。

enter image description here

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" 
      xmlns:Maps="clr-namespace:Xamarin.Forms.Maps;assembly=Xamarin.Forms.Maps.dll" 
      xmlns:local="clr-namespace:App20" 
      x:Class="App20.MainPage"> 
    <ContentPage.Content> 
     <Grid> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="8*"></RowDefinition> 
       <RowDefinition Height="4*"></RowDefinition> 
       <RowDefinition Height="*"></RowDefinition> 
       <RowDefinition Height="*"></RowDefinition> 
      </Grid.RowDefinitions> 

      <Maps:Map x:Name="map1" Grid.Row="0"></Maps:Map> 
      <ListView ItemsSource="{Binding AddressList}" Grid.Row="1" /> 
      <Button Text="Move To Region" Grid.Row="2" Clicked="Button_Clicked_Move"></Button> 
      <Button Text="Get Address" Grid.Row="3" Clicked="Button_Clicked_Address"></Button> 
     </Grid> 
    </ContentPage.Content> 
</ContentPage> 

CS:

public partial class MainPage : ContentPage 
{ 
    MyViewModel vm; 

    public MainPage() 
    { 
     InitializeComponent(); 

     vm = new MyViewModel(); 
     BindingContext = vm; 
    } 

    private void Button_Clicked_Move(object sender, EventArgs e) 
    { 
     map1.MoveToRegion(MapSpan.FromCenterAndRadius(
      new Position(vm.Lat, vm.Lon), Distance.FromMiles(vm.Distance))); 
    } 

    private async void Button_Clicked_Address(object sender, EventArgs e) 
    { 
     Geocoder gc = new Geocoder(); 

     var list = await gc.GetAddressesForPositionAsync(new Position(vm.Lat, vm.Lon)); 

     if (list.Count() > 0) 
     { 
      foreach (string s in list) 
       vm.AddressList.Add(s); 
     } 
     else 
     { 
      MyGeocoder mgc = new MyGeocoder(); 

      var mylist = await mgc.GetAddressesForPositionAsync(vm.Lat, vm.Lon, vm.Key); 

      foreach (string s in mylist) 
       vm.AddressList.Add(s); 
     } 
    } 
} 

视图模型:

public class MyViewModel 
{ 
    public string Key { get; } 
    public double Lat { get; set; } 
    public double Lon { get; set; } 
    public double Distance { get; set; } 
    public ObservableCollection<string> AddressList { get; set; } 

    public MyViewModel() 
    { 
     Lat = 40.706501; 
     Lon = -74.011340; 
     Distance = 0.5; 
     Key = "YOUR_API_KEY"; 
     AddressList = new ObservableCollection<string>(); 
    } 
} 

自定义地理编码:

public class MyGeocoder 
{ 
    public async Task<IEnumerable<string>> GetAddressesForPositionAsync(double lat, double lon, string key) 
    { 
     HttpClient client = new HttpClient(); 

     var request = string.Format(@"https://maps.googleapis.com/maps/api/geocode/json?latlng={0},{1}&key={2}", lat, lon, key); 

     var json = await client.GetStringAsync(request); 

     var result = JObject.Parse(json)["results"]; 

     List<string> list = new List<string>(); 

     foreach (JToken jt in result) 
      list.Add((string)jt["formatted_address"]); 

     return list.AsEnumerable<string>(); 
    } 
} 
+0

感谢你,我发现问题来自我的地图自定义渲染器以实现Tap事件。现在我可以找到一个解决方案^^ – OrcusZ

+0

Geocoder一直运行不起来( – OrcusZ

+0

)如果_not working_的意思是_empty response_,那很可能是因为Google Play for emulators没有提供必要的支持服务,因为如果你仍然遇到异常,你应该发布一个[MCVE](https://stackoverflow.com/help/mcve),并确保你可以在更多人的帮助下更快地获得帮助愿意帮忙 – jsanalytics