谷歌地图Geocoder和MoveToRegion无法正常工作

时间:2017-08-21 06:13:54

标签: google-maps xamarin xamarin.android xamarin.forms google-geocoder

我'与Xamarin.Forms.Maps有一个非常奇怪的问题。 我尝试使用获取当前位置的地图并在页面开始时移动到区域来实现页面。

在IOS中一切正常,但在Android,Geocoder& 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);

我在AVD的Genymotion,Emulator中尝试过。 我无法在真实设备中进行测试(我的平板电脑部署失败)

修改:

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表单使用地图示例

时出现相同的错误

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

这是一个可用的跨平台示例应用。它在 KitKat 4.4 API Level 19 模拟器中运行,也在 Samsung 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>();
    }
}